Skip to content

Commit

Permalink
log/slog: initial commit
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jba authored and eric committed Sep 7, 2023
1 parent dc1e088 commit 58b5dde
Show file tree
Hide file tree
Showing 33 changed files with 5,647 additions and 2 deletions.
158 changes: 158 additions & 0 deletions api/next/56345.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
pkg log/slog, const KindAny = 0 #56345
pkg log/slog, const KindAny Kind #56345
pkg log/slog, const KindBool = 1 #56345
pkg log/slog, const KindBool Kind #56345
pkg log/slog, const KindDuration = 2 #56345
pkg log/slog, const KindDuration Kind #56345
pkg log/slog, const KindFloat64 = 3 #56345
pkg log/slog, const KindFloat64 Kind #56345
pkg log/slog, const KindGroup = 8 #56345
pkg log/slog, const KindGroup Kind #56345
pkg log/slog, const KindInt64 = 4 #56345
pkg log/slog, const KindInt64 Kind #56345
pkg log/slog, const KindLogValuer = 9 #56345
pkg log/slog, const KindLogValuer Kind #56345
pkg log/slog, const KindString = 5 #56345
pkg log/slog, const KindString Kind #56345
pkg log/slog, const KindTime = 6 #56345
pkg log/slog, const KindTime Kind #56345
pkg log/slog, const KindUint64 = 7 #56345
pkg log/slog, const KindUint64 Kind #56345
pkg log/slog, const LevelDebug = -4 #56345
pkg log/slog, const LevelDebug Level #56345
pkg log/slog, const LevelError = 8 #56345
pkg log/slog, const LevelError Level #56345
pkg log/slog, const LevelInfo = 0 #56345
pkg log/slog, const LevelInfo Level #56345
pkg log/slog, const LevelKey = "level" #56345
pkg log/slog, const LevelKey ideal-string #56345
pkg log/slog, const LevelWarn = 4 #56345
pkg log/slog, const LevelWarn Level #56345
pkg log/slog, const MessageKey = "msg" #56345
pkg log/slog, const MessageKey ideal-string #56345
pkg log/slog, const SourceKey = "source" #56345
pkg log/slog, const SourceKey ideal-string #56345
pkg log/slog, const TimeKey = "time" #56345
pkg log/slog, const TimeKey ideal-string #56345
pkg log/slog, func Any(string, interface{}) Attr #56345
pkg log/slog, func AnyValue(interface{}) Value #56345
pkg log/slog, func Bool(string, bool) Attr #56345
pkg log/slog, func BoolValue(bool) Value #56345
pkg log/slog, func Debug(string, ...interface{}) #56345
pkg log/slog, func DebugCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Default() *Logger #56345
pkg log/slog, func Duration(string, time.Duration) Attr #56345
pkg log/slog, func DurationValue(time.Duration) Value #56345
pkg log/slog, func Error(string, ...interface{}) #56345
pkg log/slog, func ErrorCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Float64(string, float64) Attr #56345
pkg log/slog, func Float64Value(float64) Value #56345
pkg log/slog, func Group(string, ...Attr) Attr #56345
pkg log/slog, func GroupValue(...Attr) Value #56345
pkg log/slog, func Info(string, ...interface{}) #56345
pkg log/slog, func InfoCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Int(string, int) Attr #56345
pkg log/slog, func Int64(string, int64) Attr #56345
pkg log/slog, func Int64Value(int64) Value #56345
pkg log/slog, func IntValue(int) Value #56345
pkg log/slog, func Log(context.Context, Level, string, ...interface{}) #56345
pkg log/slog, func LogAttrs(context.Context, Level, string, ...Attr) #56345
pkg log/slog, func New(Handler) *Logger #56345
pkg log/slog, func NewJSONHandler(io.Writer) *JSONHandler #56345
pkg log/slog, func NewLogLogger(Handler, Level) *log.Logger #56345
pkg log/slog, func NewRecord(time.Time, Level, string, uintptr) Record #56345
pkg log/slog, func NewTextHandler(io.Writer) *TextHandler #56345
pkg log/slog, func SetDefault(*Logger) #56345
pkg log/slog, func String(string, string) Attr #56345
pkg log/slog, func StringValue(string) Value #56345
pkg log/slog, func Time(string, time.Time) Attr #56345
pkg log/slog, func TimeValue(time.Time) Value #56345
pkg log/slog, func Uint64(string, uint64) Attr #56345
pkg log/slog, func Uint64Value(uint64) Value #56345
pkg log/slog, func Warn(string, ...interface{}) #56345
pkg log/slog, func WarnCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func With(...interface{}) *Logger #56345
pkg log/slog, method (*JSONHandler) Enabled(context.Context, Level) bool #56345
pkg log/slog, method (*JSONHandler) Handle(context.Context, Record) error #56345
pkg log/slog, method (*JSONHandler) WithAttrs([]Attr) Handler #56345
pkg log/slog, method (*JSONHandler) WithGroup(string) Handler #56345
pkg log/slog, method (*Level) UnmarshalJSON([]uint8) error #56345
pkg log/slog, method (*Level) UnmarshalText([]uint8) error #56345
pkg log/slog, method (*LevelVar) Level() Level #56345
pkg log/slog, method (*LevelVar) MarshalText() ([]uint8, error) #56345
pkg log/slog, method (*LevelVar) Set(Level) #56345
pkg log/slog, method (*LevelVar) String() string #56345
pkg log/slog, method (*LevelVar) UnmarshalText([]uint8) error #56345
pkg log/slog, method (*Logger) Debug(string, ...interface{}) #56345
pkg log/slog, method (*Logger) DebugCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Enabled(context.Context, Level) bool #56345
pkg log/slog, method (*Logger) Error(string, ...interface{}) #56345
pkg log/slog, method (*Logger) ErrorCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Handler() Handler #56345
pkg log/slog, method (*Logger) Info(string, ...interface{}) #56345
pkg log/slog, method (*Logger) InfoCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Log(context.Context, Level, string, ...interface{}) #56345
pkg log/slog, method (*Logger) LogAttrs(context.Context, Level, string, ...Attr) #56345
pkg log/slog, method (*Logger) Warn(string, ...interface{}) #56345
pkg log/slog, method (*Logger) WarnCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) With(...interface{}) *Logger #56345
pkg log/slog, method (*Logger) WithGroup(string) *Logger #56345
pkg log/slog, method (*Record) Add(...interface{}) #56345
pkg log/slog, method (*Record) AddAttrs(...Attr) #56345
pkg log/slog, method (*TextHandler) Enabled(context.Context, Level) bool #56345
pkg log/slog, method (*TextHandler) Handle(context.Context, Record) error #56345
pkg log/slog, method (*TextHandler) WithAttrs([]Attr) Handler #56345
pkg log/slog, method (*TextHandler) WithGroup(string) Handler #56345
pkg log/slog, method (Attr) Equal(Attr) bool #56345
pkg log/slog, method (Attr) String() string #56345
pkg log/slog, method (HandlerOptions) NewJSONHandler(io.Writer) *JSONHandler #56345
pkg log/slog, method (HandlerOptions) NewTextHandler(io.Writer) *TextHandler #56345
pkg log/slog, method (Kind) String() string #56345
pkg log/slog, method (Level) Level() Level #56345
pkg log/slog, method (Level) MarshalJSON() ([]uint8, error) #56345
pkg log/slog, method (Level) MarshalText() ([]uint8, error) #56345
pkg log/slog, method (Level) String() string #56345
pkg log/slog, method (Record) Attrs(func(Attr)) #56345
pkg log/slog, method (Record) Clone() Record #56345
pkg log/slog, method (Record) NumAttrs() int #56345
pkg log/slog, method (Value) Any() interface{} #56345
pkg log/slog, method (Value) Bool() bool #56345
pkg log/slog, method (Value) Duration() time.Duration #56345
pkg log/slog, method (Value) Equal(Value) bool #56345
pkg log/slog, method (Value) Float64() float64 #56345
pkg log/slog, method (Value) Group() []Attr #56345
pkg log/slog, method (Value) Int64() int64 #56345
pkg log/slog, method (Value) Kind() Kind #56345
pkg log/slog, method (Value) LogValuer() LogValuer #56345
pkg log/slog, method (Value) Resolve() Value #56345
pkg log/slog, method (Value) String() string #56345
pkg log/slog, method (Value) Time() time.Time #56345
pkg log/slog, method (Value) Uint64() uint64 #56345
pkg log/slog, type Attr struct #56345
pkg log/slog, type Attr struct, Key string #56345
pkg log/slog, type Attr struct, Value Value #56345
pkg log/slog, type Handler interface { Enabled, Handle, WithAttrs, WithGroup } #56345
pkg log/slog, type Handler interface, Enabled(context.Context, Level) bool #56345
pkg log/slog, type Handler interface, Handle(context.Context, Record) error #56345
pkg log/slog, type Handler interface, WithAttrs([]Attr) Handler #56345
pkg log/slog, type Handler interface, WithGroup(string) Handler #56345
pkg log/slog, type HandlerOptions struct #56345
pkg log/slog, type HandlerOptions struct, AddSource bool #56345
pkg log/slog, type HandlerOptions struct, Level Leveler #56345
pkg log/slog, type HandlerOptions struct, ReplaceAttr func([]string, Attr) Attr #56345
pkg log/slog, type JSONHandler struct #56345
pkg log/slog, type Kind int #56345
pkg log/slog, type Level int #56345
pkg log/slog, type LevelVar struct #56345
pkg log/slog, type Leveler interface { Level } #56345
pkg log/slog, type Leveler interface, Level() Level #56345
pkg log/slog, type LogValuer interface { LogValue } #56345
pkg log/slog, type LogValuer interface, LogValue() Value #56345
pkg log/slog, type Logger struct #56345
pkg log/slog, type Record struct #56345
pkg log/slog, type Record struct, Level Level #56345
pkg log/slog, type Record struct, Message string #56345
pkg log/slog, type Record struct, PC uintptr #56345
pkg log/slog, type Record struct, Time time.Time #56345
pkg log/slog, type TextHandler struct #56345
pkg log/slog, type Value struct #56345
15 changes: 13 additions & 2 deletions src/go/build/deps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ var depsRules = `
# Bulk of the standard library must not use cgo.
# The prohibition stops at net and os/user.
C !< fmt, go/types, CRYPTO-MATH;
C !< fmt, go/types, CRYPTO-MATH, log/slog;
CGO, OS
< plugin;
Expand Down Expand Up @@ -372,11 +372,22 @@ var depsRules = `
FMT
< log;
log !< crypto/tls, database/sql, go/importer, testing;
log, log/slog !< crypto/tls, database/sql, go/importer, testing;
FMT, log, net
< log/syslog;
RUNTIME
< log/slog/internal, log/slog/internal/buffer;
FMT,
encoding, encoding/json,
log,
log/slog/internal, log/slog/internal/buffer,
slices
< log/slog
< log/slog/internal/testutil;
NET, log
< net/mail;
Expand Down
84 changes: 84 additions & 0 deletions src/log/slog/attr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package slog

import (
"fmt"
"time"
)

// An Attr is a key-value pair.
type Attr struct {
Key string
Value Value
}

// String returns an Attr for a string value.
func String(key, value string) Attr {
return Attr{key, StringValue(value)}
}

// Int64 returns an Attr for an int64.
func Int64(key string, value int64) Attr {
return Attr{key, Int64Value(value)}
}

// Int converts an int to an int64 and returns
// an Attr with that value.
func Int(key string, value int) Attr {
return Int64(key, int64(value))
}

// Uint64 returns an Attr for a uint64.
func Uint64(key string, v uint64) Attr {
return Attr{key, Uint64Value(v)}
}

// Float64 returns an Attr for a floating-point number.
func Float64(key string, v float64) Attr {
return Attr{key, Float64Value(v)}
}

// Bool returns an Attr for a bool.
func Bool(key string, v bool) Attr {
return Attr{key, BoolValue(v)}
}

// Time returns an Attr for a time.Time.
// It discards the monotonic portion.
func Time(key string, v time.Time) Attr {
return Attr{key, TimeValue(v)}
}

// Duration returns an Attr for a time.Duration.
func Duration(key string, v time.Duration) Attr {
return Attr{key, DurationValue(v)}
}

// Group returns an Attr for a Group Value.
// The caller must not subsequently mutate the
// argument slice.
//
// Use Group to collect several Attrs under a single
// key on a log line, or as the result of LogValue
// in order to log a single value as multiple Attrs.
func Group(key string, as ...Attr) Attr {
return Attr{key, GroupValue(as...)}
}

// Any returns an Attr for the supplied value.
// See [Value.AnyValue] for how values are treated.
func Any(key string, value any) Attr {
return Attr{key, AnyValue(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 {
return fmt.Sprintf("%s=%s", a.Key, a.Value)
}
43 changes: 43 additions & 0 deletions src/log/slog/attr_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package slog

import (
"internal/testenv"
"testing"
"time"
)

func TestAttrNoAlloc(t *testing.T) {
testenv.SkipIfOptimizationOff(t)
// Assign values just to make sure the compiler doesn't optimize away the statements.
var (
i int64
u uint64
f float64
b bool
s string
x any
p = &i
d time.Duration
)
a := int(testing.AllocsPerRun(5, func() {
i = Int64("key", 1).Value.Int64()
u = Uint64("key", 1).Value.Uint64()
f = Float64("key", 1).Value.Float64()
b = Bool("key", true).Value.Bool()
s = String("key", "foo").Value.String()
d = Duration("key", d).Value.Duration()
x = Any("key", p).Value.Any()
}))
if a != 0 {
t.Errorf("got %d allocs, want zero", a)
}
_ = u
_ = f
_ = b
_ = s
_ = x
}
Loading

0 comments on commit 58b5dde

Please sign in to comment.