Logger

log.New, the options, the Logger interface, Wrap, Discard, and the process-wide default.

The logger is the main entry point. New assembles outputs, a level, and filters into a Logger you build once and pass around.

New

func New(opts ...Option) Logger

Assembles a Logger from the given options. With no outputs it writes text to stdout at DEBUG. Several outputs fan out through a MultiHandler, and any filters wrap the assembled outputs in a FilterHandler.

logger := log.New(
	log.WithText(os.Stdout),
	log.WithLevel(slog.LevelInfo),
)

Options

Each option is an Option, a function that configures the logger being built. Pass any number to New.

func WithText(w io.Writer) Option

Adds a text handler writing to w.

func WithJSON(w io.Writer) Option

Adds a JSON handler writing to w. Pass a rotating writer such as a lumberjack.Logger here to keep that dependency out of this module.

func WithOutput(h slog.Handler) Option

Adds an arbitrary slog.Handler, such as a memory sink or an exporter. The handler controls its own level, so WithLevel does not affect it.

func WithLevel(level slog.Level) Option

Sets the minimum level for the Text and JSON outputs. Defaults to DEBUG.

func WithFilters(filters ...Filter) Option

Wraps the assembled outputs in a FilterHandler running the given filters. See the filters reference.

The Logger interface

type Logger interface {
	slog.Handler
	With(args ...any) Logger
	// WithLevel returns a logger with a new minimum level, preserving the
	// underlying outputs, format, and attributes.
	WithLevel(level slog.Level) Logger
	Trace(msg string, args ...any)
	Debug(msg string, args ...any)
	Info(msg string, args ...any)
	Warn(msg string, args ...any)
	Error(msg string, args ...any)
	// Fatal logs at LevelFatal and returns; it does not exit the process.
	Fatal(msg string, args ...any)
	// Slog returns the wrapped *slog.Logger as an escape hatch.
	Slog() *slog.Logger
}

Logger embeds slog.Handler, so it drops into any code that expects a handler, and adds the level helpers plus the custom Trace and Fatal. With returns a logger that carries extra attributes on every record. WithLevel returns a logger at a new minimum level, preserving the underlying outputs, format, and attributes. Slog returns the wrapped *slog.Logger as an escape hatch.

Wrap and Discard

func Wrap(l *slog.Logger) Logger

Adopts an existing *slog.Logger as a Logger. Use it when you have assembled handlers by hand.

func Discard() Logger

Returns a Logger that drops every record, useful as a silent default in tests or in libraries that take a Logger but should produce no output. It reports itself disabled at every level.

The process-wide default

The package holds one default logger, created at startup, writing text to stdout. The package-level helpers route through it.

func Default() Logger
func SetDefault(l Logger)

Default returns the process-wide logger, and SetDefault replaces it. After SetDefault, log.Info and the other helpers write to your logger.

func SetLevel(level slog.Level)
func Level() slog.Level

SetLevel moves the minimum level of the built-in default logger, and Level returns it. Once SetDefault installs a logger of your own, SetLevel has no effect on it, so set that logger's level with WithLevel when you build it.

The helpers each log at their level on the default logger.

func Trace(msg string, args ...any)
func Debug(msg string, args ...any)
func Info(msg string, args ...any)
func Warn(msg string, args ...any)
func Error(msg string, args ...any)
func Fatal(msg string, args ...any)