-
Notifications
You must be signed in to change notification settings - Fork 329
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
🎁 Deterministic exit code for zap's Fatal for sharedmain
#2496
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: cardil The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
8e3b800
to
e5e9a4a
Compare
Codecov Report
@@ Coverage Diff @@
## main #2496 +/- ##
==========================================
+ Coverage 81.71% 81.74% +0.02%
==========================================
Files 163 165 +2
Lines 9653 9688 +35
==========================================
+ Hits 7888 7919 +31
- Misses 1529 1533 +4
Partials 236 236
Continue to review full report at Codecov.
|
e5e9a4a
to
682c51d
Compare
Github's Unit test fail looks like an unrelated flake. |
/assign @knative/technical-oversight-committee |
/assign @dprotaso |
@@ -282,7 +282,7 @@ func MainWithConfig(ctx context.Context, component string, cfg *rest.Config, cto | |||
} | |||
|
|||
func flush(logger *zap.SugaredLogger) { | |||
logger.Sync() | |||
_ = logger.Sync() // we care about stdout and stderr only |
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 don't understand this change
zap's godoc says the Fatal exit code is See: https://pkg.go.dev/go.uber.org/zap#Logger.Fatal Are you seeing something different? |
I'm not particularly sold on this change - as the exit code is dependent on the log message. Plus a range of exit codes are meant to reserved: |
if entry.Level >= zapcore.DPanicLevel { | ||
return ce.AddCore(entry, r) | ||
} |
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.
Do we need to do this separately from the base
?
if err := r.base.Write(entry, fields); err != nil { | ||
return err | ||
} |
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.
Other implementations won't exit during Write
, correct?
}) | ||
|
||
type retcodeCore struct { | ||
base zapcore.Core |
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.
How much would you get for free from embedding zapcore.Core
?
type retcodeCore struct {
zapcore.Core
fields []zapcore.Field
}
|
||
type retcodeCore struct { | ||
base zapcore.Core | ||
fields []zapcore.Field |
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.
Can you add a comment on why we're tracking the fields here specially?
} | ||
code := r.calculateRetcode(entry, fields) | ||
_ = r.Sync() | ||
exit.Exit(code) |
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.
Do you want to call go.uber.org/zap/internal/exit
to enable working with zap's testing spy?
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 looks like you've copied the zap
spy into the pkg
codebase, though I don't understand why we need that rather than adopting / improving the zap one.
|
||
import "hash/crc32" | ||
|
||
// Calc will calculate an POSIX retcode from an error. |
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 not sure why we want to do this -- it looks like we're collapsing all errors into a range of code 1-255.
https://unix.stackexchange.com/a/418802 suggests that the range 1-125 might be more reasonable, or 1 - (2^31-1) if you're willing to work with waitid
and some of the newer posix calls.
) | ||
|
||
func TestCalc(t *testing.T) { | ||
cases := testCases() |
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 not inline this declaration (as we do elsewhere)?
cases := []struct {
name string
err error
want int
}{{
name: "nil",
err: nil,
want: 0,
}, {
...
}}
assert.Check(t, cmp.Contains(logs, `"message":"foo"`)) | ||
assert.Check(t, cmp.Contains(logs, `"error":"bar"`)) |
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 slightly concerned about adding a new dependency here to save a line of code:
if ! strings.Contains(logs, `"message":"foo"`) {
t.Errorf("Expected %q to contain message tag", logs)
}
(To put it simply, the cost of adding the dependency seems higher than the value that it adds in terms of clarity.)
@cardil: PR needs rebase. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Where do we stand with this PR ? Seems to be dormant since quite some time. |
I don't think we should merge this change - changing the exit code based on log messages I think will just make things more confusing as people google exit code values and they have different meaning. We should probably write the correct log line to the k8s termination path https://kubernetes.io/docs/tasks/debug/debug-application/determine-reason-pod-failure/ |
Going to close this out |
Changes
sharedmain
/kind enhancement
Fixes #2495