【问题标题】:looking for a call or thread id to use for logging寻找用于记录的调用或线程 ID
【发布时间】:2013-10-07 13:25:00
【问题描述】:

我正在修改我们用 golang 编写的小型 Web 应用程序的日志记录。由于外部要求,日志记录已被隔离在一个地方,因此我们以后可能会切换到 日志记录服务器。 (不是我的想法——我保证......)不过,我们现在能够记录常见的东西,比如日期/时间、行号、用户和消息,主要使用标准库的一部分和我们传递的用户/会话结构大约。

但是 - 问题来了 - 在较低级别的方法中,为了记录而传递会话只是为了获取用户名是一种浪费。所以我想找点别的东西来在日志文件中找到一个特定的请求。我确信有一些我没有想到的显而易见的事情。

目前的想法:

  • Java 日志框架可以打印出线程 ID,这在这种情况下也足够了。只是它在golang中被称为别的东西吗?
  • 以某种方式使用户/会话结构可以全局访问。 (除非有线程用作查找键,否则仍需要传递会话 ID。回到想法 1。)
  • 无论如何都要放弃并传递用户/会话结构。
  • 不要在最低级别记录错误,但仅在用户/会话结构可用时才记录。不过行号不会那么好。

我们将部分 gorilla 用于网络事物,除此之外主要是标准库。

对此有何建议和想法?

【问题讨论】:

  • 你没有真正的选择:你必须在某种程度上将引用传递给你的用户(显式地或通过闭包),没有 goroutine id 这样的东西。
  • 您是否考虑过使用类似 expvar 的东西? (golang.org/pkg/expvar) “包 expvar 为公共变量提供标准化接口,例如服务器中的操作计数器。它通过 HTTP 以 JSON 格式在 /debug/vars 公开这些变量。”可以帮助获得全球可访问的统计数据。
  • 不——有趣的包。不知道它对我有什么帮助 - 我仍然需要一些东西来解决这个问题。某种钥匙?对吗?

标签: logging go


【解决方案1】:

由于滥用的可能性很大,在 Go 中无法访问当前 goroutine 的标识符。这可能看起来很苛刻,但这实际上保留了 Go 包生态系统的一个重要属性:你是否启动一个新的 goroutine 来做某事并不重要

即对于函数F的任意方法:

F()

几乎完全等同于:

done := make(chan struct{})
go func() {
   defer close(done)
   F()
}
<-done

(“几乎”来自这样一个事实,即如果 F 恐慌,恐慌 不会被原来的 goroutine 捕获)。

这也适用于日志记录——如果你使用的是当前的 goroutine 推断当前用户,任何启动新 goroutine 的代码 如上所述将打破该假设,并且您的日志记录 不会包含预期的信息。

您需要传递某种上下文。

【讨论】:

  • 感谢您的解释。这很有意义。我怀疑我会传递上下文,但不会一直传递下去。我认为如果检测到的问题仅对上下文有意义,我们将添加额外的日志记录。通过这种方式,代码将保持相当干净。
  • 恕我直言,“滥用的可能性很高”有点可疑。它首先需要枚举 Go 例程。
  • @rog:我在this blog post about logging中引用了这个答案的部分内容。
  • 不是说golang sn-p相当于函数Fcall,应该是go func() { ...}()吧?在末尾注明()。 (≖_≖)
  • 在查看日志行时有 100% 的正当理由需要知道 go 线程,因为混合的日志行会混淆逻辑。大多数人通过他们在线程中使用的结构上的某种唯一 id 来解决这个问题。除非该语言提供完整的线程安全,否则是否在线程中运行某些东西很重要,任何意识形态立场都不会改变这一点。
猜你喜欢
  • 1970-01-01
  • 2023-04-07
  • 2010-10-15
  • 1970-01-01
  • 1970-01-01
  • 2016-03-01
  • 1970-01-01
  • 2018-07-27
  • 2016-09-21
相关资源
最近更新 更多