Skip to content

Commit 7e405b1

Browse files
committed
Add log.F
1 parent a93630c commit 7e405b1

File tree

9 files changed

+82
-91
lines changed

9 files changed

+82
-91
lines changed

entry.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func (ent entry) String() string {
8585
type entryConfig struct {
8686
level level
8787
msg string
88-
fields []interface{}
88+
fields []Field
8989
skip int
9090
}
9191

examples_test.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ import (
1111
func Example_stderr() {
1212
ctx := context.Background()
1313
stderrlog.Info(ctx, "my message here",
14-
"field_name", "something or the other",
15-
"some_map", map[string]string{
14+
slog.F("field_name", "something or the other"),
15+
slog.F("some_map", map[string]string{
1616
"nested_fields": "wowow",
17-
},
18-
"some slice", []interface{}{
17+
}),
18+
slog.F("some slice", []interface{}{
1919
1,
2020
"foof",
2121
"bar",
2222
true,
23-
},
23+
}),
2424
slog.Component("test"),
2525
)
2626
}
@@ -30,16 +30,20 @@ func Example_test() {
3030
var t *testing.T
3131

3232
testlog.Info(t, "my message here",
33-
"field_name", "something or the other",
34-
"some_map", map[string]interface{}{
33+
slog.F("field_name", "something or the other"),
34+
slog.F("some_map", map[string]interface{}{
3535
"nested_fields": "wowow",
36-
},
37-
"some slice", []interface{}{
36+
}),
37+
slog.F("some slice", []interface{}{
3838
1,
3939
"foof",
4040
"bar",
4141
true,
42-
},
42+
}),
4343
slog.Component("test"),
44+
45+
slog.F("name", slog.ValueFunc(func() interface{} {
46+
return "wow"
47+
})),
4448
)
4549
}

fields.go

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package slog
33
import (
44
"context"
55
"go.opencensus.io/trace"
6-
"golang.org/x/xerrors"
76
"reflect"
87
)
98

@@ -25,36 +24,13 @@ type parsedFields struct {
2524
fields fieldMap
2625
}
2726

28-
func parseFields(fields []interface{}) parsedFields {
27+
func parseFields(fields []Field) parsedFields {
2928
var l parsedFields
29+
l.fields = make(fieldMap, len(fields))
3030

3131
for i := 0; i < len(fields); i++ {
3232
f := fields[i]
33-
switch f := f.(type) {
34-
case componentField:
35-
l = l.appendComponent(string(f))
36-
continue
37-
case Field:
38-
l = l.appendField(f.LogKey(), f)
39-
continue
40-
case string:
41-
i++
42-
if i < len(fields) {
43-
v := fields[i]
44-
l = l.appendField(f, v)
45-
continue
46-
}
47-
48-
// Missing value for key.
49-
err := xerrors.Errorf("missing log value for key %v", f)
50-
l = l.appendField("missing_value_error", err)
51-
default:
52-
// Unexpected key type.
53-
err := xerrors.Errorf("unexpected log key of type %T: %#v", f, f)
54-
l = l.appendField("bad_key_error", err)
55-
// Skip the next value under the assumption that it is a value.
56-
i++
57-
}
33+
l = l.appendField(f.LogKey(), f.LogValue())
5834
}
5935

6036
return l
@@ -65,7 +41,7 @@ func (l parsedFields) appendField(k string, v interface{}) parsedFields {
6541
return l
6642
}
6743

68-
func (l parsedFields) withFields(f []interface{}) parsedFields {
44+
func (l parsedFields) withFields(f []Field) parsedFields {
6945
return l.with(parseFields(f))
7046
}
7147

logger.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,37 +32,37 @@ type logger struct {
3232
skip int
3333
}
3434

35-
func (sl logger) Debug(ctx context.Context, msg string, fields ...interface{}) {
35+
func (sl logger) Debug(ctx context.Context, msg string, fields ...Field) {
3636
sl.log(ctx, levelDebug, msg, fields)
3737
}
3838

39-
func (sl logger) Info(ctx context.Context, msg string, fields ...interface{}) {
39+
func (sl logger) Info(ctx context.Context, msg string, fields ...Field) {
4040
sl.log(ctx, levelInfo, msg, fields)
4141
}
4242

43-
func (sl logger) Warn(ctx context.Context, msg string, fields ...interface{}) {
43+
func (sl logger) Warn(ctx context.Context, msg string, fields ...Field) {
4444
sl.log(ctx, levelWarn, msg, fields)
4545
}
4646

47-
func (sl logger) Error(ctx context.Context, msg string, fields ...interface{}) {
47+
func (sl logger) Error(ctx context.Context, msg string, fields ...Field) {
4848
sl.log(ctx, levelError, msg, fields)
4949
}
5050

51-
func (sl logger) Critical(ctx context.Context, msg string, fields ...interface{}) {
51+
func (sl logger) Critical(ctx context.Context, msg string, fields ...Field) {
5252
sl.log(ctx, levelCritical, msg, fields)
5353
}
5454

55-
func (sl logger) Fatal(ctx context.Context, msg string, fields ...interface{}) {
55+
func (sl logger) Fatal(ctx context.Context, msg string, fields ...Field) {
5656
sl.log(ctx, levelFatal, msg, fields)
5757
os.Exit(1)
5858
}
5959

60-
func (sl logger) With(fields ...interface{}) Logger {
60+
func (sl logger) With(fields ...Field) Logger {
6161
sl.l = sl.l.withFields(fields)
6262
return sl
6363
}
6464

65-
func (sl logger) log(ctx context.Context, sev level, msg string, fields []interface{}) {
65+
func (sl logger) log(ctx context.Context, sev level, msg string, fields []Field) {
6666
ent := sl.l.entry(ctx, entryConfig{
6767
level: sev,
6868
msg: msg,

slog.go

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,23 @@ import (
66

77
type Logger interface {
88
// Debug means a potentially noisy log.
9-
Debug(ctx context.Context, msg string, fields ...interface{})
9+
Debug(ctx context.Context, msg string, fields ...Field)
1010
// Info means an informational log.
11-
Info(ctx context.Context, msg string, fields ...interface{})
11+
Info(ctx context.Context, msg string, fields ...Field)
1212
// Warn means something may be going wrong.
13-
Warn(ctx context.Context, msg string, fields ...interface{})
13+
Warn(ctx context.Context, msg string, fields ...Field)
1414
// Error means the an error occured but does not require immediate attention.
15-
Error(ctx context.Context, msg string, fields ...interface{})
15+
Error(ctx context.Context, msg string, fields ...Field)
1616
// Critical means an error occured and requires immediate attention.
17-
Critical(ctx context.Context, msg string, fields ...interface{})
17+
Critical(ctx context.Context, msg string, fields ...Field)
1818
// Fatal is the same as critical but calls os.Exit(1) afterwards.
19-
Fatal(ctx context.Context, msg string, fields ...interface{})
19+
Fatal(ctx context.Context, msg string, fields ...Field)
2020

2121
// With returns a logger that will merge the given fields with all fields logged.
2222
// Fields logged with one of the above methods or from the context will always take priority.
2323
// Use the global with function when the fields being stored belong in the context and this
2424
// when they do not.
25-
With(fields ...interface{}) Logger
25+
With(fields ...Field) Logger
2626
}
2727

2828
// field represents a log field.
@@ -48,33 +48,44 @@ func (fn ValueFunc) LogValue() interface{} {
4848

4949
type componentField string
5050

51+
func (c componentField) LogKey() string { panic("never called") }
52+
func (c componentField) LogValue() interface{} { panic("never called") }
53+
5154
// Component represents the component a log is being logged for.
5255
// If there is already a component set, it will be joined by ".".
5356
// E.g. if the component is currently "my_component" and then later
5457
// the component "my_pkg" is set, then the final component will be
5558
// "my_component.my_pkg".
56-
func Component(name string) interface{} {
59+
func Component(name string) Field {
5760
return componentField(name)
5861
}
5962

60-
type errorField struct {
63+
type unparsedField struct {
6164
name string
62-
err error
65+
v interface{}
66+
}
67+
68+
func (f unparsedField) LogKey() string {
69+
return f.name
6370
}
6471

65-
func (e errorField) LogKey() string {
66-
return e.name
72+
func (f unparsedField) LogValue() interface{} {
73+
return f.v
6774
}
6875

69-
func (e errorField) LogValue() interface{} {
70-
return e.err
76+
// F is used to log arbitrary fields with the logger.
77+
func F(name string, v interface{}) Field {
78+
return unparsedField{
79+
name: name,
80+
v: v,
81+
}
7182
}
7283

7384
// Error is the standard key used for logging a Go error value.
7485
func Error(err error) Field {
75-
return errorField{
86+
return unparsedField{
7687
name: "error",
77-
err: err,
88+
v: err,
7889
}
7990
}
8091

@@ -92,7 +103,7 @@ func fromContext(ctx context.Context) parsedFields {
92103
// With returns a context that contains the given fields.
93104
// Any logs written with the provided context will contain
94105
// the given fields.
95-
func With(ctx context.Context, fields ...interface{}) context.Context {
106+
func With(ctx context.Context, fields ...Field) context.Context {
96107
l := fromContext(ctx)
97108
l = l.withFields(fields)
98109
return withContext(ctx, l)

stderrlog/stderrlog.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,31 @@ func init() {
1919
}
2020

2121
// Debug logs the given msg and fields on the debug level to stderr.
22-
func Debug(ctx context.Context, msg string, fields ...interface{}) {
22+
func Debug(ctx context.Context, msg string, fields ...slog.Field) {
2323
stderrLogger.Debug(skipctx.With(ctx, 1), msg, fields...)
2424
}
2525

2626
// Info logs the given msg and fields on the info level to stderr.
27-
func Info(ctx context.Context, msg string, fields ...interface{}) {
27+
func Info(ctx context.Context, msg string, fields ...slog.Field) {
2828
stderrLogger.Info(skipctx.With(ctx, 1), msg, fields...)
2929
}
3030

3131
// Warn logs the given msg and fields on the warn level to stderr.
32-
func Warn(ctx context.Context, msg string, fields ...interface{}) {
32+
func Warn(ctx context.Context, msg string, fields ...slog.Field) {
3333
stderrLogger.Warn(skipctx.With(ctx, 1), msg, fields...)
3434
}
3535

3636
// Error logs the given msg and fields on the error level to stderr.
37-
func Error(ctx context.Context, msg string, fields ...interface{}) {
37+
func Error(ctx context.Context, msg string, fields ...slog.Field) {
3838
stderrLogger.Error(skipctx.With(ctx, 1), msg, fields...)
3939
}
4040

4141
// Critical logs the given msg and fields on the critical level to stderr.
42-
func Critical(ctx context.Context, msg string, fields ...interface{}) {
42+
func Critical(ctx context.Context, msg string, fields ...slog.Field) {
4343
stderrLogger.Critical(skipctx.With(ctx, 1), msg, fields...)
4444
}
4545

4646
// Fatal logs the given msg and fields on the fatal level to stderr.
47-
func Fatal(ctx context.Context, msg string, fields ...interface{}) {
47+
func Fatal(ctx context.Context, msg string, fields ...slog.Field) {
4848
stderrLogger.Fatal(skipctx.With(ctx, 1), msg, fields...)
4949
}

tee.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,31 @@ type multiLogger struct {
1818
loggers []Logger
1919
}
2020

21-
func (l multiLogger) Debug(ctx context.Context, msg string, fields ...interface{}) {
21+
func (l multiLogger) Debug(ctx context.Context, msg string, fields ...Field) {
2222
l.log(ctx, levelDebug, msg, fields)
2323
}
2424

25-
func (l multiLogger) Info(ctx context.Context, msg string, fields ...interface{}) {
25+
func (l multiLogger) Info(ctx context.Context, msg string, fields ...Field) {
2626
l.log(ctx, levelInfo, msg, fields)
2727
}
2828

29-
func (l multiLogger) Warn(ctx context.Context, msg string, fields ...interface{}) {
29+
func (l multiLogger) Warn(ctx context.Context, msg string, fields ...Field) {
3030
l.log(ctx, levelWarn, msg, fields)
3131
}
3232

33-
func (l multiLogger) Error(ctx context.Context, msg string, fields ...interface{}) {
33+
func (l multiLogger) Error(ctx context.Context, msg string, fields ...Field) {
3434
l.log(ctx, levelError, msg, fields)
3535
}
3636

37-
func (l multiLogger) Critical(ctx context.Context, msg string, fields ...interface{}) {
37+
func (l multiLogger) Critical(ctx context.Context, msg string, fields ...Field) {
3838
l.log(ctx, levelCritical, msg, fields)
3939
}
4040

41-
func (l multiLogger) Fatal(ctx context.Context, msg string, fields ...interface{}) {
41+
func (l multiLogger) Fatal(ctx context.Context, msg string, fields ...Field) {
4242
l.log(ctx, levelDebug, msg, fields)
4343
}
4444

45-
func (l multiLogger) log(ctx context.Context, level level, msg string, fields []interface{}) {
45+
func (l multiLogger) log(ctx context.Context, level level, msg string, fields []Field) {
4646
ctx = skipctx.With(ctx, 2)
4747
for _, l := range l.loggers {
4848
switch level {
@@ -64,11 +64,11 @@ func (l multiLogger) log(ctx context.Context, level level, msg string, fields []
6464
}
6565
}
6666

67-
func (l multiLogger) With(fields ...interface{}) Logger {
67+
func (l multiLogger) With(fields ...Field) Logger {
6868
loggers2 := make([]Logger, len(l.loggers))
6969

7070
for i, l := range l.loggers {
71-
loggers2[i] = l.With(fields)
71+
loggers2[i] = l.With(fields...)
7272
}
7373

7474
return multiLogger{

test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,42 +27,42 @@ type testLogger struct {
2727
p parsedFields
2828
}
2929

30-
func (tl testLogger) Debug(ctx context.Context, msg string, fields ...interface{}) {
30+
func (tl testLogger) Debug(ctx context.Context, msg string, fields ...Field) {
3131
tl.tb.Helper()
3232
tl.log(ctx, levelDebug, msg, fields)
3333
}
3434

35-
func (tl testLogger) Info(ctx context.Context, msg string, fields ...interface{}) {
35+
func (tl testLogger) Info(ctx context.Context, msg string, fields ...Field) {
3636
tl.tb.Helper()
3737
tl.log(ctx, levelInfo, msg, fields)
3838
}
3939

40-
func (tl testLogger) Warn(ctx context.Context, msg string, fields ...interface{}) {
40+
func (tl testLogger) Warn(ctx context.Context, msg string, fields ...Field) {
4141
tl.tb.Helper()
4242
tl.log(ctx, levelWarn, msg, fields)
4343
}
4444

45-
func (tl testLogger) Error(ctx context.Context, msg string, fields ...interface{}) {
45+
func (tl testLogger) Error(ctx context.Context, msg string, fields ...Field) {
4646
tl.tb.Helper()
4747
tl.log(ctx, levelError, msg, fields)
4848
}
4949

50-
func (tl testLogger) Critical(ctx context.Context, msg string, fields ...interface{}) {
50+
func (tl testLogger) Critical(ctx context.Context, msg string, fields ...Field) {
5151
tl.tb.Helper()
5252
tl.log(ctx, levelCritical, msg, fields)
5353
}
5454

55-
func (tl testLogger) Fatal(ctx context.Context, msg string, fields ...interface{}) {
55+
func (tl testLogger) Fatal(ctx context.Context, msg string, fields ...Field) {
5656
tl.tb.Helper()
5757
tl.log(ctx, levelFatal, msg, fields)
5858
}
5959

60-
func (tl testLogger) With(fields ...interface{}) Logger {
60+
func (tl testLogger) With(fields ...Field) Logger {
6161
tl.p = tl.p.withFields(fields)
6262
return tl
6363
}
6464

65-
func (tl testLogger) log(ctx context.Context, level level, msg string, fields []interface{}) {
65+
func (tl testLogger) log(ctx context.Context, level level, msg string, fields []Field) {
6666
tl.tb.Helper()
6767

6868
ent := tl.p.entry(ctx, entryConfig{

0 commit comments

Comments
 (0)