golang-samber-slog

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
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.
角色定位: 你是一名Go日志架构师。你设计的日志管道能让每条日志记录流经正确的处理器——采样环节提前过滤冗余日志,格式化环节在日志记录离开进程前剥离PII(个人可识别信息),路由环节将错误日志发送至Sentry,而信息日志发送至Loki。

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

samber/slog-**** — 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 informations. Context7 can help as a discoverability platform.
为Go 1.21+提供20余个可组合的
slog.Handler
包。包含三个核心管道库,以及均实现标准
slog.Handler
接口的HTTP中间件和后端输出端。
官方资源:
本技能内容并非详尽无遗。更多信息请参考库文档和代码示例。Context7可作为发现平台提供帮助。

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.
每个samber/slog管道都遵循标准顺序。日志记录从左到右流动——将采样环节放在最前面,可提前过滤日志,避免为永远不会到达输出端的记录浪费CPU资源。
record → [Sampling] → [Pipe: trace/PII] → [Router] → [Sinks]
顺序至关重要:先采样后格式化可节省CPU资源。先格式化后路由可确保所有输出端接收的属性都是干净的。颠倒顺序会导致为被过滤的记录做无用功。

Core Libraries

核心库

LibraryPurposeKey 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
处理器组合
Fanout
,
Router
,
FirstMatch
,
Failover
,
Pool
,
Pipe
slog-sampling
吞吐量控制
UniformSamplingOption
,
ThresholdSamplingOption
,
AbsoluteSamplingOption
,
CustomSamplingOption
slog-formatter
属性转换
PIIFormatter
,
ErrorFormatter
,
FormatByType[T]
,
FormatByKey
,
FlattenFormatterMiddleware

slog-multi — Handler Composition

slog-multi — 处理器组合

Six composition patterns, each for a different routing need:
PatternBehaviorLatency impact
Fanout(handlers...)
Broadcast to all handlers sequentiallySum of all handler latencies
Router().Add(h, predicate).Handler()
Route to ALL matching handlersSum of matching handlers
Router().Add(...).FirstMatch().Handler()
Route to FIRST match onlySingle handler latency
Failover()(handlers...)
Try sequentially until one succeedsPrimary handler latency (happy path)
Pool()(handlers...)
Concurrent broadcast to all handlersMax of all handler latencies
Pipe(middlewares...).Handler(sink)
Middleware chain before sinkMiddleware overhead + sink
go
// 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.
六种组合模式,分别适用于不同的路由需求:
模式行为延迟影响
Fanout(handlers...)
按顺序广播至所有处理器所有处理器延迟之和
Router().Add(h, predicate).Handler()
路由至所有匹配的处理器匹配处理器的延迟之和
Router().Add(...).FirstMatch().Handler()
仅路由至第一个匹配的处理器单个处理器的延迟
Failover()(handlers...)
按顺序尝试直至其中一个成功主处理器延迟(正常路径)
Pool()(handlers...)
并发广播至所有处理器所有处理器中的最大延迟
Pipe(middlewares...).Handler(sink)
输出端前的中间件链中间件开销 + 输出端延迟
go
// 将错误日志路由至Sentry,所有日志输出至标准输出
logger := slog.New(
    slogmulti.Router().
        Add(sentryHandler, slogmulti.LevelIs(slog.LevelError)).
        Add(slog.NewJSONHandler(os.Stdout, nil)).
        Handler(),
)
内置断言:
LevelIs
,
LevelIsNot
,
MessageIs
,
MessageIsNot
,
MessageContains
,
MessageNotContains
,
AttrValueIs
,
AttrKindIs
每种模式的完整代码示例,请参考 Pipeline Patterns

slog-sampling — Throughput Control

slog-sampling — 吞吐量控制

StrategyBehaviorBest for
UniformDrop fixed % of all recordsDev/staging noise reduction
ThresholdLog first N per interval, then sample at rate RProduction — preserves initial visibility
AbsoluteCap at N records per interval globallyHard cost control
CustomUser function returns sample rate per recordLevel-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.
go
// 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.
策略行为最佳适用场景
均匀采样过滤固定比例的所有记录开发/测试环境减少冗余日志
阈值采样在每个时间间隔内记录前N条,之后按比例R采样生产环境——保留初始可见性
绝对采样全局限制每个时间间隔内的记录数为N严格控制成本
自定义采样用户函数返回每条记录的采样率基于日志级别或时间的规则
采样环节必须是管道的最外层处理器——将其放在格式化之后会导致为被过滤的记录浪费CPU资源。
go
// 阈值采样:每5秒记录前10条,之后按10%采样——错误日志始终通过路由放行
logger := slog.New(
    slogmulti.
        Pipe(slogsampling.ThresholdSamplingOption{
            Tick: 5 * time.Second, Threshold: 10, Rate: 0.1,
        }.NewMiddleware()).
        Handler(innerHandler),
)
匹配器用于对相似记录进行分组去重:
MatchByLevel()
,
MatchByMessage()
,
MatchByLevelAndMessage()
(默认),
MatchBySource()
,
MatchByAttribute(groups, key)
策略对比和配置详情,请参考 Sampling Strategies

slog-formatter — Attribute Transformation

slog-formatter — 属性转换

Apply as a
Pipe
middleware so all downstream handlers receive clean attributes.
go
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
.
作为
Pipe
中间件使用,确保所有下游处理器接收的属性都是干净的。
go
logger := slog.New(
    slogmulti.Pipe(slogformatter.NewFormatterMiddleware(
        slogformatter.PIIFormatter("user"),          // 掩码PII字段
        slogformatter.ErrorFormatter("error"),       // 结构化错误信息
        slogformatter.IPAddressFormatter("client"),  // 掩码IP地址
    )).Handler(slog.NewJSONHandler(os.Stdout, nil)),
)
核心格式化工具:
PIIFormatter
,
ErrorFormatter
,
TimeFormatter
,
UnixTimestampFormatter
,
IPAddressFormatter
,
HTTPRequestFormatter
,
HTTPResponseFormatter
。通用格式化工具:
FormatByType[T]
,
FormatByKey
,
FormatByKind
,
FormatByGroup
,
FormatByGroupKey
。使用
FlattenFormatterMiddleware
展平嵌套属性。

HTTP Middlewares

HTTP中间件

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
.
go
// 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.
各框架遵循一致的模式:
router.Use(slogXXX.New(logger))
可用中间件:
slog-gin
,
slog-echo
,
slog-fiber
,
slog-chi
,
slog-http
(net/http)。
所有中间件均包含
Config
结构体,参数包括:
DefaultLevel
,
ClientErrorLevel
,
ServerErrorLevel
,
WithRequestBody
,
WithResponseBody
,
WithUserAgent
,
WithRequestID
,
WithTraceID
,
WithSpanID
,
Filters
go
// Gin框架搭配过滤器——忽略健康检查
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"),
    },
}))
框架专属设置,请参考 HTTP Middlewares

Backend Sinks

后端输出端

All follow the
Option{}.NewXxxHandler()
constructor pattern.
CategoryPackages
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 shutdown
slog-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.
所有输出端均遵循
Option{}.NewXxxHandler()
构造函数模式。
分类
云服务
slog-datadog
,
slog-sentry
,
slog-loki
,
slog-graylog
消息队列
slog-kafka
,
slog-fluentd
,
slog-logstash
,
slog-nats
通知服务
slog-slack
,
slog-telegram
,
slog-webhook
存储
slog-parquet
桥接工具
slog-zap
,
slog-zerolog
,
slog-logrus
批量处理器需要优雅关闭 ——
slog-datadog
,
slog-loki
,
slog-kafka
, 和
slog-parquet
会在内部缓存日志记录。关闭时需刷新缓存(例如Datadog使用
handler.Stop(ctx)
,Loki使用
lokiClient.Stop()
,Kafka使用
writer.Close()
),否则缓存的日志会丢失。
配置示例和关闭模式,请参考 Backend Handlers

Common Mistakes

常见错误

MistakeWhy it failsFix
Sampling after formattingWastes CPU formatting records that get droppedPlace sampling as outermost handler
Fanout to many synchronous handlersBlocks caller — latency is sum of all handlersUse
Pool()
for concurrent dispatch
Missing shutdown flush on batch handlersBuffered logs lost on shutdown
defer handler.Stop(ctx)
(Datadog),
defer lokiClient.Stop()
(Loki),
defer writer.Close()
(Kafka)
Router without default/catch-all handlerUnmatched records silently droppedAdd a handler with no predicate as catch-all
AttrFromContext
without HTTP middleware
Context has no request attributes to extractInstall
slog-gin
/
echo
/
fiber
/
chi
middleware first
Using
Pipe
with no middleware
No-op wrapper adding per-record overheadRemove
Pipe()
if no middleware needed
错误失败原因修复方案
采样环节在格式化之后为被过滤的记录浪费CPU资源进行格式化将采样环节放在最外层
同步广播至多个处理器阻塞调用者——延迟为所有处理器延迟之和使用
Pool()
进行并发分发
批量处理器未执行关闭刷新关闭时缓存的日志丢失
defer handler.Stop(ctx)
(Datadog)、
defer lokiClient.Stop()
(Loki)、
defer writer.Close()
(Kafka)
路由处理器无默认/兜底处理器不匹配的记录被静默丢弃添加一个无断言的处理器作为兜底
未使用HTTP中间件就调用
AttrFromContext
上下文没有可提取的请求属性先安装
slog-gin
/
echo
/
fiber
/
chi
中间件
使用
Pipe
但未添加中间件
无操作包装会增加每条记录的开销无需中间件时移除
Pipe()

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.
  • Fanout延迟 = 所有处理器延迟之和(顺序执行)。如果有5个处理器,每个延迟10ms,那么每次日志调用会花费50ms。使用
    Pool()
    可将延迟降低至最大延迟值
  • Pipe中间件 会增加每条记录的函数调用开销——保持中间件链简短(2-4个中间件)
  • slog-formatter 会顺序处理属性——多个格式化工具会叠加开销。对于热点路径的属性格式化,建议在你的类型上实现
    slog.LogValuer
    替代
  • 基准测试:生产部署前使用
    go test -bench
    测试你的管道性能
诊断方法: 测量管道每条记录的内存分配和延迟,确定链中哪个处理器的内存分配最多。

Best Practices

最佳实践

  1. Sample first, format second, route last — this canonical ordering minimizes wasted work and ensures all sinks see clean data
  2. Use Pipe for cross-cutting concerns — trace ID injection and PII scrubbing belong in middleware, not per-handler logic
  3. Test pipelines with
    slogmulti.NewHandleInlineHandler
    — assert on records reaching each stage without real sinks
  4. Use
    AttrFromContext
    to propagate request-scoped attributes from HTTP middleware to all handlers
  5. Prefer Router over Fanout when handlers need different record subsets — Router evaluates predicates and skips non-matching handlers
  1. 先采样,再格式化,最后路由 —— 这个标准顺序可最大限度减少无用功,并确保所有输出端接收的都是干净的数据
  2. 使用Pipe处理横切关注点 —— Trace ID注入和PII清理属于中间件逻辑,而非单个处理器的逻辑
  3. 使用
    slogmulti.NewHandleInlineHandler
    测试管道
    —— 无需真实输出端,即可断言每条记录是否到达每个环节
  4. 使用
    AttrFromContext
    从HTTP中间件向所有处理器传播请求范围的属性
  5. 当处理器需要不同的记录子集时,优先使用Router而非Fanout —— Router会评估断言,跳过不匹配的处理器

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).
  • → 关于slog基础(日志级别、上下文、处理器设置、迁移),请查看
    samber/cc-skills-golang@golang-observability
    技能
  • → 关于日志或返回规则,请查看
    samber/cc-skills-golang@golang-error-handling
    技能
  • → 关于日志中的PII处理,请查看
    samber/cc-skills-golang@golang-security
    技能
  • → 关于使用
    samber/oops
    实现结构化错误上下文,请查看
    samber/cc-skills-golang@golang-samber-oops
    技能
如果在任何samber/slog-*包中遇到bug或异常行为,请在对应仓库提交issue(例如slog-multi/issuesslog-sampling/issues)。