slog: rename AtomicLevel to LevelVar; doc tweaks
These changes were suggested in https://go-review.git.corp.google.com/c/proposal/+/444415/6.
Change-Id: If95b5c14c5e3fd611449cd259e2c5a1b488be229
Reviewed-on: https://go-review.googlesource.com/c/exp/+/446495
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/slog/attr.go b/slog/attr.go
index 90541ee..29431cb 100644
--- a/slog/attr.go
+++ b/slog/attr.go
@@ -74,9 +74,9 @@
return Attr{key, AnyValue(value)}
}
-// Equal reports whether two Attrs have equal keys and values.
-func (a1 Attr) Equal(a2 Attr) bool {
- return a1.Key == a2.Key && a1.Value.Equal(a2.Value)
+// Equal reports whether a and b have equal keys and values.
+func (a Attr) Equal(b Attr) bool {
+ return a.Key == b.Key && a.Value.Equal(b.Value)
}
func (a Attr) String() string {
diff --git a/slog/handler.go b/slog/handler.go
index 5d476b2..893fad7 100644
--- a/slog/handler.go
+++ b/slog/handler.go
@@ -106,19 +106,21 @@
// HandlerOptions are options for a TextHandler or JSONHandler.
// A zero HandlerOptions consists entirely of default values.
type HandlerOptions struct {
- // Add a "source" attribute to the output whose value is of the form
- // "file:line".
- // This is false by default, because there is a cost to extracting this
- // information.
+ // When AddSource is true, the handler adds a ("source", "file:line")
+ // attribute to the output indicating the source code position of the log
+ // statement. AddSource is false by default to skip the cost of computing
+ // this information.
AddSource bool
- // Ignore records with levels below Level.Level().
- // The default is InfoLevel.
+ // Level reports the minimum record level that will be logged.
+ // The handler discards records with lower levels.
+ // If Level is nil, the handler assumes InfoLevel.
+ // The handler calls Level.Level for each record processed;
+ // to adjust the minimum level dynamically, use a LevelVar.
Level Leveler
- // If set, ReplaceAttr is called on each attribute of the message,
- // and the returned value is used instead of the original. If the returned
- // key is empty, the attribute is omitted from the output.
+ // ReplaceAttr is called to rewrite each attribute before it is logged.
+ // If ReplaceAttr returns an Attr with Key == "", the attribute is discarded.
//
// The built-in attributes with keys "time", "level", "source", and "msg"
// are passed to this function first, except that time and level are omitted
diff --git a/slog/handler_test.go b/slog/handler_test.go
index 3cfe9ff..0223cb8 100644
--- a/slog/handler_test.go
+++ b/slog/handler_test.go
@@ -319,8 +319,8 @@
}
func TestHandlerEnabled(t *testing.T) {
- atomicLevel := func(l Level) *AtomicLevel {
- var al AtomicLevel
+ levelVar := func(l Level) *LevelVar {
+ var al LevelVar
al.Set(l)
return &al
}
@@ -331,10 +331,10 @@
}{
{nil, true},
{WarnLevel, false},
- {&AtomicLevel{}, true}, // defaults to Info
- {atomicLevel(WarnLevel), false},
+ {&LevelVar{}, true}, // defaults to Info
+ {levelVar(WarnLevel), false},
{DebugLevel, true},
- {atomicLevel(DebugLevel), true},
+ {levelVar(DebugLevel), true},
} {
h := &commonHandler{opts: HandlerOptions{Level: test.leveler}}
got := h.enabled(InfoLevel)
diff --git a/slog/level.go b/slog/level.go
index b799470..1d0ba18 100644
--- a/slog/level.go
+++ b/slog/level.go
@@ -83,25 +83,27 @@
// It implements Leveler.
func (l Level) Level() Level { return l }
-// An AtomicLevel is a Level that can be read and written safely by multiple
-// goroutines.
-// The default value of AtomicLevel is InfoLevel.
-type AtomicLevel struct {
+// A LevelVar is a Level variable, to allow a Handler level to change
+// dynamically.
+// It implements Leveler as well as a Set method,
+// and it is safe for use by multiple goroutines.
+// The zero LevelVar corresponds to InfoLevel.
+type LevelVar struct {
val atomic.Int64
}
-// Level returns r's level.
-func (a *AtomicLevel) Level() Level {
- return Level(int(a.val.Load()))
+// Level returns v's level.
+func (v *LevelVar) Level() Level {
+ return Level(int(v.val.Load()))
}
-// Set sets the receiver's level to l.
-func (a *AtomicLevel) Set(l Level) {
- a.val.Store(int64(l))
+// Set sets v's level to l.
+func (v *LevelVar) Set(l Level) {
+ v.val.Store(int64(l))
}
-func (a *AtomicLevel) String() string {
- return fmt.Sprintf("AtomicLevel(%s)", a.Level())
+func (v *LevelVar) String() string {
+ return fmt.Sprintf("LevelVar(%s)", v.Level())
}
// A Leveler provides a Level value.
@@ -109,7 +111,7 @@
// As Level itself implements Leveler, clients typically supply
// a Level value wherever a Leveler is needed, such as in HandlerOptions.
// Clients who need to vary the level dynamically can provide a more complex
-// Leveler implementation such as *AtomicLevel.
+// Leveler implementation such as *LevelVar.
type Leveler interface {
Level() Level
}
diff --git a/slog/level_test.go b/slog/level_test.go
index b0a6013..d85de39 100644
--- a/slog/level_test.go
+++ b/slog/level_test.go
@@ -32,8 +32,8 @@
}
}
-func TestAtomicLevel(t *testing.T) {
- var al AtomicLevel
+func TestLevelVar(t *testing.T) {
+ var al LevelVar
if got, want := al.Level(), InfoLevel; got != want {
t.Errorf("got %v, want %v", got, want)
}
diff --git a/slog/logger.go b/slog/logger.go
index 942c5e8..8be8c34 100644
--- a/slog/logger.go
+++ b/slog/logger.go
@@ -78,7 +78,7 @@
func (l Logger) Context() context.Context { return l.ctx }
// With returns a new Logger that includes the given arguments, converted to
-// Attrs as in [Logger.Log]. The Attrs will be prepended to each output from the
+// Attrs as in [Logger.Log]. The Attrs will be added to each output from the
// Logger.
//
// The new Logger's handler is the result of calling WithAttrs on the receiver's
diff --git a/slog/value.go b/slog/value.go
index de127b1..bcf10bd 100644
--- a/slog/value.go
+++ b/slog/value.go
@@ -168,7 +168,7 @@
//////////////// Accessors
-// Any returns the Value's value as an any.
+// Any returns v's value as an any.
func (v Value) Any() any {
switch v.Kind() {
case AnyKind, GroupKind, LogValuerKind:
@@ -195,8 +195,8 @@
}
}
-// Int64 returns the Value's value as an int64. It panics
-// if the value is not a signed integer.
+// Int64 returns v's value as an int64. It panics
+// if v is not a signed integer.
func (v Value) Int64() int64 {
if g, w := v.Kind(), Int64Kind; g != w {
panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
@@ -204,8 +204,8 @@
return int64(v.num)
}
-// Uint64 returns the Value's value as a uint64. It panics
-// if the value is not an unsigned integer.
+// Uint64 returns v's value as a uint64. It panics
+// if v is not an unsigned integer.
func (v Value) Uint64() uint64 {
if g, w := v.Kind(), Uint64Kind; g != w {
panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
@@ -213,8 +213,8 @@
return v.num
}
-// Bool returns the Value's value as a bool. It panics
-// if the value is not a bool.
+// Bool returns v's value as a bool. It panics
+// if v is not a bool.
func (v Value) Bool() bool {
if g, w := v.Kind(), BoolKind; g != w {
panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
@@ -226,8 +226,8 @@
return a.num == 1
}
-// Duration returns the Value's value as a time.Duration. It panics
-// if the value is not a time.Duration.
+// Duration returns v's value as a time.Duration. It panics
+// if v is not a time.Duration.
func (a Value) Duration() time.Duration {
if g, w := a.Kind(), DurationKind; g != w {
panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
@@ -240,8 +240,8 @@
return time.Duration(int64(a.num))
}
-// Float64 returns the Value's value as a float64. It panics
-// if the value is not a float64.
+// Float64 returns v's value as a float64. It panics
+// if v is not a float64.
func (v Value) Float64() float64 {
if g, w := v.Kind(), Float64Kind; g != w {
panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
@@ -254,8 +254,8 @@
return math.Float64frombits(a.num)
}
-// Time returns the Value's value as a time.Time. It panics
-// if the value is not a time.Time.
+// Time returns v's value as a time.Time. It panics
+// if v is not a time.Time.
func (v Value) Time() time.Time {
if g, w := v.Kind(), TimeKind; g != w {
panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
@@ -267,47 +267,47 @@
return time.Unix(0, int64(v.num)).In(v.any.(timeLocation))
}
-// LogValuer returns the Value's value as a LogValuer. It panics
-// if the value is not a LogValuer.
+// LogValuer returns v's value as a LogValuer. It panics
+// if v is not a LogValuer.
func (v Value) LogValuer() LogValuer {
return v.any.(LogValuer)
}
-// Group returns the Value's value as a []Attr.
-// It panics if the Value's Kind is not GroupKind.
+// Group returns v's value as a []Attr.
+// It panics if v's Kind is not GroupKind.
func (v Value) Group() []Attr {
return v.group()
}
//////////////// Other
-// Equal reports whether two Values have equal keys and values.
-func (v1 Value) Equal(v2 Value) bool {
- k1 := v1.Kind()
- k2 := v2.Kind()
+// Equal reports whether v and w have equal keys and values.
+func (v Value) Equal(w Value) bool {
+ k1 := v.Kind()
+ k2 := w.Kind()
if k1 != k2 {
return false
}
switch k1 {
case Int64Kind, Uint64Kind, BoolKind, DurationKind:
- return v1.num == v2.num
+ return v.num == w.num
case StringKind:
- return v1.str() == v2.str()
+ return v.str() == w.str()
case Float64Kind:
- return v1.float() == v2.float()
+ return v.float() == w.float()
case TimeKind:
- return v1.time().Equal(v2.time())
+ return v.time().Equal(w.time())
case AnyKind, LogValuerKind:
- return v1.any == v2.any // may panic if non-comparable
+ return v.any == w.any // may panic if non-comparable
case GroupKind:
- return slices.EqualFunc(v1.uncheckedGroup(), v2.uncheckedGroup(), Attr.Equal)
+ return slices.EqualFunc(v.uncheckedGroup(), w.uncheckedGroup(), Attr.Equal)
default:
panic(fmt.Sprintf("bad kind: %s", k1))
}
}
-// append appends a text representation of the Value to dst.
-// The value is formatted as with fmt.Sprint.
+// append appends a text representation of v to dst.
+// v is formatted as with fmt.Sprint.
func (v Value) append(dst []byte) []byte {
switch v.Kind() {
case StringKind:
@@ -331,8 +331,7 @@
}
}
-// A LogValuer is a Value that transforms itself into a different Value (or,
-// using the Group feature, a group of Attrs) at the moment it is logged.
+// A LogValuer is any Go value that can convert itself into a Value for logging.
//
// This mechanism may be used to defer expensive operations until they are
// needed, or to expand a single value into a sequence of components.
diff --git a/slog/value_safe.go b/slog/value_safe.go
index c5b66c9..38d5f97 100644
--- a/slog/value_safe.go
+++ b/slog/value_safe.go
@@ -26,7 +26,7 @@
any any
}
-// Kind returns the Value's Kind.
+// Kind returns v's Kind.
func (v Value) Kind() Kind {
switch k := v.any.(type) {
case Kind:
@@ -54,7 +54,7 @@
}
// String returns Value's value as a string, formatted like fmt.Sprint. Unlike
-// the methods Int64, Float64, and so on, which panic if the Value is of the
+// the methods Int64, Float64, and so on, which panic if v is of the
// wrong kind, String never panics.
func (v Value) String() string {
if v.Kind() == StringKind {
diff --git a/slog/value_unsafe.go b/slog/value_unsafe.go
index a5e86cb..f8e50cc 100644
--- a/slog/value_unsafe.go
+++ b/slog/value_unsafe.go
@@ -37,7 +37,7 @@
groupptr unsafe.Pointer // used in Value.any when the Value is a []Attr
)
-// Kind returns the Value's Kind.
+// Kind returns v's Kind.
func (v Value) Kind() Kind {
switch x := v.any.(type) {
case Kind:
@@ -72,7 +72,7 @@
}
// String returns Value's value as a string, formatted like fmt.Sprint. Unlike
-// the methods Int64, Float64, and so on, which panic if the Value is of the
+// the methods Int64, Float64, and so on, which panic if v is of the
// wrong kind, String never panics.
func (v Value) String() string {
if sp, ok := v.any.(stringptr); ok {