首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Uber Zap Logger:如何用字符串在每个日志条目前面添加

Uber Zap Logger:如何用字符串在每个日志条目前面添加
EN

Stack Overflow用户
提问于 2021-12-26 19:12:14
回答 1查看 2.1K关注 0票数 4

我正在使用我的应用程序作为SystemD服务,并且需要为JournalD添加一个入门级<LEVEL>,例如:

代码语言:javascript
复制
<6> this is info
<7> this is debug
<4> this is warning

否则,JournalD将所有条目处理为相同的级别,我希望使用它的高级功能只显示一定级别的日志。

如何使用uber-zap库为每个日志条目加上正确的级别标签(比如,对于信息,它将是<6>)?

编辑:这是我的记录器配置的相关部分:

代码语言:javascript
复制
    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"}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-27 07:52:27

您可以使用嵌入zapcore.Encoder的自定义编码器。

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

注意:如果您计划使用结构化日志记录(例如logger.With() ),则仍然需要实现Clone()。更多信息:Why custom encoding is lost after calling logger.With in Uber Zap?

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

代码语言:javascript
复制
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 ""
}

稍后,您将使用自定义编码器构造具有自定义核心的记录器。您使用现在使用的相同的编码器初始化嵌入式字段。下面看到的选项模拟了当前的选项。

代码语言:javascript
复制
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以蓝色打印,调试用粉红色,警告以黄色,如您的zapcore.CapitalColorLevelEncoder):

代码语言:javascript
复制
<6> INFO        this is info
<7> DEBUG       this is debug
<4> WARN        this is warn
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70489167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档