Groups

April 28, 2026

Early bird registration for [**Idiomatic Testing in Go**](/idiomatic-testing/) ends today!

Not sure how to adapt your xUnit habits to Go? This is the course for you!

Sign up today to save 25% over the full price.

Sometimes you want to group several key/value attributes together when logging. Maybe different aspects of an error (error_code, error_detail, stacktrace, etc), or different aspects of an HTTP response (bytes_sent, status_code, etc). The log/slog package gives us this!

Groups

Attributes can be collected into groups. A group has a name that is used to qualify the names of its attributes. How this qualification is displayed depends on the handler. TextHandler separates the group and attribute names with a dot. JSONHandler treats each group as a separate JSON object, with the group name as the key.

Use Group to create a Group attribute from a name and a list of key-value pairs:

slog.Group("request",
    "method", r.Method,
    "url", r.URL)

TextHandler would display this group as

request.method=GET request.url=http://example.com

JSONHandler would display it as

"request":{"method":"GET","url":"http://example.com"}

Share this

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

Unsure? Browse the archive .

Related Content


Concurrent logging

One last note in the performance section… How does logging work in a concurrent system? Performance considerations … The built-in handlers acquire a lock before calling io.Writer.Write to ensure that exactly one Record is written at a time in its entirety. Although each log record has a timestamp, the built-in handlers do not use that time to sort the written records. User-defined handlers are responsible for their own locking and sorting.


Back after an unannounced absence

Hey everyone… I dropped the ball! A combination of unexpected family events, prepping for a conference, and some travel, meant I haven’t been writing for much longer than I like. But I’m back! So where were we? Oh that’s right… performance considerations with log/slog. We had looked at using the fmt.Stringer interface to avoid eager processing with slog.TextHandler. But let’s now look at a more general solution: Performance considerations …


Lazy attribute evaluation for JSONHandler

As I was writing yesterday’s post, a portion of the GoDoc confused me. I’ve now spent over 3 hours with Claude trying to parse the prose grammatically, build test cases, and make general sense of it. I think I finally have… Here’s hoping! So, yesterday we saw how you can lazy-evaluate some values when using TextHandler. But the proposed solution (pass a fmt.Stringer rather than a literal string) has other, likely uninintended, consequences if you’re using JSONHandler:

Get daily content like this in your inbox!

Subscribe