blob: 7351ca493b18f8877f22edc8ea4c8d29ceb4d876 [file] [log] [blame] [edit]
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package slog_test
import (
"context"
"log/slog"
"os"
)
// This example demonstrates using custom log levels and custom log level names.
// In addition to the default log levels, it introduces Trace, Notice, and
// Emergency levels. The ReplaceAttr changes the way levels are printed for both
// the standard log levels and the custom log levels.
func ExampleHandlerOptions_customLevels() {
// Exported constants from a custom logging package.
const (
LevelTrace = slog.Level(-8)
LevelDebug = slog.LevelDebug
LevelInfo = slog.LevelInfo
LevelNotice = slog.Level(2)
LevelWarning = slog.LevelWarn
LevelError = slog.LevelError
LevelEmergency = slog.Level(12)
)
th := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
// Set a custom level to show all log output. The default value is
// LevelInfo, which would drop Debug and Trace logs.
Level: LevelTrace,
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
// Remove time from the output for predictable test output.
if a.Key == slog.TimeKey {
return slog.Attr{}
}
// Customize the name of the level key and the output string, including
// custom level values.
if a.Key == slog.LevelKey {
// Rename the level key from "level" to "sev".
a.Key = "sev"
// Handle custom level values.
level := a.Value.Any().(slog.Level)
// This could also look up the name from a map or other structure, but
// this demonstrates using a switch statement to rename levels. For
// maximum performance, the string values should be constants, but this
// example uses the raw strings for readability.
switch {
case level < LevelDebug:
a.Value = slog.StringValue("TRACE")
case level < LevelInfo:
a.Value = slog.StringValue("DEBUG")
case level < LevelNotice:
a.Value = slog.StringValue("INFO")
case level < LevelWarning:
a.Value = slog.StringValue("NOTICE")
case level < LevelError:
a.Value = slog.StringValue("WARNING")
case level < LevelEmergency:
a.Value = slog.StringValue("ERROR")
default:
a.Value = slog.StringValue("EMERGENCY")
}
}
return a
},
})
logger := slog.New(th)
ctx := context.Background()
logger.Log(ctx, LevelEmergency, "missing pilots")
logger.Error("failed to start engines", "err", "missing fuel")
logger.Warn("falling back to default value")
logger.Log(ctx, LevelNotice, "all systems are running")
logger.Info("initiating launch")
logger.Debug("starting background job")
logger.Log(ctx, LevelTrace, "button clicked")
// Output:
// sev=EMERGENCY msg="missing pilots"
// sev=ERROR msg="failed to start engines" err="missing fuel"
// sev=WARNING msg="falling back to default value"
// sev=NOTICE msg="all systems are running"
// sev=INFO msg="initiating launch"
// sev=DEBUG msg="starting background job"
// sev=TRACE msg="button clicked"
}