command: include default otel error handler for the cli#4975
command: include default otel error handler for the cli#4975laurazard merged 1 commit intodocker:masterfrom
Conversation
| func init() { | ||
| otel.SetErrorHandler(DefaultOTELErrorHandler) | ||
| } |
There was a problem hiding this comment.
I'm not a big fan of init funcs. Could we do this inside the main func instead?
Is DefaultOTELErrHandler necessary? Can't we do this instead
| func init() { | |
| otel.SetErrorHandler(DefaultOTELErrorHandler) | |
| } | |
| func init() { | |
| otel.SetErrorHandler(otel.ErrorHandlerFunc(handleOTELError)) | |
| } |
There was a problem hiding this comment.
Yeah, also not a huge fan of init. If we must keep this, we could even consider inlinining handleOTELError;
| func init() { | |
| otel.SetErrorHandler(DefaultOTELErrorHandler) | |
| } | |
| func init() { | |
| otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) { | |
| logrus.WithError(err).Debug("otel error") | |
| })) | |
| } |
But I'd also be more in favour of having this up to the consumer to decide (and set the error-handler in their main or elsewhere).
There was a problem hiding this comment.
+1 to not having this as an init, unless we have strong arguments for it.
(but if we must do it that way, this is one of the less awful uses of init and I'd be okay with it 😅)
There was a problem hiding this comment.
The main reason is because this handler would also be standard for any plugins and I don't want to necessarily be too invasive in requiring those plugins to know to set the error handler.
I'm not a big fan of the init. I'll see if I can find a more common place to put this code.
The primary reason for DefaultOTELErrorHandler is because I also plan that this error handler is used by plugins too and I didn't want to leak the implementation. I can create the variable though and inline the function though since that won't really leak anything.
There was a problem hiding this comment.
Yeah, so I was looking at this from some perspectives;
- it's setting some defaults in an
init, which may beccome part of imported code in other code-bases - the default is to set up a debug-logger; performing logging as part of library code is often considered a bit of a "no-no"
- I'm also looking a the
logrusimport in this case, as I know we're trying to move away from hard-coding logrus as implementation for logging; in the moby code-base we started to use thecontainerd/logmodule (https://github.com/containerd/log), which is currently a wrapper around logrus, but could allow using that abstraction to move to a different implementation, as well as allows for implementations to attach a logger through the context (unfortunately a context-logger doesn't look to be a real option here due to the signature).
There was a problem hiding this comment.
This logging is meant to tie in with the github.com/docker/cli/cli/debug package which explicitly uses logrus for the debugging. What if I were to move the error handler to there, remove the init() function, and invoke otel.SetErrorHandler on both the runDocker function and inside of one of the plugin packages?
There was a problem hiding this comment.
Another option I was thinking about here could be something like this:
- create an ad-hoc func (eg
setDefaultOtelErrorHandler) for setting this error handler instead of init, and make sure it only executes once; - call this handler in both our "provider constructor" funcs, so:
- in
func (cli *DockerCli) MeterProvider(..); - and in
func (cli *DockerCli) TracerProvider(..)
- in
Tiny bit of repetition, but it'd still be transparent to plugins as long as they actually use one of the given providers, and we can avoid the init() func which would be run even when no other otel bits are being used.
WDYT?
There was a problem hiding this comment.
I'm not the biggest fan of registering these with the provider constructors. It seems like invoking a function that returns a non-global value shouldn't also modify a global error handler.
I did a bit of changes and moved the error handler to the debug package that specifically uses logrus so it's easier to find and change whenever that part gets refactored. I also changed the SetErrorHandler call to be invoked from the plugin.Run function and inside of cmd/docker/main.go directly so it's no longer in an init() function. I think this might solve the problems we were discussing although I don't know if these are the best places for these calls.
5acfb69 to
22a9635
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #4975 +/- ##
==========================================
- Coverage 60.99% 60.95% -0.04%
==========================================
Files 295 295
Lines 20621 20642 +21
==========================================
+ Hits 12578 12583 +5
- Misses 7149 7163 +14
- Partials 894 896 +2 |
|
|
||
| func handleOTELError(err error) { | ||
| logrus.WithError(err).Debug("otel error") | ||
| } |
There was a problem hiding this comment.
I think this is no longer used in the last iteration, correct?
There was a problem hiding this comment.
Correct. Let me remove it.
This adds a default otel error handler for the cli in the debug package. It uses logrus to log the error on the debug level and should work out of the box with the `--debug` flag and `DEBUG` environment variable. Signed-off-by: Jonathan A. Sternberg <[email protected]>
22a9635 to
8f45f14
Compare
krissetto
left a comment
There was a problem hiding this comment.
i'm overall ok with this. if we ever do decide to move to using the containerd/log module mentioned, we can re-think these few lines
- What I did
This adds a default otel error handler for the cli in the debug package.
It uses logrus to log the error on the debug level and should work out
of the box with the
--debugflag andDEBUGenvironment variable.- How I did it
Created a function for handling the error that logs the message to
logrusand registered it with this type: https://pkg.go.dev/go.opentelemetry.io/otel#ErrorHandlerFunc- How to verify it
Without this change, the output is:
- Description for the changelog
Include otel-related errors in debug logs.
- A picture of a cute animal (not mandatory but encouraged)