在 Linux 环境下使用 Go (Golang) 写服务时,日志分析通常分为 日志产生 → 日志收集 → 日志分析 → 问题定位 几个阶段。下面从实践角度系统讲一下。
log.Println("something happened")
缺点:没有级别、没有结构化、不好检索。
常用:
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("user login",
zap.String("user", "tom"),
zap.Int("uid", 1001),
)
输出:
{"level":"info","ts":1710000000.123,"msg":"user login","user":"tom","uid":1001}
✅ 结构化日志是后续分析的基础
./app > app.log 2>&1
或使用 systemd:
StandardOutput=append:/var/log/app/app.log
StandardError=append:/var/log/app/app.log
用 logrotate:
/var/log/app/*.log {
daily
rotate 7
compress
missingok
notifempty
}
tail -f app.log
grep -i error app.log
grep ERROR app.log | wc -l
awk '$1 >= "2024-03-01" && $1 <= "2024-03-02"' app.log
cat app.log | jq 'select(.level=="error")'
grep -A 20 panic app.log
配合:
defer func() {
if r := recover(); r != nil {
log.Printf("panic: %v", r)
}
}()
日志中打耗时:
start := time.Now()
// ...
logger.Info("http request",
zap.String("path", "/login"),
zap.Duration("cost", time.Since(start)),
)
分析慢接口:
jq 'select(.cost > 500000000)'
jq 'select(.msg=="user login") | .user' app.log | sort | uniq -c
适合:
✅ 使用结构化日志(zap / slog)
✅ 日志包含:时间、级别、trace_id、关键参数
✅ Linux 下必须做 logrotate
✅ 错误日志单独通道
✅ 小项目:grep + jq
✅ 大项目:ELK / Loki
如果你愿意,可以告诉我:
我可以直接给你一套 可落地的日志方案 + 示例配置。