aboutsummaryrefslogtreecommitdiff
path: root/design/56345-structured-logging.md
diff options
context:
space:
mode:
Diffstat (limited to 'design/56345-structured-logging.md')
-rw-r--r--design/56345-structured-logging.md66
1 files changed, 33 insertions, 33 deletions
diff --git a/design/56345-structured-logging.md b/design/56345-structured-logging.md
index 64fc949..91c10d8 100644
--- a/design/56345-structured-logging.md
+++ b/design/56345-structured-logging.md
@@ -133,9 +133,9 @@ import "log/slog"
func main() {
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr)))
slog.Info("hello", "name", "Al")
- slog.Error("oops", net.ErrClosed, "status", 500)
+ slog.Error("oops", "err", net.ErrClosed, "status", 500)
slog.LogAttrs(slog.LevelError, "oops",
- slog.Int("status", 500), slog.Any("err", net.ErrClosed))
+ slog.Any("err", net.ErrClosed), slog.Int("status", 500))
}
```
@@ -143,8 +143,8 @@ This program generates the following output on standard error:
```
time=2022-10-24T16:05:48.054-04:00 level=INFO msg=hello name=Al
-time=2022-10-24T16:05:48.054-04:00 level=ERROR msg=oops status=500 err="use of closed network connection"
-time=2022-10-24T16:05:48.054-04:00 level=ERROR msg=oops status=500 err="use of closed network connection"
+time=2022-10-24T16:05:48.054-04:00 level=ERROR err="use of closed network connection" msg=oops status=500
+time=2022-10-24T16:05:48.054-04:00 level=ERROR err="use of closed network connection" msg=oops status=500
```
It begins by setting the default logger to one that writes log records in an
@@ -157,14 +157,14 @@ producing mostly structured output:
```
2022/10/24 16:07:00 INFO hello name=Al
-2022/10/24 16:07:00 ERROR oops status=500 err="use of closed network connection"
-2022/10/24 16:07:00 ERROR oops status=500 err="use of closed network connection"
+2022/10/24 16:07:00 ERROR oops err="use of closed network connection" status=500
+2022/10/24 16:07:00 ERROR oops err="use of closed network connection" status=500
```
The program outputs three log messages augmented with key-value pairs.
The first logs at the Info level, passing a single key-value pair along with the
message.
-The second logs at the Error level, passing an `error` and a key-value pair.
+The second logs at the Error level, passing two key-value pairs.
The third produces the same output as the second, but more efficiently.
Functions like `Any` and `Int` construct `slog.Attr` values, which are key-value
@@ -632,9 +632,8 @@ func (l *Logger) Info(msg string, args ...any)
func (l *Logger) Warn(msg string, args ...any)
Warn logs at LevelWarn.
-func (l *Logger) Error(msg string, err error, args ...any)
- Error logs at LevelError. If err is non-nil, Error adds Any("err",
- err) before the list of attributes.
+func (l *Logger) Error(msg string, args ...any)
+ Error logs at LevelError.
func (l *Logger) DebugCtx(ctx context.Context, msg string, args ...any)
DebugCtx logs at LevelDebug with the given context.
@@ -645,8 +644,8 @@ func (l *Logger) InfoCtx(ctx context.Context, msg string, args ...any)
func (l *Logger) WarnCtx(ctx context.Context, msg string, args ...any)
WarnCtx logs at LevelWarn with the given context.
-func ErrorCtx(ctx context.Context, msg string, err error, args ...any)
- ErrorCtx calls Logger.ErrorCtx on the default logger.
+func (l *Logger) ErrorCtx(ctx context.Context, msg string, args ...any)
+ ErrorCtx logs at LevelError with the given context.
```
Loggers can have attributes as well, added by the `With` method.
@@ -1133,9 +1132,9 @@ distinct keys.
# Contexts
-Some handlers may wish to include information from the [current.Context] that
-is available at the call site. One example of such data is the identifier for a
-telemetry trace.
+Some handlers may wish to include information from the context.Context that is
+available at the call site. One example of such information is the identifier
+for the current span when tracing is is enabled.
The Logger.Log and Logger.LogAttrs methods take a context as a first argument,
as do their corresponding top-level functions.
@@ -1178,7 +1177,7 @@ and you call it like this in main.go:
Infof(slog.Default(), "hello, %s", "world")
-then slog will use source file mylog.go, not main.go.
+then slog will report the source file as mylog.go, not main.go.
A correct implementation of Infof will obtain the source location (pc) and
pass it to NewRecord. The Infof function in the package-level example called
@@ -1263,9 +1262,6 @@ const (
// SourceKey is the key used by the built-in handlers for the source file
// and line of the log call. The associated value is a string.
SourceKey = "source"
- // ErrorKey is the key used for errors by Logger.Error.
- // The associated value is an [error].
- ErrorKey = "err"
)
Keys for "built-in" attributes.
@@ -1278,10 +1274,10 @@ func Debug(msg string, args ...any)
func DebugCtx(ctx context.Context, msg string, args ...any)
DebugCtx calls Logger.DebugCtx on the default logger.
-func Error(msg string, err error, args ...any)
+func Error(msg string, args ...any)
Error calls Logger.Error on the default logger.
-func ErrorCtx(ctx context.Context, msg string, err error, args ...any)
+func ErrorCtx(ctx context.Context, msg string, args ...any)
ErrorCtx calls Logger.ErrorCtx on the default logger.
func Info(msg string, args ...any)
@@ -1366,15 +1362,16 @@ type Handler interface {
// The handler ignores records whose level is lower.
// It is called early, before any arguments are processed,
// to save effort if the log event should be discarded.
- // The Logger's context is passed so Enabled can use its values
- // to make a decision. The context may be nil.
+ // If called from a Logger method, the first argument is the context
+ // passed to that method, or context.Background() if nil was passed
+ // or the method does not take a context.
+ // The context is passed so Enabled can use its values
+ // to make a decision.
Enabled(context.Context, Level) bool
// Handle handles the Record.
- // It will only be called if Enabled returns true.
- //
- // The first argument is the context of the Logger that created the Record,
- // which may be nil.
+ // It will only be called Enabled returns true.
+ // The Context argument is as for Enabled.
// It is present solely to provide Handlers access to the context's values.
// Canceling the context should not affect record processing.
// (Among other things, log messages may be necessary to debug a
@@ -1382,6 +1379,7 @@ type Handler interface {
//
// Handle methods that produce output should observe the following rules:
// - If r.Time is the zero time, ignore the time.
+ // - If r.PC is zero, ignore it.
// - If an Attr's key is the empty string and the value is not a group,
// ignore the Attr.
// - If a group's key is empty, inline the group's Attrs.
@@ -1392,6 +1390,7 @@ type Handler interface {
// WithAttrs returns a new Handler whose attributes consist of
// both the receiver's attributes and the arguments.
// The Handler owns the slice: it may retain, modify or discard it.
+ // [Logger.With] will resolve the Attrs.
WithAttrs(attrs []Attr) Handler
// WithGroup returns a new Handler with the given group appended to
@@ -1425,6 +1424,9 @@ type Handler interface {
with other methods. It is the responsibility of the Handler to manage this
concurrency.
+ Users of the slog package should not invoke Handler methods directly.
+ They should use the methods of Logger instead.
+
type HandlerOptions struct {
// When AddSource is true, the handler adds a ("source", "file:line")
// attribute to the output indicating the source code position of the log
@@ -1666,13 +1668,11 @@ func (l *Logger) DebugCtx(ctx context.Context, msg string, args ...any)
func (l *Logger) Enabled(ctx context.Context, level Level) bool
Enabled reports whether l emits log records at the given context and level.
-func (l *Logger) Error(msg string, err error, args ...any)
- Error logs at LevelError. If err is non-nil, Error adds Any(ErrorKey,
- err) before the list of attributes.
+func (l *Logger) Error(msg string, args ...any)
+ Error logs at LevelError.
-func (l *Logger) ErrorCtx(ctx context.Context, msg string, err error, args ...any)
- ErrorCtx logs at LevelError with the given context. If err is non-nil,
- it adds Any(ErrorKey, err) before the list of attributes.
+func (l *Logger) ErrorCtx(ctx context.Context, msg string, args ...any)
+ ErrorCtx logs at LevelError with the given context.
func (l *Logger) Handler() Handler
Handler returns l's Handler.