slog Records and levels

April 2, 2026

Yesterday we saw that slog uses handlers to process/record logs. But what exactly does it process? Records!

Overview

A log record consists of a time, a level, a message, and a set of key-value pairs, where the keys are strings and the values may be of any type. As an example,

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

creates a record containing the time of the call, a level of Info, the message “hello”, and a single pair with key “count” and value 3.

When you use the log/slog package, you’re basically building records by (usually) calling level-specific methods, passing a message, and potentially key/value/value pairs. This record is then what’s passed to the handler(s) you’ve configured. The handler(s) then typically format the record as plain text, as JSON, or to send to your cloud logging API.


Share this

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

Unsure? Browse the archive .

Related Content


Working with Records

In my experience, it’s rare you’ll need to worry about slog Records, unless you’re writing a Handler, or some kind of middleware/transform. But even if you never need to manipulate a Record directly, understanding the concept can be useful. Working with Records Sometimes a Handler will need to modify a Record before passing it on to another Handler or backend. A Record contains a mixture of simple public fields (e.g. Time, Level, Message) and hidden fields that refer to state (such as attributes) indirectly.


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 …

Get daily content like this in your inbox!

Subscribe