slog.Any în Go

Creează un atribut cu o valoare de orice tip: structuri, liste, map-uri, erori.

Sintaxă
func Any(key string, value any) Attr

Ce face slog.Any

slog.Any acceptă orice valoare. Pentru tipurile de bază alege singur forma potrivită (ca slog.Int, slog.String). Pentru restul, handler-ul text folosește formatarea fmt (%+v), iar handler-ul JSON folosește encoding/json.

Dacă tipul valorii are metoda LogValue() slog.Value (interfața slog.LogValuer), handler-ul folosește rezultatul ei. Așa poți ascunde parole sau poți scrie doar câmpurile importante ale unei structuri mari.

Parametri

Parametru Descriere
key Numele câmpului.
value Valoarea, de orice tip.

Ce returnează

Un slog.Attr.

Exemple

Exemplul 1: Structuri, liste și erori

package main

import (
    "errors"
    "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
}

type Produs struct {
    Nume string
    Pret float64
}

func main() {
    logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ReplaceAttr: faraTimp}))
    logger.Info("coș actualizat",
        slog.Any("produs", Produs{"Carte de bucate", 59.9}),
        slog.Any("etichete", []string{"reducere", "nou"}),
        slog.Any("err", errors.New("cupon expirat")))
}

Rezultat

level=INFO msg="coș actualizat" produs="{Nume:Carte de bucate Pret:59.9}" etichete="[reducere nou]" err="cupon expirat"

Exemplul 2: Ascunderea parolei cu LogValuer

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
}

type Cont struct {
    Email  string
    Parola string
}

// LogValue spune lui slog ce să afișeze în locul structurii.
func (c Cont) LogValue() slog.Value {
    return slog.GroupValue(slog.String("email", c.Email), slog.String("parola", "***"))
}

func main() {
    logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ReplaceAttr: faraTimp}))
    c := Cont{Email: "ana@exemplu.ro", Parola: "Secret!2025"}
    logger.Info("cont creat", slog.Any("cont", c))
}

Rezultat

{"level":"INFO","msg":"cont creat","cont":{"email":"ana@exemplu.ro","parola":"***"}}

Greșeli frecvente

  • Pui în jurnal structuri întregi cu date personale sau secrete. Ce ajunge în jurnal e greu de șters; folosește LogValuer sau alege câmpurile.

Comenzi înrudite

  • slog.String: Creează un atribut tipizat (text, întreg, boolean) pentru un mesaj slog, în locul perechii cheie, valoare.
  • slog.Group: Grupează mai multe atribute sub un nume comun: în text devin grup.cheie=…, în JSON un obiect.
  • slog.NewJSONHandler: Creează un handler care scrie fiecare mesaj ca un obiect JSON pe un rând, potrivit pentru servere și cloud.
  • slog.Error: Scrie în jurnalul implicit un mesaj de nivel ERROR, de obicei împreună cu eroarea primită.