【问题标题】:What's the proper way to use logger along with context?将记录器与上下文一起使用的正确方法是什么?
【发布时间】:2017-04-12 21:40:57
【问题描述】:

我正在用 Golang 构建一个 Web 服务器。你知道 Golang 有一个 context 包,它是 offically recommended 始终将上下文作为第一个参数传递。 context.Context 有一个 Value 方法来将变量保存在上下文中。

但是,大多数日志库还提供了一种继承记录器的方法,例如,使用来自其父级的字段创建子记录器。在logrus(或其他一些记录器,没关系)中,您可以创建一个logrus.Entry 并应用WithFields 来获取一个子记录器。

例如,当每个来自 request-id 的 HTTP 请求都附加时。我希望将它放在上下文中,并在每个日志中记录为一个字段。

那么,如何以正确的方式做到这一点?

谢谢!!

【问题讨论】:

  • 你有没有尝试过,还是只是要求我们为你做?
  • 虽然Context 可以提供执行上下文,但它可以做更多的事情,尤其是处理取消。为什么您认为Context 是处理派生记录器的最合适方式? (不是。)
  • 我做的和你说的差不多。我有一个中间件,它设置了一个 logrus.Entry 与会话和请求信息(url、request-id 等...)。然后我有一个我自己的日志 pkg,它带有一个函数,它接受一个上下文并返回一个 logrus.Entry,如果它在上下文中找到一个 logrus.Entry,它会使用它,如果不是,它会创建一个新的。
  • @Volker 这真的取决于。例如,在我的项目中,我们使用 logrus,为了在 ElasticSearch 中索引日志,我们希望在默认的“msg”字段之外设置 logrus.Fields,如 user_id。因此,一种更简洁的方法是当我们捕获user_id 并在请求的整个生命周期中通过在上下文中传递该条目来重用该条目时,在中间件中通过logrus.WithField 创建一个条目。通过这种方式,这个记录器实际上变成了一个特定的请求。

标签: logging go


【解决方案1】:

您可以从传入请求中获取request-id,然后使用上下文将request-id 传递给您正在调用的函数。 这是一个例子:https://medium.com/@cep21/how-to-correctly-use-context-context-in-go-1-7-8f2c0fafdf39。 对于日志记录:使用 std 日志库定义您自己的记录器

func CreateCustomLogger(requestId string) *log.Logger {
    defaultLoggingFlags := 
log.Ldate|log.Ltime|log.LUTC|log.Lmicroseconds|log.Lshortfile
    return log.New(os.Stderr, requestId + ": ", defaultLoggingFlags)
}

在你的功能中:

customLogger := CreateCustomLogger(requestId)
customLogger.Printf("Custom log message")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-10
    • 2013-01-02
    • 1970-01-01
    • 2020-08-27
    • 2020-07-10
    • 2020-09-29
    • 1970-01-01
    • 2012-05-12
    相关资源
    最近更新 更多