slog.NewJSONHandler în Go

Creează un handler care scrie fiecare mesaj ca un obiect JSON pe un rând, potrivit pentru servere și cloud.

Sintaxă
func NewJSONHandler(w io.Writer, opts *HandlerOptions) *JSONHandler

Ce face slog.NewJSONHandler

slog.NewJSONHandler scrie câte un obiect JSON pe rând (formatul „JSON Lines”): {"time":"...","level":"INFO","msg":"...","cheie":valoare}. Serviciile de jurnale (Elasticsearch, Datadog, Google Cloud Logging) îl citesc direct.

Valorile sunt codate cu encoding/json: numerele rămân numere, structurile devin obiecte, slice-urile devin liste, erorile devin textul lor. Atenție: duratele (time.Duration) apar ca număr de nanosecunde.

Parametri

Parametru Descriere
w Destinația.
opts Opțiunile sau nil.

Ce returnează

Un *slog.JSONHandler.

Exemple

Exemplul 1: Valori de tipuri diferite

package main

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

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 Adresa struct {
    Oras  string `json:"oras"`
    Strada string `json:"strada"`
}

func main() {
    logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ReplaceAttr: faraTimp}))
    logger.Info("comandă livrată",
        "id", 1042,
        "platit", true,
        "produse", []string{"carte", "pix"},
        "adresa", Adresa{"Iași", "Lăpușneanu 12"},
        "durata", 1500*time.Millisecond)
}

Rezultat

{"level":"INFO","msg":"comandă livrată","id":1042,"platit":true,"produse":["carte","pix"],"adresa":{"oras":"Iași","strada":"Lăpușneanu 12"},"durata":1500000000}

Exemplul 2: Citirea înapoi a jurnalului

Fiecare rând este JSON valid, deci îl poți decoda cu json.Unmarshal.

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "log/slog"
)

func main() {
    var buf bytes.Buffer
    logger := slog.New(slog.NewJSONHandler(&buf, nil))
    logger.Warn("spațiu pe disc redus", "liber_gb", 3)

    var rand map[string]any
    if err := json.Unmarshal(buf.Bytes(), &rand); err != nil {
        fmt.Println("eroare:", err)
        return
    }
    fmt.Println("nivel:", rand["level"])
    fmt.Println("mesaj:", rand["msg"])
    fmt.Println("liber_gb:", rand["liber_gb"])
    _, areTimp := rand["time"]
    fmt.Println("are câmpul time:", areTimp)
}

Rezultat

nivel: WARN
mesaj: spațiu pe disc redus
liber_gb: 3
are câmpul time: true

Greșeli frecvente

  • Te aștepți ca durata să apară ca „1.5s” în JSON. Apare ca 1500000000 (nanosecunde); dacă vrei text, folosește slog.String("durata", d.String()).
  • Pui în jurnal structuri cu parole sau tokenuri: JSON-ul le scrie pe toate. Ascunde-le cu json:"-" sau cu un slog.LogValuer.

Comenzi înrudite

  • slog.NewTextHandler: Creează un handler care scrie fiecare mesaj ca un rând de perechi cheie=valoare (format logfmt).
  • slog.Any: Creează un atribut cu o valoare de orice tip: structuri, liste, map-uri, erori.
  • slog.HandlerOptions: Opțiunile handler-elor text și JSON: nivelul minim, adăugarea fișierului sursă și modificarea oricărui atribut.