ZAP使用
uber开源高性能日志库
一、快速开始
1.非结构化
性能比结构化的要差(性能比较:https://github.com/uber-go/zap)
(1)友好的日志打印
url := "https://www.baidu.com" logger, _ := zap.NewDevelopment() defer logger.Sync() sugar := logger.Sugar() sugar.Infow("failed to fetch URL", "url", url, "attempt", 3, "backoff", time.Second, ) sugar.Infof("Failed to fetch URL: %s", url)
控制台
- 2019-06-26T15:05:15.564+0800 INFO stuzap/main.go:13 failed to fetch URL {“url”: “https://www.baidu.com”, “attempt”: 3, “backoff”: “1s”}
- 2019-06-26T15:05:15.591+0800 INFO stuzap/main.go:18 Failed to fetch URL: https://www.baidu.com
(2)易于程序识别的格式
url := "https://www.baidu.com" logger, _ := zap.NewProduction() defer logger.Sync() sugar := logger.Sugar() sugar.Infow("failed to fetch URL", "url", url, "attempt", 3, "backoff", time.Second, ) sugar.Infof("Failed to fetch URL: %s", url)
控制台
- {“level”:“info”,“ts”:.,“caller”:“stuzap/main.go:13”,“msg”:“failed to fetch URL”,“url”:“https://www.baidu.com”,“attempt”:3,“backoff”:1}
- {“level”:“info”,“ts”:.,“caller”:“stuzap/main.go:18”,“msg”:“Failed to fetch URL: https://www.baidu.com”}
2.结构化
性能优于非结构化(性能比较https://github.com/uber-go/zap)
(1)友好的日志打印
url := "https://www.baidu.com" logger, _ := zap.NewDevelopment() defer logger.Sync() logger.Info("failed to fetch URL", // Structured context as strongly typed Field values. zap.String("url", url), zap.Int("attempt", 3), zap.Duration("backoff", time.Second), )
控制台
- 2019-06-26T15:09:17.333+0800 INFO stuzap/main.go:12 failed to fetch URL {“url”: “https://www.baidu.com”, “attempt”: 3, “backoff”: “1s”}
(2)易于程序识别的格式
url := "https://www.baidu.com" logger, _ := zap.NewProduction() defer logger.Sync() logger.Info("failed to fetch URL", // Structured context as strongly typed Field values. zap.String("url", url), zap.Int("attempt", 3), zap.Duration("backoff", time.Second), )
控制台
- {“level”:“info”,“ts”:.,“caller”:“stuzap/main.go:12”,“msg”:“failed to fetch URL”,“url”:“https://www.baidu.com”,“attempt”:3,“backoff”:1}
二、动态日志等级
dynamicLevel := zap.NewAtomicLevel() // 默认Info级别 logcfg := zap.NewProductionConfig() logcfg.Level = dynamicLevel logger, err := logcfg.Build() if err != nil {
panic(err) } defer logger.Sync() // 获取当前日志等级 level := dynamicLevel.String() logger.Info("this info log", zap.String("logLevel", level)) // 设置当前日志等级为Debug dynamicLevel.SetLevel(zap.DebugLevel) logger.Debug("this is debug log.", zap.Int64("st", time.Now().Unix())) // http设置日志等级 // 只支持get、put // 格式:{"level":"info"} // dynamicLevel.ServeHTTP
控制台
- {“level”:“info”,“ts”:.,“caller”:“stuzap/main.go:22”,“msg”:“this info log”,“logLevel”:“info”}
- {“level”:“debug”,“ts”:.,“caller”:“stuzap/main.go:26”,“msg”:“this is debug log.”,“st”:}
三、记录到文件中
package main import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" "os" "time" ) // 格式化时间 func TimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05.000")) } func NewEncoderConfig() zapcore.EncoderConfig {
return zapcore.EncoderConfig{
// Keys can be anything except the empty string. TimeKey: "T", // json时时间键 LevelKey: "L", // json时日志等级键 NameKey: "N", // json时日志记录器键 CallerKey: "C", // json时日志文件信息键 MessageKey: "M", // json时日志消息键 StacktraceKey: "S", // json时堆栈键 LineEnding: zapcore.DefaultLineEnding, // 友好日志换行符 EncodeLevel: zapcore.CapitalLevelEncoder, // 友好日志等级名大小写(info INFO) EncodeTime: TimeEncoder, // 友好日志时日期格式化 EncodeDuration: zapcore.StringDurationEncoder, // 时间序列化 EncodeCaller: zapcore.ShortCallerEncoder, // 日志文件信息(包/文件.go:行号) } } func main() {
w := zapcore.AddSync(&lumberjack.Logger{
Filename: "all.log", // 输出文件 MaxSize: 500, // 日志文件最大大小(单位:MB) MaxBackups: 3, // 保留的旧日志文件最大数量 MaxAge: 28, // 保存日期 }) core := zapcore.NewCore( zapcore.NewJSONEncoder(NewEncoderConfig()), // 日志形式 //json形式 //zapcore.NewJSONEncoder(NewEncoderConfig()) //友好形式 //zapcore.NewConsoleEncoder(NewEncoderConfig()) zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), w), // 日志输出流可以添加多个 zap.DebugLevel, // 日志等级 ) logger := zap.New(core, zap.AddCaller()) defer logger.Sync() logger.Info("this is info.", zap.Int("id", 1)) }
控制台
- {“L”:“INFO”,“T”:“2019-06-26 15:46:46.895”,“C”:“stuzap/main.go:52”,“M”:“this is info.”,“id”:1}
四、动态日志等级+记录文件中
package main import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" "os" "time" ) // 格式化时间 func TimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05.000")) } func NewEncoderConfig() zapcore.EncoderConfig {
return zapcore.EncoderConfig{
// Keys can be anything except the empty string. TimeKey: "T", // json时时间键 LevelKey: "L", // json时日志等级键 NameKey: "N", // json时日志记录器名 CallerKey: "C", // json时日志文件信息键 MessageKey: "M", // json时日志消息键 StacktraceKey: "S", // json时堆栈键 LineEnding: zapcore.DefaultLineEnding, // 友好日志换行符 EncodeLevel: zapcore.CapitalLevelEncoder, // 友好日志等级名大小写(info INFO) EncodeTime: TimeEncoder, // 友好日志时日期格式化 EncodeDuration: zapcore.StringDurationEncoder, // 时间序列化 EncodeCaller: zapcore.ShortCallerEncoder, // 日志文件信息(包/文件.go:行号) } } func main() {
// 动态日志等级 dynamicLevel := zap.NewAtomicLevel() w := zapcore.AddSync(&lumberjack.Logger{
Filename: "all.log", // 输出文件 MaxSize: 500, // 日志文件最大大小(单位:MB) MaxBackups: 3, // 保留的旧日志文件最大数量 MaxAge: 28, // 保存日期 }) core := zapcore.NewCore( zapcore.NewJSONEncoder(NewEncoderConfig()), // 日志形式 //json形式 //zapcore.NewJSONEncoder(NewEncoderConfig()) //友好形式 //zapcore.NewConsoleEncoder(NewEncoderConfig()) zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), w), // 日志输出流可以添加多个 dynamicLevel, // 日志等级 ) logger := zap.New(core, zap.AddCaller()) defer logger.Sync() // 将当前日志等级设置为Debug // 注意日志等级低于设置的等级,日志文件也不分记录 dynamicLevel.SetLevel(zap.DebugLevel) logger.Info("this is info.", zap.Int("id", 1)) }
控制台
- {“L”:“INFO”,“T”:“2019-06-26 15:49:57.866”,“C”:“stuzap/main.go:57”,“M”:“this is info.”,“id”:1}
五、动态等级+记录文件+控制台友好格式打印、文件json格式记录
package main import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" "os" "time" ) // 格式化时间 func TimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05.000")) } func NewEncoderConfig() zapcore.EncoderConfig {
return zapcore.EncoderConfig{
// Keys can be anything except the empty string. TimeKey: "T", // json时时间键 LevelKey: "L", // json时日志等级键 NameKey: "N", // json时日志记录器名 CallerKey: "C", // json时日志文件信息键 MessageKey: "M", // json时日志消息键 StacktraceKey: "S", // json时堆栈键 LineEnding: zapcore.DefaultLineEnding, // 友好日志换行符 EncodeLevel: zapcore.CapitalLevelEncoder, // 友好日志等级名大小写(info INFO) EncodeTime: TimeEncoder, // 友好日志时日期格式化 EncodeDuration: zapcore.StringDurationEncoder, // 时间序列化 EncodeCaller: zapcore.ShortCallerEncoder, // 日志文件信息(包/文件.go:行号) } } func main() {
// 动态日志等级 dynamicLevel := zap.NewAtomicLevel() w := zapcore.AddSync(&lumberjack.Logger{
Filename: "all.log", // 输出文件 MaxSize: 500, // 日志文件最大大小(单位:MB) MaxBackups: 3, // 保留的旧日志文件最大数量 MaxAge: 28, // 保存日期 }) highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= zapcore.InfoLevel }) core := zapcore.NewTee( // 有好的格式、输出控制台、动态等级 zapcore.NewCore(zapcore.NewConsoleEncoder(NewEncoderConfig()), os.Stdout, dynamicLevel), // json格式、输出文件、处定义等级规则 zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewDevelopmentEncoderConfig()), w, highPriority), ) logger := zap.New(core, zap.AddCaller()) defer logger.Sync() // 将当前日志等级设置为Debug // 注意日志等级低于设置的等级,日志文件也不分记录 dynamicLevel.SetLevel(zap.DebugLevel) logger.Info("this is info.", zap.Int("ID", 1)) }
控制台
- 2019-06-26 16:33:13.856 INFO stuzap/main.go:68 this is info. {“ID”: 1}
all.log
- {“L”:“INFO”,“T”:“2019-06-26T16:33:13.856+0800”,“C”:“stuzap/main.go:68”,“M”:“this is info.”,“ID”:1}
参考
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201666.html原文链接:https://javaforall.net
