【发布时间】: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 (!!) 将其转换为字符串,并将其用作信息消息。无论如何,消息应该始终是一个字符串,您不应该将任意数据记录为消息,这就是字段的用途。