版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | http://vearne.cc

1. 前言

uber开源的高性能日志库zap, 除了性能远超logrus之外,还有很多诱人的功能,比如支持数据采样、支持通过HTTP服务动态调整日志级别。

前些天有同事问我,zap默认打印的日志格式,我不喜欢,可否自定义一下。
这个是日志库应该有的功能,zap怎么可能不支持。

下面我们来谈谈如何自定义日志格式,在zap中,它被称为Encoder, 在日志库中logrus,被做Formatter

2. 默认格式

目前 zap只支持2种日志格式

2.1 console

1.5392310605133479e+09  info    golab/test_zap.go:34    Info log    {"name": "buick2008", "age": 15}

2.2 json

{"level":"info","ts":1539234945.009923,"caller":"golab/test_zap.go:34","msg":"Info log","name":"buick2008","age":15}

3. 实现

1) 为了实现自定义的Encoder 需要实现
zapcore.Encoder
zapcore.PrimitiveArrayEncoder
所定义的接口

大部分接口实现可以照抄zapcore.jsonEncoder的代码实现
真正需要改动的是

EncodeEntry(ent zapcore.Entry, fields [] zapcore.Field) (*buffer.Buffer, error)

2) 注册Encoder

    // 注册Encoder
    zap.RegisterEncoder("console2", MyEncoding)

用法示例

package main

import (
    "fmt"
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
    "time"
    "github.com/vearne/golab/myencoder"
)


func MyEncoding(config zapcore.EncoderConfig) (zapcore.Encoder, error) {
    return myencoder.NewConsole2Encoder(config, true), nil
}


func main() {
    // 注册一个Encoder
    zap.RegisterEncoder("console2", MyEncoding)

    // 默认是Info级别
    logcfg := zap.NewProductionConfig()
    // 启用自定义的Encoding
    logcfg.Encoding = "console2"

    logger, err := logcfg.Build()
    if err != nil {
        fmt.Println("err", err)
    }

    defer logger.Sync()
    for i := 0; i < 3; i++ {
        time.Sleep(1 * time.Second)
        logger.Info("some message", zap.String("name", "buick2008"),
            zap.Int("age", 15))
    }
}

打印出的日志效果

"level": "info", "caller": "golab/test_zap.go:34", "msg": "some message"$$$ "name": "buick2008", "age": 15

vearne/golab
主要涉及的文件
test_zap.go
console2_encoder.go

注意 由于时间原因,笔者并没有完整实现
zapcore.Encoder
zapcore.PrimitiveArrayEncoder
所定义的接口,请勿直接在生产环境使用

推荐阅读


如果我的文章对你有帮助,你可以给我打赏以促使我拿出更多的时间和精力来分享我的经验和思考总结。

微信支付码

4 对 “玩转高性能日志库zap(4)–自定义日志格式”的想法;

    1. config := zap.NewProductionConfig()
      DefaultLogger, _ = config.Build()
      

      其中的Sampling就是设置采样的

      func NewProductionConfig() Config {
          return Config{
              Level:       NewAtomicLevelAt(InfoLevel),
              Development: false,
              Sampling: &SamplingConfig{
                  Initial:    100,
                  Thereafter: 100,
              },
              Encoding:         "json",
              EncoderConfig:    NewProductionEncoderConfig(),
              OutputPaths:      []string{"stderr"},
              ErrorOutputPaths: []string{"stderr"},
          }
      }
      
          // Sampling sets a sampling policy. A nil SamplingConfig disables sampling.
          Sampling *SamplingConfig `json:"sampling" yaml:"sampling"`
      

wj进行回复 取消回复

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据