我正在使用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包装器处理请求时将其设置在context(https://golang.org/pkg/context/)中。并在我想登录的所有地方使用此上下文。
但是要实现这一点,我需要将上下文对象传递给需要记录某些内容的所有函数。这对我来说听起来不好,因为我接触了所有函数的原型(即添加上下文参数)。 有什么更好的方法吗?类似于ThreadLocal对象。可以从线程中的任何位置访问它,并且可以使用它在需要的任何地方获取请求ID?
答案 0 :(得分:5)
故意地Go不支持等同于线程局部变量,因为它们经常被滥用和错误使用。代码不应该依赖于哪个goroutine执行它。这样做还会限制函数启动更多的goroutine(或者使设置goroutine特定的上下文变得复杂)。
相反,如果您的函数需要额外的信息(例如记录器),则必须将额外的信息显式传递给他们。
当然,一个函数可能需要许多额外的信息,并且随着时间的流逝,所需的东西可能会更改或“增长”,因此最好是为此类额外的信息创建一个包装器,并传递此单个额外的包装器值。如果您需要其他信息(例如,已登录的用户ID或数据库连接或其他任何信息),则只需将其添加到包装程序中,而不必更改任何签名。
此包装器是一个参数,还是您使包装器的函数方法(因此包装器将成为接收器)完全取决于您,并且仅是实现细节。
查看相关问题:
答案 1 :(得分:0)
我不喜欢有些人一直这样跟我说:
<块引用>ThreadLocal
是坏的/危险的/被滥用的。Golang
不需要 goroutine 局部变量。Context
。我只想像过去几年使用 Golang
那样使用 C++/Java/...
。
所以,我创建了一个新库,将 ThreadLocal
引入 Golang
。