Slog Structured Logging JSON

Adopt Go structured logging with slog: leveled JSON handlers, grouped attributes, log record routing, and child loggers with bound context.

GoResilience

Code

snippet
package main

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

type PaymentHandler struct {
	logger *slog.Logger
}

func (h *PaymentHandler) Settle(ctx context.Context, orderID string, amount int) error {
	logger := h.logger.With(
		slog.String("order_id", orderID),
		slog.Int("amount_cents", amount),
	)

	logger.InfoContext(ctx, "settlement started")

	if amount > 1_000_000 {
		logger.ErrorContext(ctx, "settlement rejected",
			slog.String("reason", "single-charge limit"),
			slog.Group("risk",
				slog.Int("score", 91),
				slog.String("band", "high"),
			),
		)
		return errAmountTooHigh
	}

	logger.InfoContext(ctx, "settlement completed")
	return nil
}

var errAmountTooHigh = errors.New("amount exceeds single-charge limit")

func main() {
	handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{})

	logger := slog.New(handler).With(
		slog.String("service", "billing"),
		slog.String("region", "cn-north"),
	)

	payments := &PaymentHandler{logger: logger}
	_ = payments.Settle(context.Background(), "ord-42", 250_000)
	_ = payments.Settle(context.Background(), "ord-43", 2_500_000)

	slog.SetDefault(logger)
	slog.Info("default logger now carries bound context")
}