在公司内部见过各种各样的日志库,其中很多是基于zap开发的,但是看源码觉得有些过于复杂,其实要自定义zap的日志格式还是挺容易的,只要自己实现Encoder接口,如果合理利用zap库已有的实现,可以做到只写EncodeEntry方法。下面就以在console格式的日志上加上日志颜色为例进行简单说明。
参考默认console的实现
type consoleEncoder struct {*jsonEncoder}func NewConsoleEncoder(cfg EncoderConfig) Encoder {if cfg.ConsoleSeparator == "" {// Use a default delimiter of '\t' for backwards compatibilitycfg.ConsoleSeparator = "\t"}return consoleEncoder{newJSONEncoder(cfg, true)}}
如何给终端添加颜色
在linux终端中添加颜色的方式非本文重点,感兴趣的可以自行搜索,这里简单说明下配置方式及代码
// 颜色设置规则:`\033[字体颜色;背景色;字体效果m`,因为代码都不一样,故其实3种效果的顺序并不重要,只要用`;`分割即可,如果没变化就不填// 1. 字体颜色代码(30~37):30-黑色,31-红色,32-绿色,33-黄色,34-蓝色,35-紫红色,36-青蓝色,37-白色// 2. 背景颜色代码(40~47):40-黑色,41-红色,42-绿色,43-黄色,44-蓝色,45-紫红色,46-青蓝色,47-白色// 3. 字体效果代码(1~8):1-加粗,4-下划线,5-闪烁,7-反色,8-不可见// 4. 0用于重置效果// 示例:辣眼睛的绿底红字加粗:\033[32;42;1mconst (green = "\033[32m"yellow = "\033[33m"red = "\033[31m"reset = "\033[0m")var colorMap = map[zapcore.Level]string{zapcore.InfoLevel: green,zapcore.WarnLevel: yellow,zapcore.ErrorLevel: red,}
重写EncodeEntry方法
type colorConsoleEncoder struct {*zapcore.EncoderConfigzapcore.Encoder}// NewColorConsole 新建ColorConsolefunc NewColorConsole(cfg zapcore.EncoderConfig) (enc zapcore.Encoder) {return colorConsoleEncoder{EncoderConfig: &cfg,// 使用默认的的 ConsoleEncoder,可以避免重写一遍 ObjectEncoder 等接口// PS:ConsoleEncoder 其实也是利用了自带的 JSONEncoderEncoder: zapcore.NewConsoleEncoder(cfg),}}// EncodeEntry 重写 ConsoleEncoder 的 EncodeEntryfunc (c colorConsoleEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (buff *buffer.Buffer, err error) {buff2, err := c.Encoder.EncodeEntry(ent, fields) // 利用zap已有的实现if err != nil {return nil, err}buff = _pool.Get()buff.AppendString(colorMap[ent.Level]) // 设置颜色buff.AppendString(buff2.String())buff.AppendString(reset) // 重置return buff, err}
注册Encoder
注册Encoder,这样我们就能像配置json、console一样修改了
const (// ColorConsole 带颜色的consoleColorConsole = "color_console")func init() {_ = zap.RegisterEncoder(ColorConsole, func(config zapcore.EncoderConfig) (zapcore.Encoder, error) {return NewColorConsole(config), nil}) // 注册Encoder}
测试效果
写个测试用例看下效果
func TestNewColorConsole(t *testing.T) {cfg := zap.NewDevelopmentConfig()cfg.Encoding = ColorConsolecfg.DisableStacktrace = true // 不打堆栈,不然Warn及以上等级会打印堆栈logger, _ := cfg.Build()logger.Debug("测试Debug", zap.Int64("i", 1))logger.Info("测试Info", zap.Int64("i", 2))logger.Warn("测试Warn", zap.Int64("i", 3))logger.Error("测试Error", zap.Int64("i", 4))}
