美文网首页
golang zaplog使用(转)

golang zaplog使用(转)

作者: 何约什 | 来源:发表于2021-09-25 10:55 被阅读0次

    zap 使用

    uber 开源,zap 可以在控制面板、文档甚至发送数据到其他系统中,以此来记录日志。我们可以指定日志的级别,支持 json 结构化,方便查询。

    和 logrus 类似,简单来讲,日志有两个概念:字段和消息。字段用来结构化输出错误相关的上下文环境,而消息简明扼要的阐述错误本身。

    开发模式下是普通文本的结构:

    package main
    
    import (
     "go.uber.org/zap"
     "time"
    )
    
    func () {
    
     logger, _ := zap.NewDevelopment() 
    
     defer logger.Sync()
     logger.Info("无法获取网址",
     zap.String("url", "http://www.baidu.com"),
     zap.Int("attempt", 3),
     zap.Duration("backoff", time.Second),
     )
    }
    

    |

    自定义配置:

    func main() {
     encoderConfig := zapcore.EncoderConfig{
     TimeKey:        "time",
     LevelKey:       "level",
     NameKey:        "logger",
     CallerKey:      "caller",
     MessageKey:     "msg",
     StacktraceKey:  "stacktrace",
     LineEnding:     zapcore.DefaultLineEnding,
     EncodeLevel:    zapcore.LowercaseLevelEncoder, 
     EncodeTime:     zapcore.ISO8601TimeEncoder,     // ISO8601 UTC 时间格式
     EncodeDuration: zapcore.SecondsDurationEncoder,
     EncodeCaller:   zapcore.FullCallerEncoder,      // 全路径编码器
     }
    
     // 设置日志级别
     atom := zap.NewAtomicLevelAt(zap.DebugLevel)
    
     config := zap.Config{
     Level:            atom,                                                // 日志级别
     Development:      true,                                                // 开发模式,堆栈跟踪
     Encoding:         "json",                                              // 输出格式 console 或 json
     EncoderConfig:    encoderConfig,                                       // 编码器配置
     InitialFields:    map[string]interface{}{"serviceName": "spikeProxy"}, // 初始化字段,如:添加一个服务器名称
     OutputPaths:      []string{"stdout", "./logs/spikeProxy.log"},         // 输出到指定文档 stdout(标准输出,正常颜色) stderr(错误输出,红色)
     ErrorOutputPaths: []string{"stderr"},
     }
    
     // 构建日志
     logger, err := config.Build()
     if err != nil {
     panic(fmt.Sprintf("log 初始化失败: %v", err))
     }
     logger.Info("log 初始化成功")
    
     logger.Info("无法获取网址",
     zap.String("url", "http://www.baidu.com"),
     zap.Int("attempt", 3),
     zap.Duration("backoff", time.Second),
     )
    }
    

    lumberjack 归档

    日志文档越来越大,我们根据大小、日期进行归档。
    zap 可以写入文档,但是并没有归档的功能。借助于 lumberjack 第三方库,利用 hook 进行归档。

    import (
     "go.uber.org/zap"
     "go.uber.org/zap/zapcore"
     "time"
     "gopkg.in/natefinch/lumberjack.v2"
     "os"
    )
    
    func main() {
     hook := lumberjack.Logger{
     Filename:   "./logs/spikeProxy1.log", // 日志文档路径
     MaxSize:    128,                      // 每个日志文档保存的最大尺寸 单位:M
     MaxBackups: 30,                       // 日志文档最多保存多少个备份
     MaxAge:     7,                        // 文档最多保存多少天
     Compress:   true,                     // 是否压缩
     }
    
     encoderConfig := zapcore.EncoderConfig{
     TimeKey:        "time",
     LevelKey:       "level",
     NameKey:        "logger",
     CallerKey:      "linenum",
     MessageKey:     "msg",
     StacktraceKey:  "stacktrace",
     LineEnding:     zapcore.DefaultLineEnding,
     EncodeLevel:    zapcore.LowercaseLevelEncoder,  // 小写编码器
     EncodeTime:     zapcore.ISO8601TimeEncoder,     // ISO8601 UTC 时间格式
     EncodeDuration: zapcore.SecondsDurationEncoder, //
     EncodeCaller:   zapcore.FullCallerEncoder,      // 全路径编码器
     EncodeName:     zapcore.FullNameEncoder,
     }
    
     // 设置日志级别
     atomicLevel := zap.NewAtomicLevel()
     atomicLevel.SetLevel(zap.InfoLevel)
    
     core := zapcore.NewCore(
     zapcore.NewJSONEncoder(encoderConfig),                                           // 编码器配置
     zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制面板和文档
     atomicLevel,                                                                     // 日志级别
     )
    
     // 开启开发模式,堆栈跟踪
     caller := zap.AddCaller()
     // 开启文档及行号
     development := zap.Development()
     // 设置初始化字段
     filed := zap.Fields(zap.String("serviceName", "serviceName"))
     // 构造日志
     logger := zap.New(core, caller, development, filed)
    
     logger.Info("log 初始化成功")
     logger.Info("无法获取网址",
     zap.String("url", "[http://www.baidu.com](http://www.baidu.com/)"),
     zap.Int("attempt", 3),
     zap.Duration("backoff", time.Second))
    }
    

    zap 优势及原理

    标准 log 没有日志分级。seelog 可分级,支持归档,比较灵活,但是利用反射,效率低。

    避免 GC: 对象复用

    zap 通过 sync.Pool 提供的对象池,复用了大量可以复用的对象,避开了 gc 这个大麻烦。

    内建的 Encoder: 避免反射

    标准库中的 json.Marshaler 提供的是基于类型反射的拼接方式,代价是高昂的。

    zap 选择了自己实现 json Encoder。 通过明确的类型调用,直接拼接字符串,最小化性能开销。

    level handler

    level handler 是 zap 提供的一种 level 的处理方式,通过 http 请求动态改变日志组件级别。

    相关文章

      网友评论

          本文标题:golang zaplog使用(转)

          本文链接:https://www.haomeiwen.com/subject/gwqxnltx.html