分享
  1. 首页
  2. 文章

聊聊golang的zap的NewProduction

go4it · · 764 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

文主要研究一下uber的zap的NewProduction。

golang的log有zaplogrus等,不过logrus现在已经处于维护状态。

实例

SugaredLogger

func main() {
 logger, _ := zap.NewProduction()
 defer logger.Sync() // flushes buffer, if any
 sugar := logger.Sugar()
 url := "https://abc.com"
 sugar.Infow("failed to fetch URL",
 // Structured context as loosely typed key-value pairs.
 "url", url,
 "attempt", 3,
 "backoff", time.Second,
 )
}

SugaredLogger比普通的结构化logging包快4-10倍

输出

{"level":"info","ts":1607095287.638658,"caller":"log-demo/zap_demo.go:14","msg":"failed to fetch URL","url":"https://abc.com","attempt":3,"backoff":1}

Logger

func main() {
 logger, _ := zap.NewProduction()
 defer logger.Sync()
 url := "https://abc.com"
 logger.Info("failed to fetch URL",
 // Structured context as strongly typed Field values.
 zap.String("url", url),
 zap.Int("attempt", 3),
 zap.Duration("backoff", time.Second),
 )
}

当对性能和类型安全都要求比较高的场景就使用Logger,它比SugaredLogger速度更快,但是它只支持结构化logging

输出

{"level":"info","ts":1607095675.5623732,"caller":"log-demo/zap_demo.go:25","msg":"failed to fetch URL","url":"https://abc.com","attempt":3,"backoff":1}

NewProduction

zap@v1.16.0/logger.go

func NewProduction(options ...Option) (*Logger, error) {
 return NewProductionConfig().Build(options...)
}

NewProduction内部执行NewProductionConfig().Build方法

NewProductionConfig

zap@v1.16.0/config.go

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"},
 }
}

NewProductionConfig方法按默认参数创建了Config,其中encoding为json,output为std

NewProductionEncoderConfig

zap@v1.16.0/config.go

func NewProductionEncoderConfig() zapcore.EncoderConfig {
 return zapcore.EncoderConfig{
 TimeKey: "ts",
 LevelKey: "level",
 NameKey: "logger",
 CallerKey: "caller",
 FunctionKey: zapcore.OmitKey,
 MessageKey: "msg",
 StacktraceKey: "stacktrace",
 LineEnding: zapcore.DefaultLineEnding,
 EncodeLevel: zapcore.LowercaseLevelEncoder,
 EncodeTime: zapcore.EpochTimeEncoder,
 EncodeDuration: zapcore.SecondsDurationEncoder,
 EncodeCaller: zapcore.ShortCallerEncoder,
 }
}

NewProductionEncoderConfig这里创建了zapcore.EncoderConfig

Build

zap@v1.16.0/config.go

func (cfg Config) Build(opts ...Option) (*Logger, error) {
 enc, err := cfg.buildEncoder()
 if err != nil {
 return nil, err
 }
 sink, errSink, err := cfg.openSinks()
 if err != nil {
 return nil, err
 }
 if cfg.Level == (AtomicLevel{}) {
 return nil, fmt.Errorf("missing Level")
 }
 log := New(
 zapcore.NewCore(enc, sink, cfg.Level),
 cfg.buildOptions(errSink)...,
 )
 if len(opts) > 0 {
 log = log.WithOptions(opts...)
 }
 return log, nil
}

Build方法执行cfg.buildEncoder()、cfg.openSinks()、zapcore.NewCore及New方法

New

zap@v1.16.0/logger.go

func New(core zapcore.Core, options ...Option) *Logger {
 if core == nil {
 return NewNop()
 }
 log := &Logger{
 core: core,
 errorOutput: zapcore.Lock(os.Stderr),
 addStack: zapcore.FatalLevel + 1,
 }
 return log.WithOptions(options...)
}
func NewNop() *Logger {
 return &Logger{
 core: zapcore.NewNopCore(),
 errorOutput: zapcore.AddSync(ioutil.Discard),
 addStack: zapcore.FatalLevel + 1,
 }
}

这里对于core为nil的返回的是NewNop,否则实例化Logger;NewNop返回的logger的core为zapcore.NewNopCore()

Logger

zap@v1.16.0/logger.go

type Logger struct {
 core zapcore.Core
 development bool
 name string
 errorOutput zapcore.WriteSyncer
 addCaller bool
 addStack zapcore.LevelEnabler
 callerSkip int
 onFatal zapcore.CheckWriteAction // default is WriteThenFatal
}

Logger定义了core、development、name、errorOutput、addCaller、addStack、callerSkip、onFatal属性

小结

zap.NewProduction()通过创建NewProductionEncoderConfig再Build出Logger,其中Logger的New方法主要设置了core、errorOutput、addStack属性

doc


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:go4it

查看原文:聊聊golang的zap的NewProduction

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
764 次点击
1 回复 | 直到 2025年04月30日 14:39:44
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏