在 Go 里“过滤日志内容”通常有几种常见场景,不同场景做法不一样。下面按最常见需求给你总结,并附示例。
log/slog(Go 1.21+,推荐)package main
import (
"log/slog"
"os"
)
func main() {
// 只输出 Info 及以上级别
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo, // Debug 会被过滤掉
}))
slog.SetDefault(logger)
slog.Debug("debug 日志") // 不会输出
slog.Info("info 日志")
slog.Warn("warn 日志")
slog.Error("error 日志")
}
✅ 优点
logrus(老项目常见)package main
import (
"github.com/sirupsen/logrus"
)
func main() {
log := logrus.New()
log.SetLevel(logrus.InfoLevel) // Debug 被过滤
log.Debug("debug")
log.Info("info")
}
io.Writertype FilterWriter struct {
writer *os.File
keyword string
}
func (fw *FilterWriter) Write(p []byte) (n int, err error) {
if !bytes.Contains(p, []byte(fw.keyword)) {
return len(p), nil
}
return fw.writer.Write(p)
}
使用:
log.SetOutput(&FilterWriter{
writer: os.Stdout,
keyword: "ERROR",
})
⚠️ 不推荐用于复杂场景,性能一般
logger := slog.With("module", "order")
logger.Info("下单成功")
logger.Error("下单失败")
然后你可以通过日志采集系统(ELK / Loki)按 module=order 过滤。
如果你用的是:
✅ 不要改 Go 代码 ✅ 在采集端按:
进行过滤,这是最专业做法。
| 错误 | 原因 |
|---|---|
用 if 判断再打日志 |
侵入业务代码 |
| 直接字符串 replace | 容易误伤 |
| 在 Debug 里打大量日志 | 影响性能 |
| 场景 | 推荐 |
|---|---|
| 新项目 | log/slog |
| 已有 logrus | 用 SetLevel |
| 按内容过滤 | 日志系统 |
| 生产环境 | 日志级别 + 采集端 |
如果你愿意,可以告诉我:
我可以直接给你一套可复制的最佳实践配置。