golang-samber-slog
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePersona: 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 packages for Go 1.21+. Three core pipeline libraries plus HTTP middlewares and backend sinks that all implement the standard interface.
slog.Handlerslog.HandlerOfficial resources:
- github.com/samber/slog-multi — handler composition
- github.com/samber/slog-sampling — throughput control
- github.com/samber/slog-formatter — attribute transformation
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余个可组合的包。包含三个核心管道库,以及均实现标准接口的HTTP中间件和后端输出端。
slog.Handlerslog.Handler官方资源:
- github.com/samber/slog-multi — 处理器组合
- github.com/samber/slog-sampling — 吞吐量控制
- github.com/samber/slog-formatter — 属性转换
本技能内容并非详尽无遗。更多信息请参考库文档和代码示例。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
核心库
| Library | Purpose | Key constructors |
|---|---|---|
| Handler composition | |
| Throughput control | |
| Attribute transforms | |
| 库 | 用途 | 核心构造函数 |
|---|---|---|
| 处理器组合 | |
| 吞吐量控制 | |
| 属性转换 | |
slog-multi — Handler Composition
slog-multi — 处理器组合
Six composition patterns, each for a different routing need:
| Pattern | Behavior | Latency impact |
|---|---|---|
| Broadcast to all handlers sequentially | Sum of all handler latencies |
| Route to ALL matching handlers | Sum of matching handlers |
| Route to FIRST match only | Single handler latency |
| Try sequentially until one succeeds | Primary handler latency (happy path) |
| Concurrent broadcast to all handlers | Max of all handler latencies |
| Middleware chain before sink | Middleware 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: , , , , , , , .
LevelIsLevelIsNotMessageIsMessageIsNotMessageContainsMessageNotContainsAttrValueIsAttrKindIsFor full code examples of every pattern, see Pipeline Patterns.
六种组合模式,分别适用于不同的路由需求:
| 模式 | 行为 | 延迟影响 |
|---|---|---|
| 按顺序广播至所有处理器 | 所有处理器延迟之和 |
| 路由至所有匹配的处理器 | 匹配处理器的延迟之和 |
| 仅路由至第一个匹配的处理器 | 单个处理器的延迟 |
| 按顺序尝试直至其中一个成功 | 主处理器延迟(正常路径) |
| 并发广播至所有处理器 | 所有处理器中的最大延迟 |
| 输出端前的中间件链 | 中间件开销 + 输出端延迟 |
go
// 将错误日志路由至Sentry,所有日志输出至标准输出
logger := slog.New(
slogmulti.Router().
Add(sentryHandler, slogmulti.LevelIs(slog.LevelError)).
Add(slog.NewJSONHandler(os.Stdout, nil)).
Handler(),
)内置断言:, , , , , , , 。
LevelIsLevelIsNotMessageIsMessageIsNotMessageContainsMessageNotContainsAttrValueIsAttrKindIs每种模式的完整代码示例,请参考 Pipeline Patterns。
slog-sampling — Throughput Control
slog-sampling — 吞吐量控制
| 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.
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: , , (default), , .
MatchByLevel()MatchByMessage()MatchByLevelAndMessage()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 middleware so all downstream handlers receive clean attributes.
Pipego
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: , , , , , , . Generic formatters: , , , , . Flatten nested attributes with .
PIIFormatterErrorFormatterTimeFormatterUnixTimestampFormatterIPAddressFormatterHTTPRequestFormatterHTTPResponseFormatterFormatByType[T]FormatByKeyFormatByKindFormatByGroupFormatByGroupKeyFlattenFormatterMiddleware作为中间件使用,确保所有下游处理器接收的属性都是干净的。
Pipego
logger := slog.New(
slogmulti.Pipe(slogformatter.NewFormatterMiddleware(
slogformatter.PIIFormatter("user"), // 掩码PII字段
slogformatter.ErrorFormatter("error"), // 结构化错误信息
slogformatter.IPAddressFormatter("client"), // 掩码IP地址
)).Handler(slog.NewJSONHandler(os.Stdout, nil)),
)核心格式化工具:, , , , , , 。通用格式化工具:, , , , 。使用展平嵌套属性。
PIIFormatterErrorFormatterTimeFormatterUnixTimestampFormatterIPAddressFormatterHTTPRequestFormatterHTTPResponseFormatterFormatByType[T]FormatByKeyFormatByKindFormatByGroupFormatByGroupKeyFlattenFormatterMiddlewareHTTP Middlewares
HTTP中间件
Consistent pattern across frameworks: .
router.Use(slogXXX.New(logger))Available: , , , , (net/http).
slog-ginslog-echoslog-fiberslog-chislog-httpAll share a struct with: , , , , , , , , , .
ConfigDefaultLevelClientErrorLevelServerErrorLevelWithRequestBodyWithResponseBodyWithUserAgentWithRequestIDWithTraceIDWithSpanIDFiltersgo
// 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))可用中间件:, , , , (net/http)。
slog-ginslog-echoslog-fiberslog-chislog-http所有中间件均包含结构体,参数包括:, , , , , , , , , 。
ConfigDefaultLevelClientErrorLevelServerErrorLevelWithRequestBodyWithResponseBodyWithUserAgentWithRequestIDWithTraceIDWithSpanIDFiltersgo
// 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 constructor pattern.
Option{}.NewXxxHandler()| Category | Packages |
|---|---|
| Cloud | |
| Messaging | |
| Notification | |
| Storage | |
| Bridges | |
Batch handlers require graceful shutdown — , , , and buffer records internally. Flush on shutdown (e.g., for Datadog, for Loki, for Kafka) or buffered logs are lost.
slog-datadogslog-lokislog-kafkaslog-parquethandler.Stop(ctx)lokiClient.Stop()writer.Close()For configuration examples and shutdown patterns, see Backend Handlers.
所有输出端均遵循构造函数模式。
Option{}.NewXxxHandler()| 分类 | 包 |
|---|---|
| 云服务 | |
| 消息队列 | |
| 通知服务 | |
| 存储 | |
| 桥接工具 | |
批量处理器需要优雅关闭 —— , , , 和 会在内部缓存日志记录。关闭时需刷新缓存(例如Datadog使用,Loki使用,Kafka使用),否则缓存的日志会丢失。
slog-datadogslog-lokislog-kafkaslog-parquethandler.Stop(ctx)lokiClient.Stop()writer.Close()配置示例和关闭模式,请参考 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 |
| Missing shutdown flush on batch handlers | Buffered logs lost on shutdown | |
| Router without default/catch-all handler | Unmatched records silently dropped | Add a handler with no predicate as catch-all |
| Context has no request attributes to extract | Install |
Using | No-op wrapper adding per-record overhead | Remove |
| 错误 | 失败原因 | 修复方案 |
|---|---|---|
| 采样环节在格式化之后 | 为被过滤的记录浪费CPU资源进行格式化 | 将采样环节放在最外层 |
| 同步广播至多个处理器 | 阻塞调用者——延迟为所有处理器延迟之和 | 使用 |
| 批量处理器未执行关闭刷新 | 关闭时缓存的日志丢失 | |
| 路由处理器无默认/兜底处理器 | 不匹配的记录被静默丢弃 | 添加一个无断言的处理器作为兜底 |
未使用HTTP中间件就调用 | 上下文没有可提取的请求属性 | 先安装 |
使用 | 无操作包装会增加每条记录的开销 | 无需中间件时移除 |
Performance Warnings
性能警告
- Fanout latency = sum of all handler latencies (sequential). With 5 handlers at 10ms each, every log call costs 50ms. Use to reduce to max(latencies)
Pool() - 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 on your types instead
slog.LogValuer - Benchmark your pipeline with before production deployment
go test -bench
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
最佳实践
- 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 — assert on records reaching each stage without real sinks
slogmulti.NewHandleInlineHandler - Use to propagate request-scoped attributes from HTTP middleware to all handlers
AttrFromContext - Prefer Router over Fanout when handlers need different record subsets — Router evaluates predicates and skips non-matching handlers
- 先采样,再格式化,最后路由 —— 这个标准顺序可最大限度减少无用功,并确保所有输出端接收的都是干净的数据
- 使用Pipe处理横切关注点 —— Trace ID注入和PII清理属于中间件逻辑,而非单个处理器的逻辑
- 使用测试管道 —— 无需真实输出端,即可断言每条记录是否到达每个环节
slogmulti.NewHandleInlineHandler - 使用从HTTP中间件向所有处理器传播请求范围的属性
AttrFromContext - 当处理器需要不同的记录子集时,优先使用Router而非Fanout —— Router会评估断言,跳过不匹配的处理器
Cross-References
交叉引用
- → See skill for slog fundamentals (levels, context, handler setup, migration)
samber/cc-skills-golang@golang-observability - → See skill for the log-or-return rule
samber/cc-skills-golang@golang-error-handling - → See skill for PII handling in logs
samber/cc-skills-golang@golang-security - → See skill for structured error context with
samber/cc-skills-golang@golang-samber-oopssamber/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/issues、slog-sampling/issues)。