Source File
logger.go
Belonging Package
go.pact.im/x/logs
package logsimport ()// Logger is an alternative implementation of [slog.Logger] that allows// configuring time source and program counter for log records.//// Unlike [slog.Logger], Logger does not provide convenience methods like// Info, Debug, Warn, or Error. Instead, all logging is done through the// Log method with explicit context, level, and attributes.type Logger struct {// handler is the underlying log handler.handler slog.Handler// timeNow is a function that returns the current time.// If timeNow is nil, [slog.Record.Time] will not be set.timeNow func() time.Time// capturePC indicates whether the logger should capture program// counter.capturePC bool// skipPC is the number of stack frames to skip for program counter.// If skipPC is negative, [slog.Record.PC] will not be set.skipPC int}// New creates a new [Logger] with the given non-nil [slog.Handler].func ( slog.Handler) *Logger {return &Logger{handler: ,timeNow: time.Now,capturePC: true,}}// Handler returns the underlying [slog.Handler].func ( *Logger) () slog.Handler {return .handler}// WithHandler returns a [Logger] that uses the given [slog.Handler].func ( *Logger) ( slog.Handler) *Logger {:= *.handler =return &}// WithAttrs returns a [Logger] that includes the given attributes in each// output operation.func ( *Logger) ( ...slog.Attr) *Logger {if len() == 0 {return}return .WithHandler(.handler.WithAttrs())}// WithGroup returns a [Logger] that starts a group. The keys of all attributes// added to the [Logger] will be qualified by the given name.//// If name is empty, WithGroup returns the receiver.func ( *Logger) ( string) *Logger {if == "" {return}return .WithHandler(.handler.WithGroup())}// WithTime returns a [Logger] that uses the given time function.// If now is nil, [slog.Record.Time] will not be set.func ( *Logger) ( func() time.Time) *Logger {if == nil && .timeNow == nil {return}:= *.timeNow =return &}// WithCapturePC returns a [Logger] with program counter capture toggled.// If v is false, [slog.Record.PC] will not be set regardless of WithSkipPC.func ( *Logger) ( bool) *Logger {if .capturePC == {return}:= *.capturePC =return &}// WithSkipPC returns a [Logger] that skips additional stack frames.// If n is non-positive, WithSkipPC returns the receiver.func ( *Logger) ( int) *Logger {if <= 0 || .skipPC < 0 {return}:= *.skipPC +=if .skipPC < 0 {.skipPC = -1}return &}// Enabled reports whether l emits log records at the given context and level.func ( *Logger) ( context.Context, slog.Level) bool {return .handler.Enabled(, )}// Log emits a log record with the given level, message, and attributes.//// By default, [slog.Record.PC] will be set to the caller’s program counter// and [slog.Record.Time] will be set to the current time. Use WithCapturePC,// WithSkipPC and WithTime methods to change this behavior.func ( *Logger) ( context.Context, slog.Level, string, ...slog.Attr) {if !.Enabled(, ) {return}_ = .output(, , , )}func ( *Logger) (context.Context,slog.Level,string,[]slog.Attr,) error {var time.Timeif .timeNow != nil {= .timeNow()}var uintptrif .capturePC && .skipPC >= 0 {// Skip 4 stack frames to log actual caller:// - runtime.Callers// - callerPC// - this function// - this function’s caller (Logger.Log or Writer.Write):= .skipPC + 4if >= 0 {= callerPC()}}:= slog.NewRecord(, , , ).AddAttrs(...)return .handler.Handle(, )}// callerPC returns the program counter at the given stack depth.func ( int) uintptr {var [1]uintptr_ = runtime.Callers(, [:])return [0]}
The pages are generated with Golds v0.8.4. (GOOS=linux GOARCH=amd64)