Filtering logs by level

April 22, 2026

Levels

In an application, you may wish to log messages only at a certain level or greater. One common configuration is to log messages at Info or higher levels, suppressing debug logging until it is needed. The built-in handlers can be configured with the minimum level to output by setting [HandlerOptions.Level]. The program’s main function typically does this. The default value is LevelInfo.

Pretty straight forward, eh? Only want to log Info-and-above inproduction? Set the handler level to Info!

But what if you need to change to Debug level for a few minutes, without re-deploying the application? Enter the LevelVar! One of the more powerful features of the log/slog package that most people overlook.

Setting the [HandlerOptions.Level] field to a Level value fixes the handler’s minimum level throughout its lifetime. Setting it to a LevelVar allows the level to be varied dynamically. A LevelVar holds a Level and is safe to read or write from multiple goroutines. To vary the level dynamically for an entire program, first initialize a global LevelVar:

var programLevel = new(slog.LevelVar) // Info by default

Then use the LevelVar to construct a handler, and make it the default:

h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel})
slog.SetDefault(slog.New(h))

Now the program can change its logging level with a single statement:

programLevel.Set(slog.LevelDebug)

With this, you could set up a /log_level endpoint, or any other mechanism in your application, that would dynamically change the log level, so you can do your debug-level observations, then later switch back to Info level.


Share this

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

Unsure? Browse the archive .

Related Content


Log levels

I'm launching a new live course: **Idiomatic Testing in Go**. The course begins May 5. Early-bird pricing is in effect until April 28. Why Go avoids assert libraries Better alternatives to mocks Make writing tests fun! See pricing & reserve → log/slog provides some rather sophisticated capabilities around log levels. We’ll get into it, but the good news is, you don’t need to care about how sophisticated it can get, if you don’t care.


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.


Intro to slog levels

By default, the log/slog package supports four log levels: Debug, Info, Warn, and Error, each of which has matching logger methods: Overview … The Info top-level function calls the Logger.Info method on the default Logger. In addition to Logger.Info, there are methods for Debug, Warn and Error levels. Besides these convenience methods for common levels, there is also a Logger.Log method which takes the level as an argument. Each of these methods has a corresponding top-level function that uses the default logger.

Get daily content like this in your inbox!

Subscribe