Protokollebene von Go lang slog zur Laufzeit ändern

王林
Freigeben: 2024-02-09 10:18:08
nach vorne
387 Leute haben es durchsucht

在运行时更改 Go lang slog 的日志级别

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.

Frageninhalt

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.

Update 1 – App mit 3 Loggern ausführen und Ebenen über HTTP ändern

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)
}
Nach dem Login kopieren

Update 2 – Einfaches Beispiel

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")

}
Nach dem Login kopieren

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"
Nach dem Login kopieren

Solution

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

    // ...
}
Nach dem Login kopieren

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)
Nach dem Login kopieren

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()
}
Nach dem Login kopieren

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!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!