slogbox
- title
- slogbox
- type
- toolbox
- summary
- slog.Handler keeping the last N records in a ring buffer, auto-dumped when an error arrives
- tags
- golang, logging, slog, observability
- language
- Go
- license
- GPL-3.0
- created
- 2026-04-06
- updated
- 2026-04-06
A slog.Handler that keeps the last N log records in a fixed-size circular buffer. Zero external dependencies โ just the Go standard library.
Two main use cases:
-
Debug endpoint โ expose recent logs via an HTTP handler at
/debug/logs. Useful for health checks or admin panels where you want to see what happened recently without digging through log aggregation. -
Black box recorder โ inspired by
runtime/trace.FlightRecorder. Buffer quietly collects logs, and when an error-level record arrives, it auto-flushes the entire buffer (including the context leading up to the error) to a destination handler. You get the "what happened before the crash" context for free.
Basic usage:
rec := slogbox.New(500, nil)
logger := slog.New(rec)
slog.SetDefault(logger)
// expose at /debug/logs
http.Handle("GET /debug/logs", slogbox.HTTPHandler(rec, nil))
Black box pattern:
rec := slogbox.New(500, &slogbox.Options{
FlushOn: slog.LevelError, // trigger on errors
FlushTo: slog.NewJSONHandler(os.Stderr, nil), // dump context here
MaxAge: 5 * time.Minute, // only recent records
})
logger := slog.New(rec)
logger.Info("request started", "path", "/api/users")
logger.Info("db query", "rows", 42)
logger.Error("query failed", "err", err) // flushes all buffered context
Performance: 150 ns/op and 1 alloc per Handle call. With GOEXPERIMENT=jsonv2, WriteTo uses streaming JSON โ 4x less memory, 54x fewer allocs at 100 records, scaling to 27x faster at 10K records.
Config options: Level (min level to store), FlushOn (level that triggers flush), FlushTo (destination handler), MaxAge (exclude stale records from reads).
Repo: https://github.com/alexrios/slogbox โ 19 stars, GPL-3.0 license.