Skip to content

fix: honor -stderrthreshold when -logtostderr is set#2421

Open
pierluigilenoci wants to merge 2 commits intoopenkruise:masterfrom
pierluigilenoci:fix/honor-stderrthreshold
Open

fix: honor -stderrthreshold when -logtostderr is set#2421
pierluigilenoci wants to merge 2 commits intoopenkruise:masterfrom
pierluigilenoci:fix/honor-stderrthreshold

Conversation

@pierluigilenoci
Copy link
Copy Markdown

What this PR does

klog v2 defaults -logtostderr to true, which silently causes -stderrthreshold to be ignored — all log messages of every severity are unconditionally written to stderr. There is no way for users to filter which severity levels reach stderr.

This has been an open issue since 2020: kubernetes/klog#212.

klog v2.140.0 (kubernetes/klog#432) introduces a legacy_stderr_threshold_behavior flag that fixes this. This PR:

  • bumps k8s.io/klog/v2 from v2.130.1 to v2.140.0
  • sets legacy_stderr_threshold_behavior=false after klog.InitFlags in both main.go and cmd/daemon/main.go
  • sets stderrthreshold=INFO so the default behavior is preserved but users can now override it on the command line (e.g. -stderrthreshold=WARNING)

Why it matters

In production clusters, log aggregation systems (Fluentd, Fluent Bit, Loki, Datadog, etc.) typically ingest logs from container stderr. When every log level goes to stderr indiscriminately:

  • Log storage costs increase — INFO-level debug noise is stored alongside real errors
  • Alerting becomes unreliable — operators cannot trigger alerts on stderr output because it contains everything
  • Signal-to-noise ratio degrades — finding actual errors in a stream of INFO messages is difficult

The -stderrthreshold flag exists precisely to solve this, but it has never worked under the default klog v2 configuration — until now.

Changed files

File Change
main.go set legacy_stderr_threshold_behavior=false + stderrthreshold=INFO after klog.InitFlags
cmd/daemon/main.go same
go.mod / go.sum bump klog v2.130.1 → v2.140.0

klog v2 defaults -logtostderr to true, which silently causes
-stderrthreshold to be ignored. klog v2.140.0 introduced the
legacy_stderr_threshold_behavior flag that restores the correct
interaction between the two flags (see kubernetes/klog#432).

This commit:
- bumps k8s.io/klog/v2 from v2.130.1 to v2.140.0
- sets legacy_stderr_threshold_behavior=false after klog.InitFlags in
  both main.go and cmd/daemon/main.go
- sets stderrthreshold=INFO so the default behavior is preserved but
  users can now override it on the command line

Ref: kubernetes/klog#212

Signed-off-by: Pierluigi Lenoci <pierluigi.lenoci@gmail.com>
Signed-off-by: Pierluigi Lenoci <pierluigilenoci@gmail.com>
Copilot AI review requested due to automatic review settings April 23, 2026 15:41
@kruise-bot kruise-bot requested a review from FillZpp April 23, 2026 15:41
@kruise-bot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign veophi for approval by writing /assign @veophi in a comment. For more information see:The Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kruise-bot kruise-bot requested a review from zmberg April 23, 2026 15:41
@kruise-bot
Copy link
Copy Markdown

Welcome @pierluigilenoci! It looks like this is your first PR to openkruise/kruise 🎉

@kruise-bot kruise-bot added the size/S size/S 10-29 label Apr 23, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 48.85%. Comparing base (d9b8202) to head (ca2d6f5).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2421      +/-   ##
==========================================
+ Coverage   48.15%   48.85%   +0.70%     
==========================================
  Files         325      325              
  Lines       34824    27950    -6874     
==========================================
- Hits        16769    13656    -3113     
+ Misses      16523    12763    -3760     
+ Partials     1532     1531       -1     
Flag Coverage Δ
unittests 48.85% <ø> (+0.70%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates klog to a version that supports honoring -stderrthreshold even when -logtostderr=true, and configures the binaries to use the new behavior while preserving current defaults.

Changes:

  • Bump k8s.io/klog/v2 from v2.130.1 to v2.140.0.
  • Set legacy_stderr_threshold_behavior=false and default stderrthreshold=INFO after klog.InitFlags in both entrypoints.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
main.go Opt into new klog stderr-threshold behavior and set default threshold to INFO
cmd/daemon/main.go Same klog flag defaults as the main binary
go.mod Bump klog dependency to v2.140.0
go.sum Update checksums for klog v2.140.0

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread main.go Outdated
Comment on lines +142 to +143
flag.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck
flag.Set("stderrthreshold", "INFO") //nolint:errcheck
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flag.Set(...) can fail (e.g., if the flag name changes, isn’t registered due to init order changes, or klog behavior differs between builds). Silencing these errors risks silently reverting to the problematic behavior in production. Consider handling the returned errors and failing fast (or at least emitting a clear warning) so misconfiguration is immediately visible.

Suggested change
flag.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck
flag.Set("stderrthreshold", "INFO") //nolint:errcheck
if err := flag.Set("legacy_stderr_threshold_behavior", "false"); err != nil {
klog.Fatalf("failed to set flag %q: %v", "legacy_stderr_threshold_behavior", err)
}
if err := flag.Set("stderrthreshold", "INFO"); err != nil {
klog.Fatalf("failed to set flag %q: %v", "stderrthreshold", err)
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — good catch. Updated both flag.Set calls in main.go to check the returned error and klog.Fatalf on failure, so misconfiguration is immediately visible instead of silently reverting to the old behavior.

Comment thread cmd/daemon/main.go Outdated
Comment on lines +64 to +65
flag.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck
flag.Set("stderrthreshold", "INFO") //nolint:errcheck
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same concern as in main.go: ignoring flag.Set errors can lead to silently incorrect logging behavior. Please handle the errors (fail fast or log a warning) to avoid a hard-to-diagnose operational regression if the flags aren’t present/registered as expected.

Suggested change
flag.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck
flag.Set("stderrthreshold", "INFO") //nolint:errcheck
if err := flag.Set("legacy_stderr_threshold_behavior", "false"); err != nil {
klog.Fatalf("Failed to set legacy_stderr_threshold_behavior: %v", err)
}
if err := flag.Set("stderrthreshold", "INFO"); err != nil {
klog.Fatalf("Failed to set stderrthreshold: %v", err)
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — same treatment applied here: both flag.Set calls now check for errors and klog.Fatalf on failure.

Comment thread cmd/daemon/main.go Outdated
Comment on lines +58 to +65
func main() {
utilfeature.DefaultMutableFeatureGate.AddFlag(pflag.CommandLine)
klog.InitFlags(nil)
// Opt into the new klog behavior so that -stderrthreshold is honored even
// when -logtostderr=true (the default).
// Ref: kubernetes/klog#212, kubernetes/klog#432
flag.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck
flag.Set("stderrthreshold", "INFO") //nolint:errcheck
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same multi-line comment and flag-defaulting logic is duplicated in two entrypoints. To avoid drift (e.g., one binary missing a future tweak), consider extracting a small helper (e.g., initKlogFlags() in a shared package) called by both mains.

Suggested change
func main() {
utilfeature.DefaultMutableFeatureGate.AddFlag(pflag.CommandLine)
klog.InitFlags(nil)
// Opt into the new klog behavior so that -stderrthreshold is honored even
// when -logtostderr=true (the default).
// Ref: kubernetes/klog#212, kubernetes/klog#432
flag.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck
flag.Set("stderrthreshold", "INFO") //nolint:errcheck
func initKlogFlags() {
klog.InitFlags(nil)
// Opt into the new klog behavior so that -stderrthreshold is honored even
// when -logtostderr=true (the default).
// Ref: kubernetes/klog#212, kubernetes/klog#432
flag.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck
flag.Set("stderrthreshold", "INFO") //nolint:errcheck
}
func main() {
utilfeature.DefaultMutableFeatureGate.AddFlag(pflag.CommandLine)
initKlogFlags()

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion. Since these are two separate main packages (main.go and cmd/daemon/main.go), extracting a shared helper would require introducing a new internal package — which feels like scope creep for this PR. The duplication is minimal (4 lines) and the pattern is now consistent between both entrypoints. Happy to revisit if the maintainers prefer a shared helper.

Replace //nolint:errcheck suppressions with proper error handling.
Both flag.Set calls now fail fast via klog.Fatalf if the flag cannot
be set, making misconfiguration immediately visible.

Signed-off-by: Pierluigi Lenoci <pierluigilenoci@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/S size/S 10-29

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants