Skip to content

Commit 58b5dde

Browse files
jbaeric
authored andcommitted
log/slog: initial commit
The slog structured logging package. This code was copied from the slog directory of the x/exp repo at commit 642cacee5cc05231f45555a333d07f1005ffc287, with the following changes: - Change import paths. - Delete unused files list.go, list_test.go. - Rename example_depth_test.go to example_wrap_test.go and adjust example output. - Change the tag safe_values to safe_slog_values. - Make captureHandler goroutine-safe to fix a race condition in benchmarks. - Other small changes as suggested in review comments. Also, add dependencies to go/build/deps_test.go. Also, add new API for the API checker. Updates golang#56345. Change-Id: Id8d720967571ced5c5f32c84a8dd9584943cd7df Reviewed-on: https://go-review.googlesource.com/c/go/+/477295 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Jonathan Amsterdam <jba@google.com> Reviewed-by: Alan Donovan <adonovan@google.com>
1 parent dc1e088 commit 58b5dde

33 files changed

+5647
-2
lines changed

api/next/56345.txt

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
pkg log/slog, const KindAny = 0 #56345
2+
pkg log/slog, const KindAny Kind #56345
3+
pkg log/slog, const KindBool = 1 #56345
4+
pkg log/slog, const KindBool Kind #56345
5+
pkg log/slog, const KindDuration = 2 #56345
6+
pkg log/slog, const KindDuration Kind #56345
7+
pkg log/slog, const KindFloat64 = 3 #56345
8+
pkg log/slog, const KindFloat64 Kind #56345
9+
pkg log/slog, const KindGroup = 8 #56345
10+
pkg log/slog, const KindGroup Kind #56345
11+
pkg log/slog, const KindInt64 = 4 #56345
12+
pkg log/slog, const KindInt64 Kind #56345
13+
pkg log/slog, const KindLogValuer = 9 #56345
14+
pkg log/slog, const KindLogValuer Kind #56345
15+
pkg log/slog, const KindString = 5 #56345
16+
pkg log/slog, const KindString Kind #56345
17+
pkg log/slog, const KindTime = 6 #56345
18+
pkg log/slog, const KindTime Kind #56345
19+
pkg log/slog, const KindUint64 = 7 #56345
20+
pkg log/slog, const KindUint64 Kind #56345
21+
pkg log/slog, const LevelDebug = -4 #56345
22+
pkg log/slog, const LevelDebug Level #56345
23+
pkg log/slog, const LevelError = 8 #56345
24+
pkg log/slog, const LevelError Level #56345
25+
pkg log/slog, const LevelInfo = 0 #56345
26+
pkg log/slog, const LevelInfo Level #56345
27+
pkg log/slog, const LevelKey = "level" #56345
28+
pkg log/slog, const LevelKey ideal-string #56345
29+
pkg log/slog, const LevelWarn = 4 #56345
30+
pkg log/slog, const LevelWarn Level #56345
31+
pkg log/slog, const MessageKey = "msg" #56345
32+
pkg log/slog, const MessageKey ideal-string #56345
33+
pkg log/slog, const SourceKey = "source" #56345
34+
pkg log/slog, const SourceKey ideal-string #56345
35+
pkg log/slog, const TimeKey = "time" #56345
36+
pkg log/slog, const TimeKey ideal-string #56345
37+
pkg log/slog, func Any(string, interface{}) Attr #56345
38+
pkg log/slog, func AnyValue(interface{}) Value #56345
39+
pkg log/slog, func Bool(string, bool) Attr #56345
40+
pkg log/slog, func BoolValue(bool) Value #56345
41+
pkg log/slog, func Debug(string, ...interface{}) #56345
42+
pkg log/slog, func DebugCtx(context.Context, string, ...interface{}) #56345
43+
pkg log/slog, func Default() *Logger #56345
44+
pkg log/slog, func Duration(string, time.Duration) Attr #56345
45+
pkg log/slog, func DurationValue(time.Duration) Value #56345
46+
pkg log/slog, func Error(string, ...interface{}) #56345
47+
pkg log/slog, func ErrorCtx(context.Context, string, ...interface{}) #56345
48+
pkg log/slog, func Float64(string, float64) Attr #56345
49+
pkg log/slog, func Float64Value(float64) Value #56345
50+
pkg log/slog, func Group(string, ...Attr) Attr #56345
51+
pkg log/slog, func GroupValue(...Attr) Value #56345
52+
pkg log/slog, func Info(string, ...interface{}) #56345
53+
pkg log/slog, func InfoCtx(context.Context, string, ...interface{}) #56345
54+
pkg log/slog, func Int(string, int) Attr #56345
55+
pkg log/slog, func Int64(string, int64) Attr #56345
56+
pkg log/slog, func Int64Value(int64) Value #56345
57+
pkg log/slog, func IntValue(int) Value #56345
58+
pkg log/slog, func Log(context.Context, Level, string, ...interface{}) #56345
59+
pkg log/slog, func LogAttrs(context.Context, Level, string, ...Attr) #56345
60+
pkg log/slog, func New(Handler) *Logger #56345
61+
pkg log/slog, func NewJSONHandler(io.Writer) *JSONHandler #56345
62+
pkg log/slog, func NewLogLogger(Handler, Level) *log.Logger #56345
63+
pkg log/slog, func NewRecord(time.Time, Level, string, uintptr) Record #56345
64+
pkg log/slog, func NewTextHandler(io.Writer) *TextHandler #56345
65+
pkg log/slog, func SetDefault(*Logger) #56345
66+
pkg log/slog, func String(string, string) Attr #56345
67+
pkg log/slog, func StringValue(string) Value #56345
68+
pkg log/slog, func Time(string, time.Time) Attr #56345
69+
pkg log/slog, func TimeValue(time.Time) Value #56345
70+
pkg log/slog, func Uint64(string, uint64) Attr #56345
71+
pkg log/slog, func Uint64Value(uint64) Value #56345
72+
pkg log/slog, func Warn(string, ...interface{}) #56345
73+
pkg log/slog, func WarnCtx(context.Context, string, ...interface{}) #56345
74+
pkg log/slog, func With(...interface{}) *Logger #56345
75+
pkg log/slog, method (*JSONHandler) Enabled(context.Context, Level) bool #56345
76+
pkg log/slog, method (*JSONHandler) Handle(context.Context, Record) error #56345
77+
pkg log/slog, method (*JSONHandler) WithAttrs([]Attr) Handler #56345
78+
pkg log/slog, method (*JSONHandler) WithGroup(string) Handler #56345
79+
pkg log/slog, method (*Level) UnmarshalJSON([]uint8) error #56345
80+
pkg log/slog, method (*Level) UnmarshalText([]uint8) error #56345
81+
pkg log/slog, method (*LevelVar) Level() Level #56345
82+
pkg log/slog, method (*LevelVar) MarshalText() ([]uint8, error) #56345
83+
pkg log/slog, method (*LevelVar) Set(Level) #56345
84+
pkg log/slog, method (*LevelVar) String() string #56345
85+
pkg log/slog, method (*LevelVar) UnmarshalText([]uint8) error #56345
86+
pkg log/slog, method (*Logger) Debug(string, ...interface{}) #56345
87+
pkg log/slog, method (*Logger) DebugCtx(context.Context, string, ...interface{}) #56345
88+
pkg log/slog, method (*Logger) Enabled(context.Context, Level) bool #56345
89+
pkg log/slog, method (*Logger) Error(string, ...interface{}) #56345
90+
pkg log/slog, method (*Logger) ErrorCtx(context.Context, string, ...interface{}) #56345
91+
pkg log/slog, method (*Logger) Handler() Handler #56345
92+
pkg log/slog, method (*Logger) Info(string, ...interface{}) #56345
93+
pkg log/slog, method (*Logger) InfoCtx(context.Context, string, ...interface{}) #56345
94+
pkg log/slog, method (*Logger) Log(context.Context, Level, string, ...interface{}) #56345
95+
pkg log/slog, method (*Logger) LogAttrs(context.Context, Level, string, ...Attr) #56345
96+
pkg log/slog, method (*Logger) Warn(string, ...interface{}) #56345
97+
pkg log/slog, method (*Logger) WarnCtx(context.Context, string, ...interface{}) #56345
98+
pkg log/slog, method (*Logger) With(...interface{}) *Logger #56345
99+
pkg log/slog, method (*Logger) WithGroup(string) *Logger #56345
100+
pkg log/slog, method (*Record) Add(...interface{}) #56345
101+
pkg log/slog, method (*Record) AddAttrs(...Attr) #56345
102+
pkg log/slog, method (*TextHandler) Enabled(context.Context, Level) bool #56345
103+
pkg log/slog, method (*TextHandler) Handle(context.Context, Record) error #56345
104+
pkg log/slog, method (*TextHandler) WithAttrs([]Attr) Handler #56345
105+
pkg log/slog, method (*TextHandler) WithGroup(string) Handler #56345
106+
pkg log/slog, method (Attr) Equal(Attr) bool #56345
107+
pkg log/slog, method (Attr) String() string #56345
108+
pkg log/slog, method (HandlerOptions) NewJSONHandler(io.Writer) *JSONHandler #56345
109+
pkg log/slog, method (HandlerOptions) NewTextHandler(io.Writer) *TextHandler #56345
110+
pkg log/slog, method (Kind) String() string #56345
111+
pkg log/slog, method (Level) Level() Level #56345
112+
pkg log/slog, method (Level) MarshalJSON() ([]uint8, error) #56345
113+
pkg log/slog, method (Level) MarshalText() ([]uint8, error) #56345
114+
pkg log/slog, method (Level) String() string #56345
115+
pkg log/slog, method (Record) Attrs(func(Attr)) #56345
116+
pkg log/slog, method (Record) Clone() Record #56345
117+
pkg log/slog, method (Record) NumAttrs() int #56345
118+
pkg log/slog, method (Value) Any() interface{} #56345
119+
pkg log/slog, method (Value) Bool() bool #56345
120+
pkg log/slog, method (Value) Duration() time.Duration #56345
121+
pkg log/slog, method (Value) Equal(Value) bool #56345
122+
pkg log/slog, method (Value) Float64() float64 #56345
123+
pkg log/slog, method (Value) Group() []Attr #56345
124+
pkg log/slog, method (Value) Int64() int64 #56345
125+
pkg log/slog, method (Value) Kind() Kind #56345
126+
pkg log/slog, method (Value) LogValuer() LogValuer #56345
127+
pkg log/slog, method (Value) Resolve() Value #56345
128+
pkg log/slog, method (Value) String() string #56345
129+
pkg log/slog, method (Value) Time() time.Time #56345
130+
pkg log/slog, method (Value) Uint64() uint64 #56345
131+
pkg log/slog, type Attr struct #56345
132+
pkg log/slog, type Attr struct, Key string #56345
133+
pkg log/slog, type Attr struct, Value Value #56345
134+
pkg log/slog, type Handler interface { Enabled, Handle, WithAttrs, WithGroup } #56345
135+
pkg log/slog, type Handler interface, Enabled(context.Context, Level) bool #56345
136+
pkg log/slog, type Handler interface, Handle(context.Context, Record) error #56345
137+
pkg log/slog, type Handler interface, WithAttrs([]Attr) Handler #56345
138+
pkg log/slog, type Handler interface, WithGroup(string) Handler #56345
139+
pkg log/slog, type HandlerOptions struct #56345
140+
pkg log/slog, type HandlerOptions struct, AddSource bool #56345
141+
pkg log/slog, type HandlerOptions struct, Level Leveler #56345
142+
pkg log/slog, type HandlerOptions struct, ReplaceAttr func([]string, Attr) Attr #56345
143+
pkg log/slog, type JSONHandler struct #56345
144+
pkg log/slog, type Kind int #56345
145+
pkg log/slog, type Level int #56345
146+
pkg log/slog, type LevelVar struct #56345
147+
pkg log/slog, type Leveler interface { Level } #56345
148+
pkg log/slog, type Leveler interface, Level() Level #56345
149+
pkg log/slog, type LogValuer interface { LogValue } #56345
150+
pkg log/slog, type LogValuer interface, LogValue() Value #56345
151+
pkg log/slog, type Logger struct #56345
152+
pkg log/slog, type Record struct #56345
153+
pkg log/slog, type Record struct, Level Level #56345
154+
pkg log/slog, type Record struct, Message string #56345
155+
pkg log/slog, type Record struct, PC uintptr #56345
156+
pkg log/slog, type Record struct, Time time.Time #56345
157+
pkg log/slog, type TextHandler struct #56345
158+
pkg log/slog, type Value struct #56345

src/go/build/deps_test.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ var depsRules = `
317317
318318
# Bulk of the standard library must not use cgo.
319319
# The prohibition stops at net and os/user.
320-
C !< fmt, go/types, CRYPTO-MATH;
320+
C !< fmt, go/types, CRYPTO-MATH, log/slog;
321321
322322
CGO, OS
323323
< plugin;
@@ -372,11 +372,22 @@ var depsRules = `
372372
FMT
373373
< log;
374374
375-
log !< crypto/tls, database/sql, go/importer, testing;
375+
log, log/slog !< crypto/tls, database/sql, go/importer, testing;
376376
377377
FMT, log, net
378378
< log/syslog;
379379
380+
RUNTIME
381+
< log/slog/internal, log/slog/internal/buffer;
382+
383+
FMT,
384+
encoding, encoding/json,
385+
log,
386+
log/slog/internal, log/slog/internal/buffer,
387+
slices
388+
< log/slog
389+
< log/slog/internal/testutil;
390+
380391
NET, log
381392
< net/mail;
382393

src/log/slog/attr.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright 2022 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package slog
6+
7+
import (
8+
"fmt"
9+
"time"
10+
)
11+
12+
// An Attr is a key-value pair.
13+
type Attr struct {
14+
Key string
15+
Value Value
16+
}
17+
18+
// String returns an Attr for a string value.
19+
func String(key, value string) Attr {
20+
return Attr{key, StringValue(value)}
21+
}
22+
23+
// Int64 returns an Attr for an int64.
24+
func Int64(key string, value int64) Attr {
25+
return Attr{key, Int64Value(value)}
26+
}
27+
28+
// Int converts an int to an int64 and returns
29+
// an Attr with that value.
30+
func Int(key string, value int) Attr {
31+
return Int64(key, int64(value))
32+
}
33+
34+
// Uint64 returns an Attr for a uint64.
35+
func Uint64(key string, v uint64) Attr {
36+
return Attr{key, Uint64Value(v)}
37+
}
38+
39+
// Float64 returns an Attr for a floating-point number.
40+
func Float64(key string, v float64) Attr {
41+
return Attr{key, Float64Value(v)}
42+
}
43+
44+
// Bool returns an Attr for a bool.
45+
func Bool(key string, v bool) Attr {
46+
return Attr{key, BoolValue(v)}
47+
}
48+
49+
// Time returns an Attr for a time.Time.
50+
// It discards the monotonic portion.
51+
func Time(key string, v time.Time) Attr {
52+
return Attr{key, TimeValue(v)}
53+
}
54+
55+
// Duration returns an Attr for a time.Duration.
56+
func Duration(key string, v time.Duration) Attr {
57+
return Attr{key, DurationValue(v)}
58+
}
59+
60+
// Group returns an Attr for a Group Value.
61+
// The caller must not subsequently mutate the
62+
// argument slice.
63+
//
64+
// Use Group to collect several Attrs under a single
65+
// key on a log line, or as the result of LogValue
66+
// in order to log a single value as multiple Attrs.
67+
func Group(key string, as ...Attr) Attr {
68+
return Attr{key, GroupValue(as...)}
69+
}
70+
71+
// Any returns an Attr for the supplied value.
72+
// See [Value.AnyValue] for how values are treated.
73+
func Any(key string, value any) Attr {
74+
return Attr{key, AnyValue(value)}
75+
}
76+
77+
// Equal reports whether a and b have equal keys and values.
78+
func (a Attr) Equal(b Attr) bool {
79+
return a.Key == b.Key && a.Value.Equal(b.Value)
80+
}
81+
82+
func (a Attr) String() string {
83+
return fmt.Sprintf("%s=%s", a.Key, a.Value)
84+
}

src/log/slog/attr_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2022 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package slog
6+
7+
import (
8+
"internal/testenv"
9+
"testing"
10+
"time"
11+
)
12+
13+
func TestAttrNoAlloc(t *testing.T) {
14+
testenv.SkipIfOptimizationOff(t)
15+
// Assign values just to make sure the compiler doesn't optimize away the statements.
16+
var (
17+
i int64
18+
u uint64
19+
f float64
20+
b bool
21+
s string
22+
x any
23+
p = &i
24+
d time.Duration
25+
)
26+
a := int(testing.AllocsPerRun(5, func() {
27+
i = Int64("key", 1).Value.Int64()
28+
u = Uint64("key", 1).Value.Uint64()
29+
f = Float64("key", 1).Value.Float64()
30+
b = Bool("key", true).Value.Bool()
31+
s = String("key", "foo").Value.String()
32+
d = Duration("key", d).Value.Duration()
33+
x = Any("key", p).Value.Any()
34+
}))
35+
if a != 0 {
36+
t.Errorf("got %d allocs, want zero", a)
37+
}
38+
_ = u
39+
_ = f
40+
_ = b
41+
_ = s
42+
_ = x
43+
}

0 commit comments

Comments
 (0)