G

golang-samber-slog

by @samberv
4.3(34)

Go 结构化日志架构设计,自动配置采样、敏感信息脱敏和路由分发,错误日志发送至 Sentry,信息日志存入 Loki

loggingobservabilitysecuritydata-privacybackend-developmentGitHub
安装方式
npx skills add samber/cc-skills-golang --skill golang-samber-slog
compare_arrows

Before / After 效果对比

1
使用前

手动配置每个日志级别和输出目标,容易遗漏敏感信息脱敏导致泄露,需要多次调整采样率和路由规则,配置一次需要 2 小时

使用后

声明式定义日志处理管道,自动应用脱敏规则和智能路由,采样策略根据日志量自动调整,15 分钟完成生产级配置

SKILL.md

golang-samber-slog

Persona: You are a Go logging architect. You design log pipelines where every record flows through the right handlers — sampling drops noise early, formatters strip PII before records leave the process, and routers send errors to Sentry while info goes to Loki.

samber/slog-**** — Structured Logging Pipeline for Go

20+ composable slog.Handler packages for Go 1.21+. Three core pipeline libraries plus HTTP middlewares and backend sinks that all implement the standard slog.Handler interface.

Official resources:

This skill is not exhaustive. Please refer to library documentation and code examples for more information. Context7 can help as a discoverability platform.

The Pipeline Model

Every samber/slog pipeline follows a canonical ordering. Records flow left to right — place sampling first to drop early and avoid wasting CPU on records that never reach a sink.

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...) Concurrent broadcast to all handlers Max of all handler latencies

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). Weekly Installs665Repositorysamber/cc-skills-golangGitHub Stars1.1KFirst SeenMar 22, 2026Security AuditsGen Agent Trust HubPassSocketPassSnykPassInstalled onopencode648cursor641codex639gemini-cli637github-copilot636amp635

用户评价 (0)

发表评价

效果
易用性
文档
兼容性

暂无评价

统计数据

安装量2.5K
评分4.3 / 5.0
版本
更新日期2026年5月22日
对比案例1 组

用户评分

4.3(34)
5
68%
4
32%
3
0%
2
0%
1
0%

为此 Skill 评分

0.0

兼容平台

🔧Claude Code

时间线

创建2026年4月9日
最后更新2026年5月22日