golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/slog/example_custom_levels_test.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package slog_test 6 7 import ( 8 "os" 9 10 "golang.org/x/exp/slog" 11 ) 12 13 // This example demonstrates using custom log levels and custom log level names. 14 // In addition to the default log levels, it introduces Trace, Notice, and 15 // Emergency levels. The ReplaceAttr changes the way levels are printed for both 16 // the standard log levels and the custom log levels. 17 func ExampleHandlerOptions_customLevels() { 18 // Exported constants from a custom logging package. 19 const ( 20 LevelTrace = slog.Level(-8) 21 LevelDebug = slog.LevelDebug 22 LevelInfo = slog.LevelInfo 23 LevelNotice = slog.Level(2) 24 LevelWarning = slog.LevelWarn 25 LevelError = slog.LevelError 26 LevelEmergency = slog.Level(12) 27 ) 28 29 th := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ 30 // Set a custom level to show all log output. The default value is 31 // LevelInfo, which would drop Debug and Trace logs. 32 Level: LevelTrace, 33 34 ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr { 35 // Remove time from the output for predictable test output. 36 if a.Key == slog.TimeKey { 37 return slog.Attr{} 38 } 39 40 // Customize the name of the level key and the output string, including 41 // custom level values. 42 if a.Key == slog.LevelKey { 43 // Rename the level key from "level" to "sev". 44 a.Key = "sev" 45 46 // Handle custom level values. 47 level := a.Value.Any().(slog.Level) 48 49 // This could also look up the name from a map or other structure, but 50 // this demonstrates using a switch statement to rename levels. For 51 // maximum performance, the string values should be constants, but this 52 // example uses the raw strings for readability. 53 switch { 54 case level < LevelDebug: 55 a.Value = slog.StringValue("TRACE") 56 case level < LevelInfo: 57 a.Value = slog.StringValue("DEBUG") 58 case level < LevelNotice: 59 a.Value = slog.StringValue("INFO") 60 case level < LevelWarning: 61 a.Value = slog.StringValue("NOTICE") 62 case level < LevelError: 63 a.Value = slog.StringValue("WARNING") 64 case level < LevelEmergency: 65 a.Value = slog.StringValue("ERROR") 66 default: 67 a.Value = slog.StringValue("EMERGENCY") 68 } 69 } 70 71 return a 72 }, 73 }) 74 75 logger := slog.New(th) 76 logger.Log(nil, LevelEmergency, "missing pilots") 77 logger.Error("failed to start engines", "err", "missing fuel") 78 logger.Warn("falling back to default value") 79 logger.Log(nil, LevelNotice, "all systems are running") 80 logger.Info("initiating launch") 81 logger.Debug("starting background job") 82 logger.Log(nil, LevelTrace, "button clicked") 83 84 // Output: 85 // sev=EMERGENCY msg="missing pilots" 86 // sev=ERROR msg="failed to start engines" err="missing fuel" 87 // sev=WARNING msg="falling back to default value" 88 // sev=NOTICE msg="all systems are running" 89 // sev=INFO msg="initiating launch" 90 // sev=DEBUG msg="starting background job" 91 // sev=TRACE msg="button clicked" 92 }