// 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" }