我在Go应用程序中使用logrus。我相信这个问题也适用于任何其他日志包(它不提供基于外部文件的配置)。
logrus提供了设置各种配置的功能,例如: SetOutput,SetLevel等。
与我需要从多个源文件/包进行日志记录的任何其他应用程序一样,您似乎需要使用logrus在每个文件中设置这些选项。
有没有办法在中心位置设置这些选项,以便在整个应用程序中共享。这样,如果我必须进行日志记录级别更改,我可以在一个地方执行此操作并应用于应用程序的所有组件。
答案 0 :(得分:20)
您无需使用Logrus在每个文件中设置这些选项。
您可以将Logrus导入为log
:
import log "github.com/Sirupsen/logrus"
然后像log.SetOutput()
这样的函数只是函数并修改全局记录器并应用于包含此导入的任何文件。
您可以创建一个包全局log
变量:
var log = logrus.New()
然后像log.SetOutput()
这样的函数是方法并修改你的包全局。如果您的程序中有多个软件包,这是一个尴尬的IMO,因为它们中的每一个都有不同的记录器,具有不同的设置(但这可能对某些用例很有用)。我也不喜欢这种方法,因为它会混淆goimports
(它会想要将log
插入到您的导入列表中。)
或者您可以创建自己的包装器(这就是我所做的)。我有自己的log
包,其中包含logger
var:
var logger = logrus.New()
然后我创建顶级函数来包装Logrus:
func Info(args ...interface{}) {
logger.Info(args...)
}
func Debug(args ...interface{}) {
logger.Debug(args...)
}
这有点单调乏味,但允许我添加特定于我的程序的功能:
func WithConn(conn net.Conn) *logrus.Entry {
var addr string = "unknown"
if conn != nil {
addr = conn.RemoteAddr().String()
}
return logger.WithField("addr", addr)
}
func WithRequest(req *http.Request) *logrus.Entry {
return logger.WithFields(RequestFields(req))
}
所以我可以做以下事情:
log.WithConn(c).Info("Connected")
(我计划将来将logrus.Entry
打包到我自己的类型中,以便我可以更好地链接这些;目前我无法调用log.WithConn(c).WithRequest(r).Error(...)
,因为我无法添加WithRequest()
到logrus.Entry
。)
答案 1 :(得分:1)
这是我为我的应用程序提供的解决方案,它允许向日志记录上下文添加字段。由于复制了上下文基本字段,它确实会对性能产生很小的影响。
package logging
import (
log "github.com/Sirupsen/logrus"
)
func NewContextLogger(c log.Fields) func(f log.Fields) *log.Entry {
return func(f log.Fields) *log.Entry {
for k, v := range c {
f[k] = v
}
return log.WithFields(f)
}
}
package main
import (
"logging"
)
func main {
app.Logger = logging.NewContextLogger(log.Fields{
"module": "app",
"id": event.Id,
})
app.Logger(log.Fields{
"startTime": event.StartTime,
"endTime": event.EndTime,
"title": event.Name,
}).Info("Starting process")
}