为了账号安全,请及时绑定邮箱和手机立即绑定

Uber Zap Logger:如何在每个日志条目前面加上一个字符串

Uber Zap Logger:如何在每个日志条目前面加上一个字符串

Go
慕桂英4014372 2022-10-24 08:59:34
我将我的应用程序用作 SystemD 服务,并且需要在每条消息之前添加<LEVEL>JournalD 的入门级别,例如:<6> this is info<7> this is debug<4> this is warning否则,JournalD 将所有条目视为同一级别,我想使用其高级功能仅显示特定级别的日志。如何<6>使用 uber-zap 库在每个日志条目之前添加正确的级别标签(例如 Info it would be )?编辑:这是我的记录器配置的相关部分:    var config zap.Config    if production {        config = zap.NewProductionConfig()        config.Encoding = `console`        config.EncoderConfig.TimeKey = "" // no time as SystemD adds timestamp    } else {        config = zap.NewDevelopmentConfig()    }    config.DisableStacktrace = true    config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder // colors    config.OutputPaths = []string{"stdout"}
查看完整描述

1 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

您可以使用嵌入zapcore.Encoder.

嵌入编码器使您可以“免费”使用您现在拥有的相同配置实现所有方法。然后,您只能EncodeEntry使用您需要的附加逻辑来实现。

注意:Clone()如果您计划使用结构化日志记录,您仍然必须实施,例如logger.With(). 更多信息:为什么在 Uber Zap 中调用 logger.With 后自定义编码会丢失?

回到您的主要问题,这是一个工作示例;请参阅代码中的注释以获取更多说明:

type prependEncoder struct {

    // embed a zapcore encoder

    // this makes prependEncoder implement the interface without extra work

    zapcore.Encoder


    // zap buffer pool

    pool buffer.Pool

}


// implementing only EncodeEntry

func (e *prependEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {

    // new log buffer

    buf := e.pool.Get()


    // prepend the JournalD prefix based on the entry level

    buf.AppendString(e.toJournaldPrefix(entry.Level))

    buf.AppendString(" ")


    // calling the embedded encoder's EncodeEntry to keep the original encoding format 

    consolebuf, err := e.Encoder.EncodeEntry(entry, fields)

    if err != nil {

        return nil, err

    }


    // just write the output into your own buffer

    _, err = buf.Write(consolebuf.Bytes())

    if err != nil {

        return nil, err

    }

    return buf, nil

}


// some mapper function

func (e *prependEncoder) toJournaldPrefix(lvl zapcore.Level) string {

    switch lvl {

    case zapcore.DebugLevel:

        return "<7>"

    case zapcore.InfoLevel:

        return "<6>"

    case zapcore.WarnLevel:

        return "<4>"

    }

    return ""

}

稍后,您将构建一个带有自定义核心的记录器,该核心使用自定义编码器。您使用您现在使用的相同编码器初始化嵌入字段。您在下面看到的选项模仿了您当前拥有的选项。


package main


import (

    "go.uber.org/zap"

    "go.uber.org/zap/buffer"

    "go.uber.org/zap/zapcore"

    "os"

)


func getConfig() zap.Config {

    // your current config options

    return config

}


func main() {

    cfg := getConfig()


    // constructing our prependEncoder with a ConsoleEncoder using your original configs

    enc := &prependEncoder{

        Encoder: zapcore.NewConsoleEncoder(cfg.EncoderConfig),

        pool:    buffer.NewPool(),

    }


    logger := zap.New(

        zapcore.NewCore(

            enc,

            os.Stdout,

            zapcore.DebugLevel,

        ),

        // this mimics the behavior of NewProductionConfig.Build

        zap.ErrorOutput(os.Stderr), 

    )


    logger.Info("this is info")

    logger.Debug("this is debug")

    logger.Warn("this is warn")

}

测试运行输出(INFO 打印为蓝色,DEBUG 打印为粉红色,WARN 打印为黄色,根据您的zapcore.CapitalColorLevelEncoder):


<6> INFO        this is info

<7> DEBUG       this is debug

<4> WARN        this is warn


查看完整回答
反对 回复 2022-10-24
  • 1 回答
  • 0 关注
  • 245 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号