-
Notifications
You must be signed in to change notification settings - Fork 572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Confusing behavior with context.Context integration #80
Comments
The rational is that a request context should only have a single instance of the logger so your requests can add fields that are visible to parent middleware for instance. This is particularly useful with the This is also better for performance. Storing a new instance of the logger in the context for each update would end up with a pretty narrow context tree that would impact lookup time for every |
Thanks. I think I understand the reasoning here, but I'm now confused by the difference between To give a more concrete example, I have an application that responds to a GitHub webhook and performs an action on every open pull request in the repository. In the handler, I loop over the open PRs and call In your view, is it better to pass the modified logger explicitly as an argument or re-add the necessary fields at each level instead of passing a modified context? |
The What I can do though, is only updating the existing pointer if the currently stored logger is the same as the one you are trying to store. This way, if you copy the logger instead of calling |
Current implementation stores a copy of the logger as a pointer and update its content, which is now unecessary since the introduction of WithContext. The new WithContext now takes the pointer and store it in the context if none is stored already or if the last one stored is a different pointer. This way it is still possible to update the context of a logger stored in the context, but it is also possible to store a copy of the logger in a sub-context. Fix #80
Please review #81. |
Current implementation stores a copy of the logger as a pointer and update its content, which is now unecessary since the introduction of WithContext. The new WithContext now takes the pointer and store it in the context if none is stored already or if the last one stored is a different pointer. This way it is still possible to update the context of a logger stored in the context, but it is also possible to store a copy of the logger in a sub-context. Fix #80
#81) Current implementation stores a copy of the logger as a pointer and update its content, which is now unecessary since the introduction of WithContext. The new WithContext now takes the pointer and store it in the context if none is stored already or if the last one stored is a different pointer. This way it is still possible to update the context of a logger stored in the context, but it is also possible to store a copy of the logger in a sub-context. Fix #80
First, thanks for this library; the API is easy to use and the
hlog
package is a nice bonus.We recently started using
zerolog.Ctx
and(Logger) WithContext
and were surprised to find thatWithContext
modified the context instead of creating a copy of the context with the modified logger. This means that when we set fields in functions that should only be visible to the functions they call, those fields are instead included on all future log message.This program demonstrates the issue (it happens more naturally in HTTP handlers):
I did some digging in the history and it seems like this was added in 6a6144a to support the
hlog
functions, which are more efficient when they can modify the existing logger and can reasonably expect to exist at the top of the middleware stack.However, at some later point, all those functions switched to use
(*Logger) UpdateContext
, which achieves the same thing. It seems like(Logger) WithContext
is now only used to set the initial logger.I think this behavior goes against the expectations of
context.Context
(modifications are not visible to functions that were not passed the modified context) and makes it difficult to add new logging fields only for sections of a request handler.Is it possible that
(Logger) WithContext
could be reverted to always return a copy of the context if the logger is updated?If not, do you have recommendations on how to work around this behavior? We're currently going to write our own functions to interact with the context, but it would be great if we could stick with the library functions.
The text was updated successfully, but these errors were encountered: