golang-samber-slog

Structured logging extensions for Golang using samber/slog-**** packages — multi-handler pipelines (slog-multi), log sampling (slog-sampling), attribute…

INSTALLATION
npx skills add https://github.com/samber/cc-skills-golang --skill golang-samber-slog
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$27

record → [Sampling] → [Pipe: trace/PII] → [Router] → [Sinks]

Order matters: sampling before formatting saves CPU. Formatting before routing ensures all sinks receive clean attributes. Reversing this wastes work on records that get dropped.

Core Libraries

Library

Purpose

Key constructors

slog-multi

Handler composition

Fanout, Router, FirstMatch, Failover, Pool, Pipe

slog-sampling

Throughput control

UniformSamplingOption, ThresholdSamplingOption, AbsoluteSamplingOption, CustomSamplingOption

slog-formatter

Attribute transforms

PIIFormatter, ErrorFormatter, FormatByType[T], FormatByKey, FlattenFormatterMiddleware

slog-multi — Handler Composition

Six composition patterns, each for a different routing need:

Pattern

Behavior

Latency impact

Fanout(handlers...)

Broadcast to all handlers sequentially

Sum of all handler latencies

Router().Add(h, predicate).Handler()

Route to ALL matching handlers

Sum of matching handlers

Router().Add(...).FirstMatch().Handler()

Route to FIRST match only

Single handler latency

Failover()(handlers...)

Try sequentially until one succeeds

Primary handler latency (happy path)

Pool()(handlers...)

Load-balance: sends each record to ONE handler

Single handler latency

Pipe(middlewares...).Handler(sink)

Middleware chain before sink

Middleware overhead + sink

// Route errors to Sentry, all logs to stdout

logger := slog.New(

    slogmulti.Router().

        Add(sentryHandler, slogmulti.LevelIs(slog.LevelError)).

        Add(slog.NewJSONHandler(os.Stdout, nil)).

        Handler(),

)

Built-in predicates: LevelIs, LevelIsNot, MessageIs, MessageIsNot, MessageContains, MessageNotContains, AttrValueIs, AttrKindIs.

For full code examples of every pattern, see Pipeline Patterns.

slog-sampling — Throughput Control

Strategy

Behavior

Best for

Uniform

Drop fixed % of all records

Dev/staging noise reduction

Threshold

Log first N per interval, then sample at rate R

Production — preserves initial visibility

Absolute

Cap at N records per interval globally

Hard cost control

Custom

User function returns sample rate per record

Level-aware or time-aware rules

Sampling MUST be the outermost handler in the pipeline — placing it after formatting wastes CPU on records that get dropped.

// Threshold: log first 10 per 5s, then 10% — errors always pass through via Router

logger := slog.New(

    slogmulti.

        Pipe(slogsampling.ThresholdSamplingOption{

            Tick: 5 * time.Second, Threshold: 10, Rate: 0.1,

        }.NewMiddleware()).

        Handler(innerHandler),

)

Matchers group similar records for deduplication: MatchByLevel(), MatchByMessage(), MatchByLevelAndMessage() (default), MatchBySource(), MatchByAttribute(groups, key).

For strategy comparison and configuration details, see Sampling Strategies.

slog-formatter — Attribute Transformation

Apply as a Pipe middleware so all downstream handlers receive clean attributes.

logger := slog.New(

    slogmulti.Pipe(slogformatter.NewFormatterMiddleware(

        slogformatter.PIIFormatter("user"),          // mask PII fields

        slogformatter.ErrorFormatter("error"),       // structured error info

        slogformatter.IPAddressFormatter("client"),  // mask IP addresses

    )).Handler(slog.NewJSONHandler(os.Stdout, nil)),

)

Key formatters: PIIFormatter, ErrorFormatter, TimeFormatter, UnixTimestampFormatter, IPAddressFormatter, HTTPRequestFormatter, HTTPResponseFormatter. Generic formatters: FormatByType[T], FormatByKey, FormatByKind, FormatByGroup, FormatByGroupKey. Flatten nested attributes with FlattenFormatterMiddleware.

HTTP Middlewares

Consistent pattern across frameworks: router.Use(slogXXX.New(logger)).

Available: slog-gin, slog-echo, slog-fiber, slog-chi, slog-http (net/http).

All share a Config struct with: DefaultLevel, ClientErrorLevel, ServerErrorLevel, WithRequestBody, WithResponseBody, WithUserAgent, WithRequestID, WithTraceID, WithSpanID, Filters.

// Gin with filters — skip health checks

router.Use(sloggin.NewWithConfig(logger, sloggin.Config{

    DefaultLevel:     slog.LevelInfo,

    ClientErrorLevel: slog.LevelWarn,

    ServerErrorLevel: slog.LevelError,

    WithRequestBody:  true,

    Filters: []sloggin.Filter{

        sloggin.IgnorePath("/health", "/metrics"),

    },

}))

For framework-specific setup, see HTTP Middlewares.

Backend Sinks

All follow the Option{}.NewXxxHandler() constructor pattern.

Category

Packages

Cloud

slog-datadog, slog-sentry, slog-loki, slog-graylog

Messaging

slog-kafka, slog-fluentd, slog-logstash, slog-nats

Notification

slog-slack, slog-telegram, slog-webhook

Storage

slog-parquet

Bridges

slog-zap, slog-zerolog, slog-logrus

Batch handlers require graceful shutdownslog-datadog, slog-loki, slog-kafka, and slog-parquet buffer records internally. Flush on shutdown (e.g., handler.Stop(ctx) for Datadog, lokiClient.Stop() for Loki, writer.Close() for Kafka) or buffered logs are lost.

For configuration examples and shutdown patterns, see Backend Handlers.

Common Mistakes

Mistake

Why it fails

Fix

Sampling after formatting

Wastes CPU formatting records that get dropped

Place sampling as outermost handler

Fanout to many synchronous handlers

Blocks caller — latency is sum of all handlers

Use Pool() for concurrent dispatch

Missing shutdown flush on batch handlers

Buffered logs lost on shutdown

defer handler.Stop(ctx) (Datadog), defer lokiClient.Stop() (Loki), defer writer.Close() (Kafka)

Router without default/catch-all handler

Unmatched records silently dropped

Add a handler with no predicate as catch-all

AttrFromContext without HTTP middleware

Context has no request attributes to extract

Install slog-gin/echo/fiber/chi middleware first

Using Pipe with no middleware

No-op wrapper adding per-record overhead

Remove Pipe() if no middleware needed

Performance Warnings

  • Fanout latency = sum of all handler latencies (sequential). With 5 handlers at 10ms each, every log call costs 50ms. Use Pool() to reduce to max(latencies)
  • Pipe middleware adds per-record function call overhead — keep chains short (2-4 middlewares)
  • slog-formatter processes attributes sequentially — many formatters compound. For hot-path attribute formatting, prefer implementing slog.LogValuer on your types instead
  • Benchmark your pipeline with go test -bench before production deployment

Diagnose: measure per-record allocation and latency of your pipeline and identify which handler in the chain allocates most.

Best Practices

  • Sample first, format second, route last — this canonical ordering minimizes wasted work and ensures all sinks see clean data
  • Use Pipe for cross-cutting concerns — trace ID injection and PII scrubbing belong in middleware, not per-handler logic
  • **Test pipelines with slogmulti.NewHandleInlineHandler** — assert on records reaching each stage without real sinks
  • **Use AttrFromContext** to propagate request-scoped attributes from HTTP middleware to all handlers
  • Prefer Router over Fanout when handlers need different record subsets — Router evaluates predicates and skips non-matching handlers

Cross-References

  • → See samber/cc-skills-golang@golang-observability skill for slog fundamentals (levels, context, handler setup, migration)
  • → See samber/cc-skills-golang@golang-error-handling skill for the log-or-return rule
  • → See samber/cc-skills-golang@golang-security skill for PII handling in logs
  • → See samber/cc-skills-golang@golang-samber-oops skill for structured error context with samber/oops

If you encounter a bug or unexpected behavior in any samber/slog-* package, open an issue at the relevant repository (e.g., slog-multi/issues, slog-sampling/issues).

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card