php-Editor Strawberry ist hier, um Ihnen eine Methode vorzustellen, mit der Sie die Protokollebene von Go lang slog zur Laufzeit ändern können. Go lang slog ist eine häufig verwendete Protokollierungsbibliothek. Während der Entwicklung müssen wir jedoch möglicherweise die Protokollebene ändern, ohne die Anwendung neu zu starten. In diesem Artikel wird eine einfache und effektive Methode vorgestellt, mit der Sie die Protokollebene zur Laufzeit problemlos ändern können, um unterschiedlichen Anforderungen gerecht zu werden. Egal, ob Sie Anfänger oder erfahrener Entwickler sind, dieser Tipp wird Ihnen bei Ihren Projekten helfen.
Mit dem Go-Slog-Protokollierungspaket ("log/slog"
) suche ich nach einer Möglichkeit, die Logger-Protokollebene zur Laufzeit zu ändern?
Ist es möglich? Ich habe Stunden damit verbracht, damit zu spielen, finde aber keine Möglichkeit, dies zu tun.
Unten ist der Code, den ich basierend auf Peters Antwort geschrieben habe.
Ich mache HTTP-Anrufe
http://localhost:8080/changeLogLevel?logger=TCP&level=ERROR
.
package main import ( "log" "log/slog" "net/http" "os" "strings" "time" ) func main() { // Create a LevelVar variable and initialize it to DEBUG. // Create the template logger with info tcpLvl := new(slog.LevelVar) tcpLvl.Set(slog.LevelDebug) dbLvl := new(slog.LevelVar) dbLvl.Set(slog.LevelDebug) mqLvl := new(slog.LevelVar) mqLvl.Set(slog.LevelDebug) tcpLogger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ Level: tcpLvl, })) mqLogger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ Level: mqLvl, })) // Create the MQLogger. dbLogger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ Level: dbLvl, })) // Create a goroutine that prints debug messages to the 3 loggers. go func() { levels := map[string]slog.Level{ "DEBUG": slog.LevelDebug, "WARN": slog.LevelWarn, "INFO": slog.LevelInfo, "ERROR": slog.LevelError, } for { for levelStr, numericLevel := range levels { log.Printf("Is: %s enabled for tcpLogger? %v \n", levelStr, tcpLogger.Enabled(nil, numericLevel)) } dbLogger.Debug("This is a debug message from the DBLogger.") tcpLogger.Debug("This is a debug message from the TCPLogger.") mqLogger.Debug("This is a debug message from the MQLogger.") log.Println("----------------------------------------------------") time.Sleep(10 * time.Second) } }() // Create an HTTP server. http.HandleFunc("/changeLogLevel", func(w http.ResponseWriter, r *http.Request) { // Get the logger name from the request. log.Println("----- Got HTTP call -------") loggerName := r.URL.Query().Get("logger") // Get the new log level from the request. newLogLevelStr := r.URL.Query().Get("level") var level slog.Level log.Printf("Incoming log level is %v\n", newLogLevelStr) switch strings.ToUpper(newLogLevelStr) { case "DEBUG": level = slog.LevelDebug case "WARNING": level = slog.LevelWarn case "ERROR": level = slog.LevelError case "INFO": level = slog.LevelInfo default: { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Invalid level name")) return } } log.Printf("Incoming logger name is %v\n", loggerName) switch strings.ToUpper(loggerName) { case "DB": dbLvl.Set(level) case "TCP": log.Printf("Going to set the TCP logger level to %v\n", level) tcpLvl.Set(level) case "MQ": mqLvl.Set(level) default: w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Invalid logger name")) return } w.WriteHeader(http.StatusOK) }) // Start the HTTP server. http.ListenAndServe(":8080", nil) }
Der folgende Code funktioniert wie erwartet.
package main import ( "log" "log/slog" "os" ) func main() { log.Println("slog chaqnge level demo") lvl := new(slog.LevelVar) lvl.Set(slog.LevelInfo) logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ Level: lvl, })) logger.Info("Info msg") logger.Debug("Debug msg - you will NOT see me") lvl.Set(slog.LevelDebug) logger.Debug("Debug msg - you will see me") }
Ausgabe
2009/11/10 23:00:00 slog chaqnge level demo time=2009-11-10T23:00:00.000Z level=INFO msg="Info msg" time=2009-11-10T23:00:00.000Z level=DEBUG msg="Debug msg - you will see me"
Die Konstruktoren integrierter Handler verwenden alle den HandlerOptions-Parameter. HandlerOptions verfügt über ein Level-Feld, mit dem Sie die Ebene dynamisch ändern können.
type HandlerOptions struct { // Level reports the minimum record level that will be logged. // The handler discards records with lower levels. // If Level is nil, the handler assumes LevelInfo. // The handler calls Level.Level for each record processed; // to adjust the minimum level dynamically, use a LevelVar. Level Leveler // ... }
Legen Sie also beim Erstellen des Loggers einfach eine LevelVar fest:
lvl := new(slog.LevelVar) lvl.Set(slog.LevelInfo) logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ Level: lvl, })) // later ... lvl.Set(slog.LevelDebug)
Wenn Sie Ihren eigenen Handler implementieren, bestimmt die Enabled-Methode die Protokollebene. Sie können auch problemlos LevelVar verwenden:
type MyHandler struct { level slog.Leveler } func (h *MyHandler) Enabled(_ context.Context, level slog.Level) bool { return level >= h.level.Level() }
Das obige ist der detaillierte Inhalt vonProtokollebene von Go lang slog zur Laufzeit ändern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!