Source File
logger.go
Belonging Package
log/slog
// 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 () {defaultLogger.Store(New(newDefaultHandler(loginternal.DefaultOutput)))}// Default returns the default [Logger].func () *Logger { return defaultLogger.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 Handlerlevel LevelercapturePC bool}func ( *handlerWriter) ( []byte) (int, error) {:= .level.Level()if !.h.Enabled(context.Background(), ) {return 0, nil}var uintptrif !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.= bytes.TrimSuffix(, []byte{'\n'}):= 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".type Logger struct {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 {if len() == 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 {return Default().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 {return log.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].// It uses [context.Background] internally; to specify the context, use// [Logger.DebugContext].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].// It uses [context.Background] internally; to specify the context, use// [Logger.InfoContext].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].// It uses [context.Background] internally; to specify the context, use// [Logger.WarnContext].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].// It uses [context.Background] internally; to specify the context, use// [Logger.ErrorContext].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 == nil {= context.Background()}if !.Enabled(, ) {return}var uintptrif !internal.IgnorePC {var [1]uintptr// skip [runtime.Callers, this function, this function's caller]runtime.Callers(3, [:])= [0]}:= NewRecord(time.Now(), , , ).Add(...)_ = .Handler().Handle(, )}// logAttrs is like [Logger.log], but for methods that take ...Attr.func ( *Logger) ( context.Context, Level, string, ...Attr) {if == nil {= context.Background()}if !.Enabled(, ) {return}var uintptrif !internal.IgnorePC {var [1]uintptr// skip [runtime.Callers, this function, this function's caller]runtime.Callers(3, [:])= [0]}:= NewRecord(time.Now(), , , ).AddAttrs(...)_ = .Handler().Handle(, )}// Debug calls [Logger.Debug] on the default logger.// It uses [context.Background] internally; to specify the context, use// [DebugContext].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.// It uses [context.Background] internally; to specify the context, use// [InfoContext].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.// It uses [context.Background] internally; to specify the context, use// [WarnContext].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.// It uses [context.Background] internally; to specify the context, use// [ErrorContext].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 Golds v0.8.4. (GOOS=linux GOARCH=amd64)