Logging common fields

April 16, 2026

It’s common that you’ll want to include certain attributes in all logs in an application or component. log/slog makes this pretty easy.

Overview

Some attributes are common to many log calls. For example, you may wish to include the URL or trace identifier of a server request with all log events arising from the request. Rather than repeat the attribute with every log call, you can use Logger.With to construct a new Logger containing the attributes:

logger2 := logger.With("url", r.URL)

The arguments to With are the same key-value pairs used in Logger.Info. The result is a new Logger with the same handler as the original, but additional attributes that will appear in the output of every call.

Put another way:

logger.Error("oh noes!", "foo", "bar")

and

logger = logger.With("foo", "bar")
logger.Error("oh noes!")

produce the same log output. The difference is, that in the second form, you can re-use the same logger for many logs, without repeating the common attribute:

func run(logger *slog.Logger) {
  logger = logger.With("key", "value")
  doFoo(logger)
  doBar(logger)
}

func doFoo(logger *slog.Logger) {
  /* ... */
  logger.Info("Did foo")
}

func doBar(logger *slog.Logger) {
  /* ... */
  logger.Info("Did bar")
}

This will log:

time=... level=INFO msg="Did foo" key=value
time=... level=INFO msg="Did bar" key=value

Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Get daily content like this in your inbox!

Subscribe