-
Notifications
You must be signed in to change notification settings - Fork 83
feat: Make logger a configurable struct member for stub #239
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
base: main
Are you sure you want to change the base?
feat: Make logger a configurable struct member for stub #239
Conversation
9f44c11 to
c679937
Compare
|
Could you expand on your use case here? How would you like to customize logging behavior in a way that is unsupported by the existing logger? Edit: I see the dranet PR mentioned above. CC @klihub what are your thoughts? |
|
(Feel free to point out if there's an already existing way on how this can be achieved, but I'll share what I interpret here) My understanding is that it likely has always been the intention to let logger be customizable, given NRI package exposes this Set function: Lines 37 to 40 in 9b8befa
But unfortunately the "stub" package already builds it's own logger at a global scope, thereby not allowing the library users an opportunity to even make use of the Lines 190 to 192 in 9b8befa
The logs that are generated currently by this library have this format (derived from logrus): Application using klog as their logger have this default format, as an example. This difference in the log format causes implications on how things like log severity are interpreted. |
|
@gauravkghildiyal Wouldn't it be simpler to allow setting the package global logger in the stub from the outside? That would also have the benefit that if we ever add logging to stub package functions which don't have a receiver (IOW, are not stub.Stub 'member' functions) these would log consistently with the rest, including Stub instances. So something like this: // SetLogger sets the logger used to log messages internally generated by the stub package.
func SetLogger(l nrilog.Logger) nrilog.Logger {
old := log
log = l
return old
}
// GetLogger returns the current logger user by the stub package.
func GetLogger() nrilog.Logger {
return log
} |
@chrishenzie My comment (although not related to dranet in any way) is that in most cases when I used such a (type-scoped) logger as proposed in this PR, I regretted it later and eventually changed it to package-scoped instead, because sooner or later I ended up in a situation where I wanted/needed to log from a non-type-scoped function but had no logger, and in some cases the context was such that this could not be worked around by turning the functions into an artificially type-scoped one just to have access to the logger. Hence my comment for the alternative approach above. |
|
@pohly had to go through this recently with all the changes in klog and context logging in kubernetes, I think his experience can be very valuable, Patrick can you give us your opinion on this matter? what is the best way to plumb a custom logger in a library? |
This is tempting, but it is better to resist the temptation. It makes the assumption that there's only going to be a single log output stream for the entire package in a program at any given time. This prevents running unit tests in parallel with per-test log output. I don't know about this stub that is being discussed here, but is it really safe to assume that no downstream consumer of the package has a need to run two instances at the same time in their program? It is very unfortunate that klog by design has a global per-program logger. I wish we hadn't. kubernetes/enhancements#3077 is about reducing it's usage. |
|
|
||
| registrationTimeout: DefaultRegistrationTimeout, | ||
| requestTimeout: DefaultRequestTimeout, | ||
| logger: nrilog.Get(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gauravkghildiyal I think it would also make sense to add a WithLogger(nrilog.Logger) Option option which would allow setting the used logger with a stub.Option.
That's true and is a valid point. IOW... no, it wouldn't be safe to assume that there would be only ever a single instance in a single program. Plus, right now we only ever internally generate log messages from a type-instance context, never from a package global context. And if we ever need to start doing that, we can always add a functions for setting that logger, too. |
Or design those functions so that the caller can pass in a logger. It's more explicit that way. This works best for functions which accept a |
|
The two are interoperable: apps can pass a |
Previously, the stub package used a global logger instance, making it difficult for applications using the stub as a library to customize logging behavior. Co-authored-by: Krisztian Litkey <krisztian.litkey@intel.com> Signed-off-by: Gaurav Ghildiyal <gauravkg@google.com> Signed-off-by: Krisztian Litkey <krisztian.litkey@intel.com>
c679937 to
08a891a
Compare
Previously, the stub package used a global logger instance, making it difficult for applications using the stub as a library to customize logging behavior, by using
nrilog.Set():nri/pkg/log/log.go
Lines 37 to 40 in 9b8befa