How to work with the proposed structured logging Package for the Golang Standard Library

Logging via the slog package

For a while now, I’ve been keeping a close eye on the structure logging proposal making its way through Go’s language proposal process. Last month an experimental version of the proposal was released under the golang.org/x/exp package (see documentation here) and I decided to experiment with it and decided to summarise my learnings in a blog for others to learn more about this proposed addition to the Go standard library.

What is the Structured Logging Proposal?

From a high level (see the proposal itself for a more in-depth look) the proposal aims to address the current gap that exists in Go’s standard library by adding structured logging with levels, residing in a new package with the import path log/slog.

First, what is Structured Logging?

Logs have traditionally been aimed at being human readable. These days it’s common to want to index them to enable better filtering and searching. This can be performed by formatting the log output in a way that makes them machine-readable. This process is called structured logging.

For example, if you’ve used Go’s existing log package then the following code would output a log that looks like the output below:

log.Printf("processed %d items in %s", 23, time.Since(time.Now()))
// Not structured, boo :(
2022/11/10 02:53:02 processed 23 items in 83ns

Its lack of structure makes parsing the output difficult and potentially costly. A better, structured alternative would be the following which adds keys and associated values to the output making parsing it programmatically far easier and more reliable.

// Structured!
time=2022/11/10 02:53:02 msg="processed item" size=23 duration=83ns level=info

Now the logs have a structure associated with them, it’s much easier to encode them as other data formats such as JSON:

{"time":"2022-11-13T03:38:37.737821Z","level":"INFO","msg":"processed items","size":23,"duration":83}

Providing a general interface for logging in Golang

A wide variety of structured logging packages exist within the Golang ecosystem (LogrusZap and Zerolog to name a few), however this diverse API landscape can make supporting logging in a provider agnostic way challenging, often requiring abstractions to avoid coupling your implementation to any given logging package. This proposal would help alleviate this pain by providing a common interface in the standard library that service owners of package authors alike could depend on.

That’s enough talk for now, let’s take a look at the proposed package in a bit more depth.

Logging via the slog package

A Bare Bones Example