在 Go 项目中,日志系统是不可或缺的一部分。它不仅帮助我们定位问题、分析性能,还能在生产环境中追踪系统行为。 本文将介绍如何使用 Zap + Lumberjack 实现高性能双写日志系统:
Zap 是 Uber 开源的高性能日志库,号称“Go 语言最快的日志库之一”。 它有以下优点:
Logger 模式)在长时间运行的服务中,日志会不断增大。 Lumberjack 是一个简单可靠的日志文件切割库,它支持:
MaxSize)MaxAge)MaxBackups)Compress)我们希望实现如下效果:
package main
import (
"io"
"os"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
// 定义编码器:使用 JSON 格式输出
encoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
// 全量日志:控制台 + 文件
coreFull := zapcore.NewCore(encoder, getFullLogWriter(), zapcore.InfoLevel)
// 错误日志:仅文件
coreError := zapcore.NewCore(encoder, getErrorLogWriter(), zapcore.ErrorLevel)
// 合并两个 core
core := zapcore.NewTee(coreFull, coreError)
// 构建 logger
logger := zap.New(core)
sugarLogger := logger.Sugar()
// 测试日志
sugarLogger.Debug("这条不会输出,因为级别低于 Info")
sugarLogger.Info("系统启动成功")
sugarLogger.Error("这是错误日志")
}
// 全量日志(控制台 + 文件)
func getFullLogWriter() zapcore.WriteSyncer {
fullLogger := &lumberjack.Logger{
Filename: "./server.log", // 日志文件路径
MaxSize: 10, // 单个文件最大 10MB
MaxBackups: 5, // 保留 5 个旧文件
MaxAge: 30, // 保留 30 天
Compress: true, // 启用压缩
}
ws := io.MultiWriter(fullLogger, os.Stdout)
return zapcore.AddSync(ws)
}
// 错误日志(仅文件)
func getErrorLogWriter() zapcore.WriteSyncer {
errLogger := &lumberjack.Logger{
Filename: "./error.log",
MaxSize: 10,
MaxBackups: 5,
MaxAge: 30,
Compress: true,
}
return zapcore.AddSync(errLogger)
}
终端输出:
{"level":"info","ts":1730265598.123,"msg":"系统启动成功"} {"level":"error","ts":1730265598.125,"msg":"这是错误日志"}
server.log 文件中会保存全部 Info 以上日志。
error.log 文件中仅保存 Error 以上日志。