英文:
looking for a call or thread id to use for logging
问题
我正在重新修改我们用golang编写的小型Web应用程序的日志记录。由于外部要求,日志记录已经被隔离在一个地方,这样我们以后可以潜在地切换到一个日志服务器。(不是我的主意 - 我保证....)尽管如此,我们现在能够记录常见的事物,比如日期/时间、行号、用户和大部分使用标准库和我们传递的用户/会话结构的消息。
但是 - 问题来了 - 在较低级别的方法中,为了记录日志而传递会话是一种浪费。所以我想找到其他方法来查找日志文件中的一个特定请求。我相信还有一些明显的方法我没有考虑到。
目前的想法有:
- Java日志框架可以打印出线程ID,在这种情况下也足够好。只是在golang中叫做其他的名字?
- 使用户/会话结构可在全局范围内访问。 (除非有一个线程可用作查找键,否则仍然需要传递会话ID。回到第一种想法。)
- 放弃并继续传递用户/会话结构。
- 仅在用户/会话结构可用时才记录错误,但行号可能不太准确。
我们在Web方面使用了gorilla的部分功能,除此之外主要使用标准库。
对此有什么建议和想法吗?
英文:
I am reworking the logging of our little web application written in golang. Due to external requirements logging has been isolated in one place so we can potentially switch in a logging server later on. (Not my idea - I promise....) Nevertheless we are now able to log the common things like date/time, line number, user and the message mostly using parts of the standard library and a user/session struct we are passing around.
But - and here comes the question - in lower level methods it is a waste to pass in the session just to get to the user name for the sake of logging. So I would like to find something else to use to find one specific request in the log files. I am sure there are something obvious I haven't thought of.
Ideas so far:
- Java logging frameworks can print out the thread id and that would be good enough in this case also. Just that it is called something else in golang?
- make the user/session struct thing accesible globally somehow. (Still need to pass the session id around unless there are a thread to use as lookup key. Back to idea number 1.)
- give up and pass the user/session struct around anyway.
- don't log errors on the lowest level but only when the user/session struct is available. The line number won't be that good though.
We are using parts of gorilla for web things and apart from that mostly the standard library.
Suggestions and ideas about this?
答案1
得分: 23
由于滥用的潜在风险很高,在Go语言中无法访问当前goroutine的标识符。这可能看起来很严格,但实际上保留了Go软件包生态系统的一个重要特性:无论您是否启动新的goroutine来执行某些操作,都没有关系。
也就是说,对于任何方法或函数F:
F()
几乎等同于:
done := make(chan struct{})
go func() {
defer close(done)
F()
}
<-done
(“几乎”是因为如果F发生恐慌,原始goroutine将无法捕获该恐慌)。
这也适用于日志记录-如果您使用当前goroutine来推断当前用户,那么任何启动新goroutine的代码都会破坏该假设,您的日志记录将不包含预期的信息。
您需要传递一些上下文。
英文:
Because of the high potential for abuse, there is no way to access an identifier for the current goroutine in Go. This may seem draconian, but this actually preserves an important property of the Go package ecosystem: <i>it does not matter if you start a new goroutine to do something</i>.
That is, for any method of function F:
F()
is almost exactly equivalent to:
done := make(chan struct{})
go func() {
defer close(done)
F()
}
<-done
(The "almost" comes from the fact that if F panics, the panic
will not be caught by the original goroutine).
This applies to logging too - if you were using the current goroutine
to infer the current user, any code that started a new goroutine
as above would break that assumption, and your logging
would not contain the expected information.
You'll need to pass around some kind of context.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论