// 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 slogimport (loginternal)var defaultLogger atomic.Pointer[Logger]var logLoggerLevel LevelVar// SetLogLoggerLevel controls the level for the bridge to the [log] package.//// Before [SetDefault] is called, slog top-level logging functions call the default [log.Logger].// In that mode, SetLogLoggerLevel sets the minimum level for those calls.// By default, the minimum level is Info, so calls to [Debug]// (as well as top-level logging calls at lower levels)// will not be passed to the log.Logger. After calling//// slog.SetLogLoggerLevel(slog.LevelDebug)//// calls to [Debug] will be passed to the log.Logger.//// After [SetDefault] is called, calls to the default [log.Logger] are passed to the// slog default handler. In that mode,// SetLogLoggerLevel sets the level at which those calls are logged.// That is, after calling//// slog.SetLogLoggerLevel(slog.LevelDebug)//// A call to [log.Printf] will result in output at level [LevelDebug].//// SetLogLoggerLevel returns the previous value.func ( Level) ( Level) { = logLoggerLevel.Level()logLoggerLevel.Set()return}func init() {defaultLogger.Store(New(newDefaultHandler(loginternal.DefaultOutput)))}// Default returns the default [Logger].func () *Logger { returndefaultLogger.Load() }// SetDefault makes l the default [Logger], which is used by// the top-level functions [Info], [Debug] and so on.// After this call, output from the log package's default Logger// (as with [log.Print], etc.) will be logged using l's Handler,// at a level controlled by [SetLogLoggerLevel].func ( *Logger) {defaultLogger.Store()// If the default's handler is a defaultHandler, then don't use a handleWriter, // or we'll deadlock as they both try to acquire the log default mutex. // The defaultHandler will use whatever the log default writer is currently // set to, which is correct. // This can occur with SetDefault(Default()). // See TestSetDefault.if , := .Handler().(*defaultHandler); ! { := log.Flags()&(log.Lshortfile|log.Llongfile) != 0log.SetOutput(&handlerWriter{.Handler(), &logLoggerLevel, })log.SetFlags(0) // we want just the log message, no time or location }}// handlerWriter is an io.Writer that calls a Handler.// It is used to link the default log.Logger to the default slog.Logger.type handlerWriter struct { h Handler level Leveler capturePC bool}func ( *handlerWriter) ( []byte) (int, error) { := .level.Level()if !.h.Enabled(context.Background(), ) {return0, nil }varuintptrif !internal.IgnorePC && .capturePC {// skip [runtime.Callers, w.Write, Logger.Output, log.Print]var [1]uintptrruntime.Callers(4, [:]) = [0] }// Remove final newline. := len() // Report that the entire buf was written.iflen() > 0 && [len()-1] == '\n' { = [:len()-1] } := NewRecord(time.Now(), , string(), )return , .h.Handle(context.Background(), )}// A Logger records structured information about each call to its// Log, Debug, Info, Warn, and Error methods.// For each call, it creates a [Record] and passes it to a [Handler].//// To create a new Logger, call [New] or a Logger method// that begins "With".typeLoggerstruct { handler Handler// for structured logging}func ( *Logger) () *Logger { := *return &}// Handler returns l's Handler.func ( *Logger) () Handler { return .handler }// With returns a Logger that includes the given attributes// in each output operation. Arguments are converted to// attributes as if by [Logger.Log].func ( *Logger) ( ...any) *Logger {iflen() == 0 {return } := .clone() .handler = .handler.WithAttrs(argsToAttrSlice())return}// WithGroup returns a Logger that starts a group, if name is non-empty.// The keys of all attributes added to the Logger will be qualified by the given// name. (How that qualification happens depends on the [Handler.WithGroup]// method of the Logger's Handler.)//// If name is empty, WithGroup returns the receiver.func ( *Logger) ( string) *Logger {if == "" {return } := .clone() .handler = .handler.WithGroup()return}// New creates a new Logger with the given non-nil Handler.func ( Handler) *Logger {if == nil {panic("nil Handler") }return &Logger{handler: }}// With calls [Logger.With] on the default logger.func ( ...any) *Logger {returnDefault().With(...)}// Enabled reports whether l emits log records at the given context and level.func ( *Logger) ( context.Context, Level) bool {if == nil { = context.Background() }return .Handler().Enabled(, )}// NewLogLogger returns a new [log.Logger] such that each call to its Output method// dispatches a Record to the specified handler. The logger acts as a bridge from// the older log API to newer structured logging handlers.func ( Handler, Level) *log.Logger {returnlog.New(&handlerWriter{, , true}, "", 0)}// Log emits a log record with the current time and the given level and message.// The Record's Attrs consist of the Logger's attributes followed by// the Attrs specified by args.//// The attribute arguments are processed as follows:// - If an argument is an Attr, it is used as is.// - If an argument is a string and this is not the last argument,// the following argument is treated as the value and the two are combined// into an Attr.// - Otherwise, the argument is treated as a value with key "!BADKEY".func ( *Logger) ( context.Context, Level, string, ...any) { .log(, , , ...)}// LogAttrs is a more efficient version of [Logger.Log] that accepts only Attrs.func ( *Logger) ( context.Context, Level, string, ...Attr) { .logAttrs(, , , ...)}// Debug logs at [LevelDebug].func ( *Logger) ( string, ...any) { .log(context.Background(), LevelDebug, , ...)}// DebugContext logs at [LevelDebug] with the given context.func ( *Logger) ( context.Context, string, ...any) { .log(, LevelDebug, , ...)}// Info logs at [LevelInfo].func ( *Logger) ( string, ...any) { .log(context.Background(), LevelInfo, , ...)}// InfoContext logs at [LevelInfo] with the given context.func ( *Logger) ( context.Context, string, ...any) { .log(, LevelInfo, , ...)}// Warn logs at [LevelWarn].func ( *Logger) ( string, ...any) { .log(context.Background(), LevelWarn, , ...)}// WarnContext logs at [LevelWarn] with the given context.func ( *Logger) ( context.Context, string, ...any) { .log(, LevelWarn, , ...)}// Error logs at [LevelError].func ( *Logger) ( string, ...any) { .log(context.Background(), LevelError, , ...)}// ErrorContext logs at [LevelError] with the given context.func ( *Logger) ( context.Context, string, ...any) { .log(, LevelError, , ...)}// log is the low-level logging method for methods that take ...any.// It must always be called directly by an exported logging method// or function, because it uses a fixed call depth to obtain the pc.func ( *Logger) ( context.Context, Level, string, ...any) {if !.Enabled(, ) {return }varuintptrif !internal.IgnorePC {var [1]uintptr// skip [runtime.Callers, this function, this function's caller]runtime.Callers(3, [:]) = [0] } := NewRecord(time.Now(), , , ) .Add(...)if == nil { = context.Background() } _ = .Handler().Handle(, )}// logAttrs is like [Logger.log], but for methods that take ...Attr.func ( *Logger) ( context.Context, Level, string, ...Attr) {if !.Enabled(, ) {return }varuintptrif !internal.IgnorePC {var [1]uintptr// skip [runtime.Callers, this function, this function's caller]runtime.Callers(3, [:]) = [0] } := NewRecord(time.Now(), , , ) .AddAttrs(...)if == nil { = context.Background() } _ = .Handler().Handle(, )}// Debug calls [Logger.Debug] on the default logger.func ( string, ...any) {Default().log(context.Background(), LevelDebug, , ...)}// DebugContext calls [Logger.DebugContext] on the default logger.func ( context.Context, string, ...any) {Default().log(, LevelDebug, , ...)}// Info calls [Logger.Info] on the default logger.func ( string, ...any) {Default().log(context.Background(), LevelInfo, , ...)}// InfoContext calls [Logger.InfoContext] on the default logger.func ( context.Context, string, ...any) {Default().log(, LevelInfo, , ...)}// Warn calls [Logger.Warn] on the default logger.func ( string, ...any) {Default().log(context.Background(), LevelWarn, , ...)}// WarnContext calls [Logger.WarnContext] on the default logger.func ( context.Context, string, ...any) {Default().log(, LevelWarn, , ...)}// Error calls [Logger.Error] on the default logger.func ( string, ...any) {Default().log(context.Background(), LevelError, , ...)}// ErrorContext calls [Logger.ErrorContext] on the default logger.func ( context.Context, string, ...any) {Default().log(, LevelError, , ...)}// Log calls [Logger.Log] on the default logger.func ( context.Context, Level, string, ...any) {Default().log(, , , ...)}// LogAttrs calls [Logger.LogAttrs] on the default logger.func ( context.Context, Level, string, ...Attr) {Default().logAttrs(, , , ...)}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.