golang-samber-slog

golang-samber-slog

熱門

使用 samber/slog-**** 套件的 Go 結構化日誌擴充功能 — 多處理器管道 (slog-multi)、日誌取樣 (slog-sampling)、屬性格式化 (slog-formatter)、HTTP 中介軟體 (slog-fiber、slog-gin、slog-chi、slog-echo) 以及後端路由 (slog-datadog、slog-sentry、slog-loki、slog-syslog、slog-logstash、slog-graylog...)。適用於正在使用或導入 slog 的專案,或程式碼庫已匯入任何 github.com/samber/slog-* 套件的情況。

2261星標
150分支
更新於 2026/6/6
SKILL.md
readonlyread-only
name
golang-samber-slog
description

使用 samber/slog-**** 套件的 Go 結構化日誌擴充功能 — 多處理器管道 (slog-multi)、日誌取樣 (slog-sampling)、屬性格式化 (slog-formatter)、HTTP 中介軟體 (slog-fiber、slog-gin、slog-chi、slog-echo) 以及後端路由 (slog-datadog、slog-sentry、slog-loki、slog-syslog、slog-logstash、slog-graylog...)。適用於正在使用或導入 slog 的專案,或程式碼庫已匯入任何 github.com/samber/slog-* 套件的情況。

角色設定: 你是一位 Go 日誌架構師。你設計的日誌管道中,每一筆記錄都會流經正確的處理器——取樣在早期就丟棄雜訊,格式化器在記錄離開程序前移除 PII,路由器將錯誤送往 Sentry,而資訊層級的日誌則送往 Loki。

samber/slog-**** — Go 的結構化日誌管道

超過 20 個可組合的 slog.Handler 套件,適用於 Go 1.21+。三個核心管道函式庫,加上 HTTP 中介軟體和後端接收器,全都實作了標準的 slog.Handler 介面。

官方資源:

此技能並非詳盡無遺。請參閱函式庫文件和程式碼範例以獲取更多資訊。Context7 可作為探索平台提供協助。如需 Go 套件文件、版本、符號和已知漏洞,→ 請參閱 samber/cc-skills-golang@golang-pkg-go-dev 技能。

管道模型

每個 samber/slog 管道都遵循標準的順序。記錄從左到右流動——先放置取樣以提早丟棄,避免浪費 CPU 在永遠不會到達接收器的記錄上。

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

順序很重要:在格式化之前取樣可以節省 CPU。在路由之前格式化可確保所有接收器收到乾淨的屬性。反過來做會浪費工作在會被丟棄的記錄上。

核心函式庫

函式庫 用途 主要建構子
slog-multi 處理器組合 FanoutRouterFirstMatchFailoverPoolPipe
slog-sampling 吞吐量控制 UniformSamplingOptionThresholdSamplingOptionAbsoluteSamplingOptionCustomSamplingOption
slog-formatter 屬性轉換 PIIFormatterErrorFormatterFormatByType[T]FormatByKeyFlattenFormatterMiddleware

slog-multi — 處理器組合

六種組合模式,各自滿足不同的路由需求:

模式 行為 延遲影響
Fanout(handlers...) 依序廣播給所有處理器 所有處理器延遲的總和
Router().Add(h, predicate).Handler() 路由給所有符合條件的處理器 符合條件處理器的延遲總和
Router().Add(...).FirstMatch().Handler() 只路由給第一個符合的處理器 單一處理器延遲
Failover()(handlers...) 依序嘗試直到成功 主要處理器延遲(正常路徑)
Pool()(handlers...) 負載平衡:每筆記錄發送給一個處理器 單一處理器延遲
Pipe(middlewares...).Handler(sink) 在接收器之前的中介軟體鏈 中介軟體開銷 + 接收器
// 將錯誤路由到 Sentry,所有日誌輸出到 stdout
logger := slog.New(
    slogmulti.Router().
        Add(sentryHandler, slogmulti.LevelIs(slog.LevelError)).
        Add(slog.NewJSONHandler(os.Stdout, nil)).
        Handler(),
)

內建謂詞:LevelIsLevelIsNotMessageIsMessageIsNotMessageContainsMessageNotContainsAttrValueIsAttrKindIs

如需每種模式的完整程式碼範例,請參閱管道模式

slog-sampling — 吞吐量控制

策略 行為 最佳適用場景
Uniform 丟棄固定比例的記錄 開發/測試環境的雜訊減少
Threshold 每個時間間隔內先記錄前 N 筆,之後以比率 R 取樣 正式環境 — 保留初始可見性
Absolute 全域限制每個時間間隔最多 N 筆記錄 嚴格的成本控制
Custom 使用者自訂函式,回傳每筆記錄的取樣率 依層級或時間的規則

取樣必須是管道中最外層的處理器——放在格式化之後會浪費 CPU 在會被丟棄的記錄上。

// Threshold:每 5 秒先記錄前 10 筆,之後取樣 10% — 錯誤透過 Router 永遠通過
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)

如需策略比較和配置細節,請參閱取樣策略

slog-formatter — 屬性轉換

作為 Pipe 中介軟體套用,以便所有下游處理器收到乾淨的屬性。

logger := slog.New(
    slogmulti.Pipe(slogformatter.NewFormatterMiddleware(
        slogformatter.PIIFormatter("user"),          // 遮罩 PII 欄位
        slogformatter.ErrorFormatter("error"),       // 結構化錯誤資訊
        slogformatter.IPAddressFormatter("client"),  // 遮罩 IP 位址
    )).Handler(slog.NewJSONHandler(os.Stdout, nil)),
)

主要格式化器:PIIFormatterErrorFormatterTimeFormatterUnixTimestampFormatterIPAddressFormatterHTTPRequestFormatterHTTPResponseFormatter。通用格式化器:FormatByType[T]FormatByKeyFormatByKindFormatByGroupFormatByGroupKey。使用 FlattenFormatterMiddleware 扁平化巢狀屬性。

HTTP 中介軟體

跨框架的一致模式:router.Use(slogXXX.New(logger))

可用套件:slog-ginslog-echoslog-fiberslog-chislog-http (net/http)。

所有套件共用一個 Config 結構,包含:DefaultLevelClientErrorLevelServerErrorLevelWithRequestBodyWithResponseBodyWithUserAgentWithRequestIDWithTraceIDWithSpanIDFilters

// 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 中介軟體

後端接收器

所有接收器都遵循 Option{}.NewXxxHandler() 建構子模式。

類別 套件
雲端 slog-datadogslog-sentryslog-lokislog-graylog
訊息傳遞 slog-kafkaslog-fluentdslog-logstashslog-nats
通知 slog-slackslog-telegramslog-webhook
儲存 slog-parquet
橋接 slog-zapslog-zerologslog-logrus

批次處理器需要優雅關閉slog-datadogslog-lokislog-kafkaslog-parquet 會在內部緩衝記錄。請在關閉時刷新(例如 Datadog 使用 handler.Stop(ctx)、Loki 使用 lokiClient.Stop()、Kafka 使用 writer.Close()),否則緩衝的日誌會遺失。

如需配置範例和關閉模式,請參閱後端處理器

常見錯誤

錯誤 失敗原因 修正方式
在格式化之後取樣 浪費 CPU 格式化會被丟棄的記錄 將取樣放在最外層處理器
使用 Fanout 連接多個同步處理器 阻塞呼叫端——延遲是所有處理器的總和 使用 Pool() 進行並行分派
未在批次處理器關閉時刷新 緩衝的日誌在關閉時遺失 defer handler.Stop(ctx) (Datadog)、defer lokiClient.Stop() (Loki)、defer writer.Close() (Kafka)
Router 沒有預設/捕捉所有處理器 未匹配的記錄被靜默丟棄 新增一個沒有謂詞的處理器作為捕捉所有
未使用 HTTP 中介軟體就使用 AttrFromContext 上下文沒有可提取的請求屬性 先安裝 slog-gin/echo/fiber/chi 中介軟體
使用沒有中介軟體的 Pipe 無作用的包裝,增加每筆記錄的開銷 如果不需要中介軟體,移除 Pipe()

效能警告

  • Fanout 延遲 = 所有處理器延遲的總和(依序)。如果有 5 個處理器,每個 10 毫秒,每次日誌呼叫耗費 50 毫秒。使用 Pool() 可降低為 max(latencies)
  • Pipe 中介軟體 會增加每筆記錄的函式呼叫開銷——保持鏈條簡短(2-4 個中介軟體)
  • slog-formatter 依序處理屬性——多個格式化器會疊加。對於熱路徑屬性格式化,建議在你的型別上實作 slog.LogValuer 來取代
  • 基準測試 你的管道,使用 go test -bench 在正式環境部署前進行

診斷: 測量管道的每筆記錄分配和延遲,找出鏈條中哪個處理器分配最多。

最佳實踐

  1. 先取樣、再格式化、最後路由 — 這個標準順序能最小化浪費的工作,並確保所有接收器看到乾淨的資料
  2. 使用 Pipe 處理橫切關注點 — 追蹤 ID 注入和 PII 清除屬於中介軟體,不應放在每個處理器的邏輯中
  3. 使用 slogmulti.NewHandleInlineHandler 測試管道 — 無需真實接收器即可斷言記錄到達每個階段
  4. 使用 AttrFromContext 將請求範圍的屬性從 HTTP 中介軟體傳播到所有處理器
  5. 需要不同記錄子集的處理器時,優先使用 Router 而非 Fanout — Router 會評估謂詞並跳過不匹配的處理器

交叉參考

  • → 參閱 samber/cc-skills-golang@golang-observability 技能以了解 slog 基礎(層級、上下文、處理器設定、遷移)
  • → 參閱 samber/cc-skills-golang@golang-error-handling 技能以了解記錄或回傳規則
  • → 參閱 samber/cc-skills-golang@golang-security 技能以了解日誌中的 PII 處理
  • → 參閱 samber/cc-skills-golang@golang-samber-oops 技能以了解使用 samber/oops 的結構化錯誤上下文

如果你在任何 samber/slog-* 套件中遇到錯誤或非預期行為,請在相關儲存庫中開啟問題(例如 slog-multi/issuesslog-sampling/issues)。