Linux下Golang日志应记录的关键信息
一 核心字段清单
二 不同场景的必记信息
| 场景 | 必记字段 | 建议级别 | 备注 |
|---|---|---|---|
| HTTP 请求 | trace_id、method、uri、status、latency_ms、client_ip、ua、err | INFO/ERROR | 在中间件记录入口/出口,统一错误返回 |
| 数据库/缓存 | query/hash、args(脱敏)、rows、duration_ms、err | DEBUG/ERROR | 记录慢查询阈值与错误 |
| 消息队列 | topic/queue、msg_id、group、partition/offset、duration_ms、err | INFO/ERROR | 便于重放与回溯 |
| 外部 HTTP 调用 | url、method、status、duration_ms、err、trace_id | INFO/ERROR | 传递/继承 trace_id |
| 定时任务/批处理 | job_name、task_id、shard、start/end、duration_ms、records、err | INFO/WARN/ERROR | 记录批次边界与影响面 |
| Goroutine/Worker | goroutine_id、job_type、queue_size、err | DEBUG/WARN | 便于定位并发问题 |
| 启动/关闭/配置变更 | version、build_time、config_key、old→new、err | INFO/WARN | 支持回滚与审计 |
| 安全事件 | user_id、ip、action、resource、result、reason | WARN/ERROR | 触发告警与风控 |
| 性能退化 | p95/p99 延迟、错误率、队列积压、饱和指标 | WARN/ERROR | 结合监控阈值 |
| 审计关键操作 | operator、tenant_id、resource_id、before/after摘要 | INFO/AUDIT | 满足合规要求 |
| 这些场景覆盖了常见后端服务的全链路,便于在 ELK/Graylog 或集中式系统中检索与聚合分析。 |
三 日志格式与输出建议
四 最小可行示例(zap + 关键字段)
package main
import (
"errors"
"fmt"
"net/http"
"os"
"time"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var logger *zap.Logger
func init() {
cfg := zap.NewProductionConfig()
cfg.EncoderConfig.TimeKey = "ts"
cfg.EncoderConfig.EncodeTime = zapcore.RFC3339NanoTimeEncoder
cfg.OutputPaths = []string{"stdout", "/var/log/myapp.log"}
var err error
logger, err = cfg.Build()
if err != nil {
panic(err)
}
}
func handle(w http.ResponseWriter, r *http.Request) {
start := time.Now()
traceID := r.Header.Get("X-Trace-Id")
if traceID == "" {
traceID = fmt.Sprintf("%d", time.Now().UnixNano())
}
defer func() {
latency := time.Since(start).Milliseconds()
logger.Info("http request completed",
zap.String("trace_id", traceID),
zap.String("method", r.Method),
zap.String("uri", r.URL.Path),
zap.Int("status", http.StatusOK),
zap.Int64("latency_ms", latency),
zap.String("ip", r.RemoteAddr),
zap.String("ua", r.UserAgent()),
)
}()
// 模拟业务错误
if r.URL.Path == "/error" {
err := errors.New("something went wrong")
logger.Error("business error occurred",
zap.String("trace_id", traceID),
zap.String("error", err.Error()),
zap.Stack("stack"),
)
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "ok\n")
}
func main() {
http.HandleFunc("/", handle)
if err := http.ListenAndServe(":8080", nil); err != nil {
logger.Fatal("server failed", zap.Error(err))
}
}
要点:在入口/出口记录trace_id、method、uri、status、latency_ms、ip、ua;错误时记录error + stack;统一 JSON 输出到 stdout 与文件,便于容器与本地分析。