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