go - 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?
解决方案
Go 故意不支持等效的线程局部变量,因为它们经常被滥用和错误使用。代码不应依赖于哪个 goroutine 执行它。它还会限制一个函数启动更多的 goroutines(或者设置 goroutine 特定的上下文会使事情复杂化)。
相反,如果您的函数需要额外的信息(例如记录器),您必须明确地传递额外的信息。
当然,一个函数可能需要很多额外的信息,并且需要的东西可能会随着时间的推移而改变或“增长”,所以最好为这些额外的信息创建一个包装器,并传递这个额外的包装器值。如果您需要其他信息(例如,登录的用户 ID 或数据库连接或其他任何信息),您可以简单地将其添加到包装器中,而无需更改任何签名。
这个包装器是否是一个参数,或者你让你的包装器的函数方法(因此包装器将成为接收器)完全取决于你,并且只是一个实现细节。
查看相关问题:
推荐阅读
- c# - 我可以从 Web 浏览器控制统一的独立应用程序吗?
- r - R - Logistic 和 Gompertz 曲线中的非线性最小平方误差
- c# - 将文件中的文本加载到列表框中
- javascript - 将 d3 x 轴(时间)缩放为零
- javascript - 使用烧瓶管理和 sqlalchemy;现在我正在尝试制作一个表格来添加/删除/编辑我的表格
- ios - 什么时候在 UIView 或 UIViewController 上调用“required init?(coder aDecoder: NSCoder)”?
- laravel - Laravel / PHPUnit:运行测试时没有模拟类
- sql - 在sybase中加入多个表
- c - 为什么 atmega32 只收到字符串的最后 16 个字符?
- java - UseConcMarkSweepGC 已被弃用,它的替代品是什么?