安装
go get -u go.uber.org/zap
go get -u github.com/natefinch/lumberjack
zap是一个uber开源的go日志库,性能十分高。
但是zap本身不支持日志切割的功能,所以引入了第三方库lumberjack,来实现日志切割及保存日志固定天数的功能。
简要说明
Zap提供了两种类型的日志记录器—Sugared Logger和Logger。
在性能很好但不是很关键的上下文中,使用SugaredLogger。它比其他结构化日志记录包快4-10倍,并且支持结构化和printf风格的日志记录。
在每一微秒和每一次内存分配都很重要的上下文中,使用Logger。它甚至比SugaredLogger更快,内存分配次数也更少,但它只支持强类型的结构化日志记录。
Logger
- 通过调用
zap.NewProduction()/zap.NewDevelopment()或者zap.Example()创建一个Logger。 - 上面的每一个函数都将创建一个logger。唯一的区别在于它将记录的信息不同。例如production logger默认记录调用函数信息、日期和时间等。
- 通过Logger调用Info/Error等。
- 默认情况下日志都会打印到应用程序的console界面。
Lumberjack Logger采用以下属性作为输入:
- Filename: 日志文件的位置
- MaxSize:在进行切割之前,日志文件的最大大小(以MB为单位)
- MaxBackups:保留旧文件的最大个数,即切割日志数,超出数量的旧日志会被删除,即使尚未到达保留的最大天数
- MaxAges:保留旧文件的最大天数
- Compress:是否压缩/归档旧文件
代码
package main
import (
"net/http"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var sugarLogger *zap.SugaredLogger
func main() {
InitLogger()
defer sugarLogger.Sync()
//不断地输出日志,查看lumberjack的日志切割功能
for i := 0; i < 100000; i++ {
simpleHttpGet("www.baidu.com")
simpleHttpGet("http://www.baidu.com")
}
}
func InitLogger() {
writeSyncer := getLogWriter()
encoder := getEncoder()
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
//AddCaller:添加将调用函数信息记录到日志中的功能
logger := zap.New(core, zap.AddCaller())
sugarLogger = logger.Sugar()
}
func getEncoder() zapcore.Encoder {
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
return zapcore.NewConsoleEncoder(encoderConfig)
// return zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig())
// return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
}
func getLogWriter() zapcore.WriteSyncer {
lumberJackLogger := &lumberjack.Logger{
Filename: "./test.log", //文件不存在,会默认创建,若存在,会追加
MaxSize: 1,
MaxBackups: 5,
MaxAge: 7,
Compress: false,
}
return zapcore.AddSync(lumberJackLogger)
// file, _ := os.Create("./test.log")
// return zapcore.AddSync(file)
}
func simpleHttpGet(url string) {
sugarLogger.Debugf("Trying to hit GET request for %s", url)
resp, err := http.Get(url)
if err != nil {
sugarLogger.Errorf("Error fetching URL %s : Error = %s", url, err)
} else {
content := make([]byte, 1024)
resp.Body.Read(content)
sugarLogger.Infof(
"Success! statusCode = %s,content = %s for URL %s",
resp.Status,
string(content),
url,
)
resp.Body.Close()
}
}
效果
test.log是最新的日志文件,带有日期命名的文件是历史日志文件。
尝试把test-2022-03-01T09-26-53.583.log文件重命名为test-2022-02-01T09-26-53.583.log,再次运行程序,会发现该文件会被删除,因为它超过了Lumberjack的MaxAge配置(我们的程序里配置为保留7天),