首页 > 解决方案 > Golang requestId 日志记录

问题描述

我正在使用 golang 编写一个 Web 应用程序。我是这种语言的新手。我正在尝试找到在 golang webapp 中记录 requestid 的最佳方法。我决定使用 go 的日志库(https://golang.org/pkg/log/)或 logrus(https://github.com/sirupsen/logrus)。在我看来,这两个都没有提供与 requestId 日志记录相关的任何内容。因此,为了生成 requestId 并在整个 api 流程中使用它,我现在已经采用以下方法

使用此处列出的任一 uid 生成库 ( https://golanglibs.com/search?q=id+generator&sort=top ) 生成 requestid。并在使用 http.Handler 包装器开始处理请求时将其设置在上下文(https://golang.org/pkg/context/ )中。并在我想登录的所有地方使用此上下文。

但要实现这一点,我需要将上下文对象传递给我需要记录某些内容的所有函数。这对我来说听起来不太好,因为我正在触摸所有函数的原型(即添加上下文参数)。有没有更好的方法来做到这一点?像 ThreadLocal 对象。并且可以从线程中的任何位置访问它,并且我们可以在任何需要的地方使用它来获取请求 ID?

标签: gologging

解决方案


Go 故意不支持等效的线程局部变量,因为它们经常被滥用和错误使用。代码不应依赖于哪个 goroutine 执行它。它还会限制一个函数启动更多的 goroutines(或者设置 goroutine 特定的上下文会使事情复杂化)。

相反,如果您的函数需要额外的信息(例如记录器),您必须明确地传递额外的信息。

当然,一个函数可能需要很多额外的信息,并且需要的东西可能会随着时间的推移而改变或“增长”,所以最好为这些额外的信息创建一个包装器,并传递这个额外的包装器值。如果您需要其他信息(例如,登录的用户 ID 或数据库连接或其他任何信息),您可以简单地将其添加到包装器中,而无需更改任何签名。

这个包装器是否是一个参数,或者你让你的包装器的函数方法(因此包装器将成为接收器)完全取决于你,并且只是一个实现细节。

查看相关问题:

为什么goroutine没有身份

Go 有类似 Java 的 ThreadLocal 的东西吗?


推荐阅读