Golang logrus - 如何进行集中配置?

Golang logrus - how to do a centralized configuration?

我在 Go 应用程序中使用 logrus。我相信这个问题也适用于任何其他日志记录包(不提供基于外部文件的配置)。

logrus 提供设置各种配置的功能,例如SetOutput、SetLevel 等

与我需要从多个源进行日志记录的任何其他应用程序一样 files/packages,您似乎需要在每个文件中使用 logrus 设置这些选项。

有没有什么方法可以在一个中心位置的某个地方设置这些选项,以便在整个应用程序中共享。这样一来,如果我必须更改日志记录级别,我可以在一处完成并应用于应用程序的所有组件。

您不需要在每个文件中使用 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.)

这是我为我的应用程序找到的解决方案,它允许将字段添加到日志记录上下文。由于上下文基础字段的复制,它确实对性能有很小的影响。

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