slog.Logger în Go

Tipul jurnalului structurat: are metodele Debug, Info, Warn, Error, Log și creează loggeri derivați cu With.

Sintaxă
type Logger struct { /* câmpuri ascunse */ }

func (l *Logger) Debug(msg string, args ...any)
func (l *Logger) Info(msg string, args ...any)
func (l *Logger) Warn(msg string, args ...any)
func (l *Logger) Error(msg string, args ...any)
func (l *Logger) With(args ...any) *Logger
func (l *Logger) WithGroup(name string) *Logger

Ce face slog.Logger

Un *slog.Logger se creează cu slog.New(handler). Metodele lui corespund funcțiilor de pachet: Debug, Info, Warn, Error, plus variantele cu context (InfoContext, ErrorContext…) și Log/LogAttrs pentru un nivel oarecare.

Logger-ul este imutabil: With și WithGroup nu îl schimbă, ci returnează unul nou, cu atribute sau grup adăugate. Un logger poate fi folosit în siguranță din mai multe goroutine. Valoarea zero (slog.Logger{}) nu este utilizabilă: creează-l mereu cu slog.New.

Ce returnează

Nu se aplică (este un tip).

Exemple

Exemplul 1: Toate nivelurile pe un logger

package main

import (
    "context"
    "log/slog"
    "os"
)

func faraTimp(groups []string, a slog.Attr) slog.Attr {
    if a.Key == slog.TimeKey && len(groups) == 0 {
        return slog.Attr{} // un atribut gol nu este afișat
    }
    return a
}

func main() {
    opt := &slog.HandlerOptions{Level: slog.LevelDebug, ReplaceAttr: faraTimp}
    var logger *slog.Logger = slog.New(slog.NewTextHandler(os.Stdout, opt))

    logger.Debug("conectare la bază", "gazda", "localhost")
    logger.Info("utilizator autentificat", "id", 7)
    logger.Warn("parolă veche", "zile", 400)
    logger.Error("plată eșuată", "comanda", 1042)
    logger.Log(context.Background(), slog.LevelError+4, "disc plin, opresc scrierile")
}

Rezultat

level=DEBUG msg="conectare la bază" gazda=localhost
level=INFO msg="utilizator autentificat" id=7
level=WARN msg="parolă veche" zile=400
level=ERROR msg="plată eșuată" comanda=1042
level=ERROR+4 msg="disc plin, opresc scrierile"

Exemplul 2: Logger cu context comun

package main

import (
    "log/slog"
    "os"
)

func faraTimp(groups []string, a slog.Attr) slog.Attr {
    if a.Key == slog.TimeKey && len(groups) == 0 {
        return slog.Attr{} // un atribut gol nu este afișat
    }
    return a
}

func proceseaza(log *slog.Logger, comanda int) {
    log = log.With("comanda", comanda)
    log.Info("încep procesarea")
    log.Info("plată confirmată")
}

func main() {
    baza := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ReplaceAttr: faraTimp}))
    proceseaza(baza, 1042)
    proceseaza(baza, 1043)
}

Rezultat

level=INFO msg="încep procesarea" comanda=1042
level=INFO msg="plată confirmată" comanda=1042
level=INFO msg="încep procesarea" comanda=1043
level=INFO msg="plată confirmată" comanda=1043

Greșeli frecvente

  • Declari var logger slog.Logger (fără slog.New) și îl folosești: programul se oprește cu panică. Folosește *slog.Logger creat cu slog.New.

Comenzi înrudite

  • slog.New: Creează un *slog.Logger care trimite mesajele unui handler (text, JSON sau propriu).
  • slog.Logger.Info: Scrie un mesaj de nivel INFO prin acest logger, cu atributele lui (din With) și cele date în apel.
  • slog.Logger.With: Returnează un logger nou care adaugă automat atributele date la fiecare mesaj.
  • slog.Logger.WithGroup: Returnează un logger nou care pune toate atributele următoare într-un grup cu numele dat.
  • slog.Level: Tipul nivelului unui mesaj (DEBUG, INFO, WARN, ERROR); valorile mai mari înseamnă mesaje mai importante.