在 Linux 上用 Golang 写服务时,“日志怎样定位问题”一般从 日志内容设计、日志采集、检索分析、结合系统工具 几方面来做。下面按实战角度讲。
一条能定位问题的日志至少要有:
示例(推荐):
2026-01-15T10:20:31+08:00 ERROR rpc/user.go:88 trace_id=abc123 user_id=1001 msg="call user service timeout" err="context deadline exceeded"
log.Println("error:", err)
❌ 缺级别、缺上下文、难检索
logger, _ := zap.NewProduction()
logger.Error("call user service failed",
zap.String("trace_id", traceID),
zap.Int("user_id", userID),
zap.Error(err),
)
log.WithFields(log.Fields{
"trace_id": traceID,
"user_id": userID,
}).Error(err)
logger.Error("call failed",
"trace_id", traceID,
"user_id", userID,
"err", err,
)
tail -f /var/log/app/app.log
grep "trace_id=abc123" app.log
sed -n '/2026-01-15 10:00/,/2026-01-15 11:00/p' app.log
grep -E "ERROR|PANIC" app.log
如果是 systemd 服务:
journalctl -u your-service -f
journalctl -u your-service --since "2026-01-15 10:00"
配合 Go 日志:
# /etc/systemd/system/app.service
StandardOutput=journal
StandardError=journal
ctx = context.WithValue(ctx, "trace_id", traceID)
{
"time": "2026-01-15T10:20:31+08:00",
"level": "ERROR",
"trace_id": "abc123",
"msg": "db timeout"
}
方便 ELK / Loki 检索。
Go App
↓
文件 / stdout
↓
filebeat / vector
↓
Kafka
↓
ES / Loki
↓
Kibana / Grafana
常用组合:
| 问题类型 | 定位方式 |
|---|---|
| 接口慢 | trace_id + 耗时日志 |
| panic | 堆栈 + 行号 |
| 偶发错误 | 时间 + 请求参数 |
| 并发问题 | goroutine id + trace |
| 系统级 | dmesg / top / strace |
如果你愿意,可以告诉我:
我可以直接给你一套可复制的日志模板和定位方案。