slog-multi
Compose Go's log/slog handlers into fanout, routing, failover, and load-balancing pipelines.
Repository Health
Technical Analysis
slog-multi extends Go’s standard library log/slog package with composable handler patterns for building sophisticated logging pipelines. Instead of writing custom slog.Handler wrappers by hand, it provides ready-made primitives — Fanout, Router, FirstMatch, Failover, Pool, and Pipe — that combine and transform any number of underlying handlers.
Each primitive addresses a distinct production logging need: broadcasting a record to every configured destination, conditionally routing records by level, message, or attribute, failing over to a backup sink when the primary is unavailable, distributing load across a pool of handlers, or building middleware chains that transform records before they reach a final handler. Because every construct fully implements the slog.Handler interface, they compose transparently with any other slog-based handler, including samber’s own family of slog-* adapters for Zap, Datadog, Sentry, Slack, and dozens of other sinks.
What You Get
- Fanout() distributes every log record to multiple slog.Handler instances in parallel, cloning the record so handlers can’t interfere with one another.
- Router() and its FirstMatch() variant conditionally dispatch records to handlers based on predicates over level, message, or attributes.
- Failover() tries handlers in priority order and falls through to the next one whenever the current handler errors.
- Pool() load-balances records across a set of handlers using randomized round robin.
- Pipe() builds ordered middleware chains that transform, filter, or recover from errors in records before they reach a final handler.
Common Use Cases
- Sending the same structured log to stdout for local debugging and to a remote sink like Datadog or Loki simultaneously via Fanout.
- Routing error-level logs to a Slack or paging handler while sending info-level logs to a plain console handler via Router.
- Keeping logging resilient in production by failing over from a primary log shipper to a local file handler when the network sink is unreachable.
- Spreading high-volume log traffic across several handler instances to avoid a single bottleneck, using Pool.
- Wrapping any handler with RecoverHandlerError so a panic or error in one logging sink never crashes the calling application.
Under The Hood
Architecture slog-multi is organized as a flat, single-package library where each composition pattern lives in its own file — Fanout in multi.go, conditional routing in router.go and firstmatch.go, high-availability failover in failover.go, load balancing in pool.go, middleware chaining in pipe.go, and panic/error recovery in recover.go — and every construct fully implements the standard library’s slog.Handler interface (Enabled/Handle/WithAttrs/WithGroup), so any of them can wrap or be wrapped by any other slog.Handler, including deeply nested combinations. State is treated immutably: WithAttrs and WithGroup always return new handler instances rather than mutating in place, matching log/slog’s own contract, and every Handle call clones the record before dispatching to child handlers so one handler’s side effects can never leak into another’s view of the record. A small shared try() helper centralizes panic recovery across every handler type, giving the whole library a uniform failure-handling seam. Because the core abstraction is the stable, external slog.Handler interface rather than a private one, the design is resilient to change even though renaming that interface would ripple through every file.
Tech Stack The library is pure Go, built directly on the standard library’s log/slog package with only a couple of runtime dependencies — samber/lo for functional slice operations and samber/slog-common for attribute/group manipulation helpers shared across samber’s broader family of slog-* handler adapters — plus test-only dependencies for assertions and goroutine-leak detection. There is no web framework, ORM, or database involved; this is a zero-infrastructure extension of the standard library. Continuous integration runs golangci-lint and a security scanner on every push and pull request, and a manual release workflow strips test files and tidies the module before tagging a release.
Code Quality Testing combines the standard library’s testing package with fuzz tests and stress tests that use goroutine-leak detection, a notably rigorous combination for a library of this size, though coverage leans toward the core Fanout and recovery paths rather than every handler type having its own dedicated test file. Error handling is idiomatic — explicit error returns, errors.Join to combine fanout failures, and panics captured through the shared try() helper rather than left to crash the caller. Naming is consistent throughout, and exported types and functions carry extensive, example-laden godoc comments, which is unusually thorough documentation for a project this size. golangci-lint is enforced in CI on every change.
API Design The public API favors small, composable constructors and fluent builders over configuration structs — slog.New(slogmulti.Fanout(h1, h2)) or slogmulti.Router().Add(handler, predicate).Handler() read naturally, and Fanout/Router calls auto-flatten nested compositions so callers never have to pre-flatten handler lists themselves. Predicates are plain functions over context and record, with a comprehensive set of ready-made ones (level, message, and attribute matchers) covering common routing needs without forcing boilerplate matcher code. Because every construct returns a standard slog.Handler, there is no new interface to learn beyond the one the standard library already defines, though some interactions — like how FirstMatch composes with WithGroup — require reading the doc comments closely to use correctly.
Used by 4 apps in this directory
Authgear
Authentication
Open-source, self-hostable authentication platform with passkeys, biometric login, SSO, MFA, and GraphQL admin API — a full Auth0/Clerk/Firebase alternative for SaaS and mobile apps.
OpenMeter
Invoicing Finance · Developer Tools
Open-source metering and billing engine for AI, agentic, and DevTool monetization — ingest usage events in real time and turn them into accurate invoices automatically.
Wakapi
Developer Tools · Analytics
Self-hosted WakaTime-compatible coding statistics backend that gives developers full control over their coding activity data.
ZITADEL
Authentication
Open-source, API-first identity platform delivering multi-tenancy, Passkeys, OIDC, SAML, and SCIM without vendor lock-in.