【问题标题】:Zap logger source lineZap logger 源代码行
【发布时间】:2020-04-16 09:23:28
【问题描述】:

如何使用 zap 打印准确的源代码行。我创建了一个存储变量(zap logger)的包。该全局变量将在该包中的函数内部调用。 问题是它没有打印实际的调用者,而是调用记录器在记录器包内调用内部函数的位置。这是我的代码:

package log

import (
    zap "go.uber.org/zap"
)

var logger        *zap.Logger

func Init() {
    logger,_ = zap.NewDevelopment()
}

func Info(msg interface{}) {
    if v,ok := msg.(string); ok {
        logger.Info(v) // when I called this function it always print the caller from this line, not the caller outside who actually called this function.
    } else {
        logger.Info(fmt.Sprintf("%v",msg))
    }
}

为实际调用者打印源行值的解决方法是什么?

【问题讨论】:

  • zap 的主要思想之一是减少分配并避免空接口。您的 Info 函数违反了 zap 的全部目的。
  • 您能详细说明一下吗? @Volker
  • 那么我唯一需要做的就是使用字符串而不是接口?,好的。
  • 除了接受的答案外,您还可以使用通用配置选项:github.com/uber-go/zap/blob/master/options.go#L104 / AddCallerSkip
  • 如果您了解 zap 的设计,他们会尝试使其类型安全,并在记录某些内容时尽量减少分配。您的 Info 函数获取传递的任何内容,将其包装在 interface{} 值中,检查该值,如果尚未通过 fmt.Sprintf (!!) 将其转换为字符串,并将其用作信息消息。无论如何,消息应该始终是一个字符串,您不应该将任意数据记录为消息,这就是字段的用途。

标签: go logging go-zap


【解决方案1】:

使用runtime 来电者。

import "runtime"

// call below line inside your Info function.
pc, src, line, ok := runtime.Caller(1)

src 和 line 是你需要的。

【讨论】:

    【解决方案2】:
    var (
        //APP_ENV for config
        APP_ENV = "APP_ENV"
    )
    
    func init() {
        BuildLogger(os.Getenv(APP_ENV))
    }
    
    // BuildLogger builds log config
    func BuildLogger(env string) {
        var outputPaths []string
        var level zapcore.Level
    
        if env == "development" || env == "" {
            outputPaths = []string{"stdout"}
            level = zapcore.DebugLevel
        } else if env == "production" {
            outputPaths = setOutputPaths()
            level = zapcore.InfoLevel
        }
    
        config = zap.Config{
            Level:       zap.NewAtomicLevelAt(level),
            Development: false,
            Sampling: &zap.SamplingConfig{
                Initial:    100,
                Thereafter: 100,
            },
            Encoding:         "json",
            EncoderConfig:    zap.NewProductionEncoderConfig(),
            OutputPaths:      outputPaths,
            ErrorOutputPaths: []string{"stderr"},
        }
    
        logger, err := config.Build(zap.AddCallerSkip(1))
        if err != nil {
            panic(err)
        }
    
        log = logger.Sugar()
    }
    

    这是我的记录器配置。添加logger, err := config.Build(zap.AddCallerSkip(1))这一行并工作,调用者改变了。

    【讨论】:

      猜你喜欢
      • 2020-02-08
      • 2018-11-28
      • 2019-06-27
      • 2022-12-09
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 2015-01-25
      • 2021-09-25
      相关资源
      最近更新 更多