Chosing an slog handler

April 10, 2026

log/slog ships with two default handlers: the TextHandler and the JSONHandler.

Overview

For more control over the output format, create a logger with a different handler. This statement uses New to create a new logger with a TextHandler that writes structured records in text form to standard error:

logger := slog.New(slog.NewTextHandler(os.Stderr, nil))

TextHandler output is a sequence of key=value pairs, easily and unambiguously parsed by machine. This statement:

logger.Info("hello", "count", 3)

produces this output:

time=2022-11-08T15:28:26.000-05:00 level=INFO msg=hello count=3

The package also provides JSONHandler, whose output is line-delimited JSON:

logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("hello", "count", 3)

produces this output:

{"time":"2022-11-08T15:28:26.000000000-05:00","level":"INFO","msg":"hello","count":3}

(There’s actually a third, the MultiHandler, that fans out logs to multiple handlers). You can also use a custom handler you’ve built, or one of many third-party library handlers out there in the wild…


Share this

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

Unsure? Browse the archive .

Related Content


slog.Group

The one Attr constructor not yet covered: func Group func Group(key string, args ...any) Attr Group returns an Attr for a Group Value. The first argument is the key; the remaining arguments are converted to Attrs as in Logger.Log. Use Group to collect several key-value pairs under a single key on a log line, or as the result of LogValue in order to log a single value as multiple Attrs.


Handler configuration

The default slog handlers are quite configurable. Overview … Both TextHandler and JSONHandler can be configured with HandlerOptions. There are options for setting the minimum level (see Levels, below), displaying the source file and line of the log call, and modifying attributes before they are logged. While HandlerOptions only exposes three fields: AddSource bool Level Leveler ReplaceAttr func(groups []string, a Attr) Attr The last one provides an immense amount of flexibility, letting you filter, replace, or augment log key/value pairs as they are processed.


slog.HandlerOptions

Now we’ll begin looking at HandlerOptions. Despite the Handler-centricity, this is something we care heavily about as mere users of the slog library. Whenever you instantiate either slog.JSONHandler or slog.TextHandler, you have the option of providing a HandlerOptions object, to tweak the default handler behavior. We’ll look at each of the config options, one at a time. type HandlerOptions type HandlerOptions struct { // AddSource causes the handler to compute the source code position // of the log statement and add a SourceKey attribute to the output.

Get daily content like this in your inbox!

Subscribe