0Pricing
Go Academy · 课时

自定义处理器

构建您自己的日志输出

自定义处理器 是 CoddyKit 上的免费 Go Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。

内置处理程序不够用时

文本和 JSON 处理程序可以满足大多数需求,但有时您会需要自定义输出:彩色终端、发送到指标系统,或对机密信息进行脱敏。此时可以构建自定义 Handler。

Handler 接口

处理程序需要实现四个方法:

  • Enabled(ctx, level) bool
  • Handle(ctx, record) error
  • WithAttrs(attrs) Handler
  • WithGroup(name) Handler
type Handler interface {
    Enabled(context.Context, slog.Level) bool
    Handle(context.Context, slog.Record) error
    WithAttrs(attrs []slog.Attr) slog.Handler
    WithGroup(name string) slog.Handler
}

Enabled 控制筛选

Enabled 会在构建记录之前被调用。返回 false 可以让 slog 完全跳过后续工作,因此应使用它进行级别检查。

func (h *MyHandler) Enabled(_ context.Context, l slog.Level) bool {
    return l >= slog.LevelInfo
}

Handle 执行实际工作

Handle 会接收包含时间、级别、消息和属性的 slog.Record。您可以按照自己的方式对其进行格式化和写入。

func (h *MyHandler) Handle(_ context.Context, r slog.Record) error {
    fmt.Printf("[%s] %s\n", r.Level, r.Message)
    return nil
}

遍历属性

Record 通过 r.Attrs 暴露其属性,该方法会针对每个属性调用您的函数。

r.Attrs(func(a slog.Attr) bool {
    fmt.Printf("  %s=%v\n", a.Key, a.Value)
    return true // keep going
})

WithAttrs 与 WithGroup

它们会返回您处理程序的副本,并携带预设属性或分组前缀。它们支持 logger.With 和 slog.Group。简易处理程序可以保存并重放这些属性,或者在学习时直接返回自身。

包装而不是构建

很多时候,您不需要完整的处理程序;可以包装现有处理程序,只重写所需行为,例如添加固定属性或对键进行脱敏。

type RedactHandler struct{ slog.Handler }

func (h RedactHandler) Handle(ctx context.Context, r slog.Record) error {
    // mutate r here, then delegate
    return h.Handler.Handle(ctx, r)
}

使用场景:脱敏

脱敏处理程序可以扫描属性,查找 password 或 token 等敏感键,并在交给 JSON 处理程序之前替换其值。

使用场景:路由

自定义处理程序可以按级别进行路由:将 Error 日志发送到标准错误输出和告警网络钩子,同时将 Info 发送到标准输出。这样可以避免在每个调用位置都编写路由逻辑。

性能注意事项

Handle 可能会在热路径中运行。请避免分配,在 Enabled 中进行级别检查,并复用缓冲区。标准处理程序在内部使用缓冲池,原因就在于此。

可运行:简易自定义处理程序

这个独立完整的程序定义了一个小型处理程序,用于打印级别、消息和属性,然后通过它记录日志。

package main

import (
    "context"
    "fmt"
    "log/slog"
)

type Mini struct{}

func (Mini) Enabled(context.Context, slog.Level) bool { return true }
func (Mini) WithAttrs(a []slog.Attr) slog.Handler   { return Mini{} }
func (Mini) WithGroup(string) slog.Handler          { return Mini{} }
func (Mini) Handle(_ context.Context, r slog.Record) error {
    fmt.Printf("%s: %s", r.Level, r.Message)
    r.Attrs(func(a slog.Attr) bool {
        fmt.Printf(" %s=%v", a.Key, a.Value)
        return true
    })
    fmt.Println()
    return nil
}

func main() {
    l := slog.New(Mini{})
    l.Info("hello", "user", "ada", "id", 7)
}

快速检查

请测试您对自定义处理程序的理解。

回顾

您已学会构建自定义处理程序:

  • 实现 Enabled、Handle、WithAttrs、WithGroup
  • 在 Enabled 中进行级别检查,以提升性能
  • 使用 r.Attrs 遍历属性
  • 通常,包装现有处理程序比从头构建更容易

常见问题解答

「自定义处理器」课时是免费的吗?

是的 — 「自定义处理器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。

「自定义处理器」这节课中我会学到什么?

构建您自己的日志输出 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Go Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「自定义处理器」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Go Academy 课中编写并运行代码吗?

能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 为什么使用结构化日志
  2. slog 处理器
  3. 日志级别与属性
  4. 自定义处理器
← 返回 Go Academy