-
Notifications
You must be signed in to change notification settings - Fork 28
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
numeric verbosity and configurable error field name #37
Conversation
@serathius: do you agree with the decision to use -1 for Logger.Error and -2 for panics? I have tested this updated zapr in Kubernetes (see kubernetes/kubernetes#104103) and it passes the existing tests with only minor changes to those tests (v=-1/-2, additional fields, different (correct?) source location for panics). |
I don't think we should mix verbosity and log type (info vs error). My understanding is that logr uses Info and Error to allow attaching additional information like stack trace. https://github.com/go-logr/logr/blob/622c97b4eb90a99cc628f4773662eb0015ce0f2a/logr.go#L45-L47 I don't treat Error as log more important then Info with V(0). Both are logged always and should be always useful to operator. Difference is that administrator might prefer to send Errors to error tracking systems like Sentry. As for dPanic, they should not be treated as panics with higher verbosity. dPanic method is way for zap to report internal errors that need to be handled more carefully. It's different call path as you cannot just log internal log as a normal log, that would lead to recursion :P. I would also not treat them as more critical than errors reported by caller. Refering to @thockin to get authoritative response. |
Errors have a different verbosity semantic than info messages. They always get logged regardless of the current verbosity level of the logger, in contrast to info messages: https://github.com/go-logr/logr/blob/622c97b4eb90a99cc628f4773662eb0015ce0f2a/logr.go#L206-L210 Logging an error with v=5 therefore doesn't make sense to me.
Both are logged only if the threshold is >=0. Theoretically a logger could also be configured with -1 as threshold and then only log errors, but not V(0) info messages. Therefore I think that one can argue that errors have either "higher" verbosity than info messages or no verbosity at all. Panics are yet another thing. They are not errors encountered by the application nor info messages. Therefore it seemed useful to log them differently. We can also always log them without numeric verbosity. |
As Error can also be used with verbosity, it would be good to agree on how it should work. Some examples about my expectation: For Info with verbosity
Should write:
Same with Error
Should write:
They are exactly the same, difference is that we might decide to add a flag to enable adding stacktrace information to |
You can write code like that, but semantically |
That was possible in logr v0.4.0, but is not possible anymore with v1.0.0 because |
... and is intended to work. Looking at the API documentation for |
FWIW, I don't care too much about |
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.
Why print a "lvl" on errors? Using negative values feels like a hack. Would it be better to have 2 keys, like "is-error" and "lvl" or something?
I don't follow the dpanic - how would a user get dpanic into the LogSink in the first place if we map log.Error() to zap.ErrorLevel?
zapr.go
Outdated
// each log message. The empty string disables this, a non-empty | ||
// string is the key for the additional field. Errors use -1 and | ||
// panics -2. | ||
func WithLogNumeric(key string) Option { |
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.
Using With*() here feels confusing. I'd make this sound imperative. e.g. LogNumericLevel(key)
or LogInfoLevel(key)
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.
I'm influenced by gRPC here. It uses the With
prefix for options. https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis doesn't use it and in logr we have some other convention around With
, so I agree, let's simplify.
zapr.go
Outdated
// panics -2. | ||
func WithLogNumeric(key string) Option { | ||
return func(zl *zapLogger) { | ||
zl.logNumericFieldName = key |
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.
This is wordy for not much value. I'd streamline the name like numericLevelKey
or levelKey
zapr.go
Outdated
|
||
// WithErrorFieldName replaces the default "error" field name | ||
// used for the error in Logger.Error calls. | ||
func WithErrorFieldName(name string) Option { |
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.
ErrorKey(key)
?
On negative V() levels. The doc-comments for V says 2 things of note:
The code backs this up:
The idea here is that I might pass a Logger to some other function with a bias in its V(). E.g.
...and that other function can't undo what I have done. Regarding |
Okay, I'll drop that.
That's basically a new feature request ("distinguish between error and info messages"). Let's postpone that until someone actually needs it and the criteria "only info messages have v" is not enough.
It's the log sink itself which generates a panic log message and sends it to the underlying zap logger. As for errors let's simply not add a "v" field to those messages. |
f46ce7d
to
8d22d6f
Compare
I've force-pushed an update. Key changes:
|
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.
mostly typos, a few small things.
} | ||
|
||
// TestInfo tests the JSON info format. | ||
func TestInfo(t *testing.T) { |
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.
This is a pretty complex test. I won't demand it now, since I know it is ported, but it would be nice to have 1 test that proves Info() works with no options. Then a test that proves that LogInfoLevel works. Then a test that proves ErrorKey works. etc. I feel like each test should be much simpler to comprehend
8d22d6f
to
2e8c031
Compare
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.
I'm willing to merge as-is, one point to discuss (naming, optional change IMO)
2e8c031
to
c13ca57
Compare
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.
As a followup, maybe change the example to use these properly?
8b94353
to
ba50232
Compare
This PR depends on |
ba50232
to
46f84fd
Compare
limitations under the License. | ||
*/ | ||
|
||
package main |
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.
As a followup, maybe change the example to use these properly?
Added that as example/example_test.go
. I'm just not sure whether godoc will pick up the example code there or whether it needs to be one level up in the same package?
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.
It turned out that they are not found inside the example
directory.
It worked for funcr when in the same directory as the code (https://pkg.go.dev/github.com/go-logr/[email protected]/funcr#pkg-examples) but not for zapr (https://pkg.go.dev/github.com/go-logr/[email protected]).
I'll move the file in a new PR.
46f84fd
to
566ac59
Compare
1.1.0 is tagged |
78b6279
to
e74c9d4
Compare
This is needed to make zapr usable for Kubernetes. Currently Kubernetes uses a forked zapr with "v" for the numeric verbosity and "err" for Logger.Error. Handling of invalid calls remains compatible with zapr v1.0.0 (= panic log messages are emitted, strongly-type Zap fields are not allowed), but new options allow changing those defaults. Those panic messages now log the source code of the caller, not the zapr.go file where the panic message is logged. The unit tests were derived from https://github.com/kubernetes/kubernetes/blob/cff40a7bcc170c473c223081fd0103fd042dc44b/staging/src/k8s.io/component-base/logs/json/json_test.go and both modified (better error messages, t.Run for each test case) and extended to enhance coverage. Several new edge cases are now covered (for example, error logging at non-zero verbosity levels). New tests for WithName, WithCallDepth and WithValues were added.
e74c9d4
to
13bdf6b
Compare
LGTM |
This is needed to make zapr usable for Kubernetes. Currently
Kubernetes uses a forked zapr with "v" for the numeric verbosity and
"err" for Logger.Error. Compared to the implementation in Kubernetes
there's one functional difference: Logger.Error is logged with v=-1
and internal panics with v=-2 to distinguish the log messages from
normal info messages where v >= 0.
The unit tests were derived from
https://github.com/kubernetes/kubernetes/blob/cff40a7bcc170c473c223081fd0103fd042dc44b/staging/src/k8s.io/component-base/logs/json/json_test.go
and both modified (better error messages, t.Run for each test case)
and extended to enhance coverage.
Several new edge cases are now covered (for example, error logging
at non-zero verbosity levels) and new tests for WithName,
WithCallDepth and WithValues were added.
Fixes #36