Skip to content

最佳实践 ​

使用 Zap 日志库的最佳实践。

初始化 Logger ​

生产环境 ​

go
func InitLogger() *zap.Logger {
    config := zap.NewProductionConfig()
    config.Level = zap.NewAtomicLevelAt(zap.InfoLevel)
    config.EncoderConfig.TimeKey = "timestamp"
    config.EncoderConfig.EncodeTime = zap.ISO8601TimeEncoder
    
    logger, _ := config.Build(zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))
    return logger
}

开发环境 ​

go
func InitDevLogger() *zap.Logger {
    config := zap.NewDevelopmentConfig()
    config.EncoderConfig.EncodeLevel = zap.CapitalColorLevelEncoder
    config.EncoderConfig.EncodeTime = zap.TimeEncoderOfLayout("2006-01-02 15:04:05")
    
    logger, _ := config.Build(zap.AddCaller())
    return logger
}

日志规范 ​

日志级别使用 ​

级别用途
Debug详细调试信息
Info通用运行信息
Warn潜在问题警告
Error错误但不影响运行
Fatal严重错误,程序退出

结构化日志 ​

go
// 推荐
logger.Info("处理请求",
    zap.String("method", "GET"),
    zap.String("path", "/api/users"),
    zap.Int("status", 200),
    zap.Duration("latency", latency),
)

// 不推荐
logger.Info(fmt.Sprintf("处理请求 method=%s path=%s status=%d", "GET", "/api/users", 200))

最佳实践总结 ​

  1. 结构化日志:使用 zap.Field 而非字符串拼接
  2. 合理级别:根据环境设置日志级别
  3. 关键字段:记录 request_id、user_id 等追踪信息
  4. 日志轮转:使用 lumberjack 管理日志文件
  5. 性能优先:使用结构化日志减少分配
  6. 敏感信息:避免记录密码等敏感数据
  7. 全局 Logger:使用 zap.L() 统一访问
  8. 上下文传递:使用 context 传递 logger

参考:https://pkg.go.dev/go.uber.org/zap