Zap (Uber开发): 高性能结构化日志库
import "go.uber.org/zap"
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("This is a structured log",
zap.String("key", "value"),
zap.Int("count", 1))
Logrus: 功能丰富,兼容标准库
import log "github.com/sirupsen/logrus"
log.SetFormatter(&log.JSONFormatter{})
log.WithFields(log.Fields{
"event": "event",
"topic": "topic",
}).Info("This is a structured log")
NewProduction()
而非NewDevelopment()
import "gopkg.in/natefinch/lumberjack.v2"
logger := &lumberjack.Logger{
Filename: "/var/log/myapp/app.log",
MaxSize: 100, // MB
MaxBackups: 5,
MaxAge: 30, // days
Compress: true,
}
log.SetOutput(logger)
/var/log/myapp/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0644 appuser appgroup
sharedscripts
postrotate
systemctl reload myapp > /dev/null
endscript
}
// Zap示例
logger.Info("User logged in",
zap.String("username", username),
zap.String("ip", ip),
zap.Time("time", time.Now()),
zap.Duration("latency", latency))
// Logrus示例
log.WithFields(log.Fields{
"username": username,
"ip": ip,
"time": time.Now(),
"latency": latency,
}).Info("User logged in")
func handler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := zap.L().With(
zap.String("requestID", middleware.GetRequestID(ctx)),
zap.String("path", r.URL.Path),
)
// 使用logger记录日志
}
// 输出到Syslog
func setupSyslog() {
log.SetFormatter(&log.JSONFormatter{})
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "myapp")
if err == nil {
log.AddHook(hook)
}
}
避免频繁字符串拼接:
// 不好
log.Info(fmt.Sprintf("User %s logged in from %s", user, ip))
// 推荐
log.Info("User logged in", "user", user, "ip", ip)
采样高频日志:
if rand.Intn(100) == 0 { // 1%采样率
log.Debug("Debug info", fields...)
}
异步日志写入:
// Zap异步核心配置
zap.New(zapcore.NewCore(
zapcore.NewJSONEncoder(encoderCfg),
zapcore.AddSync(asyncWriter),
zap.InfoLevel,
))
日志错误率监控:
# 统计ERROR级别日志
grep -c '"level":"ERROR"' /var/log/myapp/app.log
Prometheus集成:
var errorCounter = prometheus.NewCounter(prometheus.CounterOpts{
Name: "app_error_logs_total",
Help: "Total number of ERROR logs",
})
func logError(msg string) {
errorCounter.Inc()
log.Error(msg)
}
敏感信息过滤:
func sanitize(input string) string {
return regexp.MustCompile(`(?i)(password|token|key)=[^&\s]+`).
ReplaceAllString(input, "$1=[REDACTED]")
}
日志文件权限:
chmod 640 /var/log/myapp/*.log
chown appuser:appgroup /var/log/myapp/*.log
通过以上优化措施,可以构建一个高性能、易维护且安全的Golang日志管理系统,满足生产环境的需求。