Skip to content

fix(metrics): fallback to mock writer on file open failure to prevent panic - #596

Merged
cmainas merged 1 commit into
urunc-dev:main-pr596from
abhaygoudannavar:one/metrics-file
Jun 23, 2026
Merged

fix(metrics): fallback to mock writer on file open failure to prevent panic#596
cmainas merged 1 commit into
urunc-dev:main-pr596from
abhaygoudannavar:one/metrics-file

Conversation

@abhaygoudannavar

@abhaygoudannavar abhaygoudannavar commented May 1, 2026

Copy link
Copy Markdown
Contributor

Description

When timestamps are enabled in the urunc configuration (/etc/urunc/config.toml) but the target file path is invalid or the parent directory does not exist, NewZerologMetrics() returns nil. Because the caller assigns this directly without a nil check, any subsequent metrics.Capture() calls result in a nil pointer dereference, crashing urunc silently.

This PR fixes the issue by returning a &mockWriter{} (safe no-op fallback) and logging a warning instead of returning nil on file open failure. This ensures urunc gracefully disables metrics rather than panicking.

Related issues

How was this tested?

  1. Enabled timestamps in /etc/urunc/config.toml with enabled = true and destination set to a non-existent directory (/var/log/urunc/timestamps.log).
  2. Ran sudo nerdctl run --rm --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/nginx-qemu-unikraft-initrd:latest.
  3. Verified that urunc starts normally, logs a warning about the file, and gracefully disables metrics without crashing.
  4. Ran make unittest to ensure no existing tests were broken.

LLM usage

No usage

Checklist

  • I have read the contribution guide.
  • The linter passes locally (make lint).
  • The e2e tests of at least one tool pass locally (make test_ctr, make test_nerdctl, make test_docker, make test_crictl).
  • If LLMs were used: I have read the llm policy.

@netlify

netlify Bot commented May 1, 2026

Copy link
Copy Markdown

Deploy Preview for urunc canceled.

Name Link
🔨 Latest commit 49d40bd
🔍 Latest deploy log https://app.netlify.com/projects/urunc/deploys/6a3a8414f2ea8f00083ce1d0

@cmainas

cmainas commented May 5, 2026

Copy link
Copy Markdown
Contributor

Hello @abhaygoudannavar ,

please do not overwrite the PR description. Read the contribution guide for more information.

@abhaygoudannavar

Copy link
Copy Markdown
Contributor Author

@cmainas i have updated the PR description as asked for now it can be merged.

@cmainas cmainas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hello @abhaygoudannavar ,

you have linked a PR instead of the issue in the description. Also, I left a comment for the unit test.

Comment thread internal/metrics/metrics_test.go Outdated
@abhaygoudannavar

abhaygoudannavar commented May 10, 2026

Copy link
Copy Markdown
Contributor Author

@cmainas i have done the changes asked for.

@cmainas cmainas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hello @abhaygoudannavar ,

thank you for the changes. I have added a comment.

Comment thread internal/metrics/metrics_test.go Outdated
@abhaygoudannavar
abhaygoudannavar force-pushed the one/metrics-file branch 2 times, most recently from 2b92199 to 05344a3 Compare May 14, 2026 21:06
@abhaygoudannavar
abhaygoudannavar requested a review from cmainas May 14, 2026 21:07

@cmainas cmainas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hello @abhaygoudannavar ,

it seems there was a misunderstanding. Maybe I di not place the comment in the correct line. The check for the nil return should remain, the call later to Capture should get removed. We should not test by checking if the test crashes.

Comment thread internal/metrics/metrics_test.go Outdated
@abhaygoudannavar

Copy link
Copy Markdown
Contributor Author

@cmainas Thanks for the clarification, I've updated the test to explicitly check for a non-nil writer instead of relying on the panic recovery. The PR has been updated.

@cmainas cmainas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hello @abhaygoudannavar ,

why were the asserts got removed?

Comment thread internal/metrics/metrics_test.go Outdated
@abhaygoudannavar

Copy link
Copy Markdown
Contributor Author

Hey @cmainas Updated the tests to use assert.Equal and require.NotNil/require.NoError from testify instead of manual checks. The asserts were removed unintentionally in the initial commit fixed now.v

@cmainas

cmainas commented May 21, 2026

Copy link
Copy Markdown
Contributor

Thank you @abhaygoudannavar for the changes. Could you please rebase over main so the CI can recognize you?

@abhaygoudannavar

Copy link
Copy Markdown
Contributor Author

@cmainas i have rebased over the main.

@cmainas

cmainas commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Hello @abhaygoudannavar ,

could you rebase over main and squash the non-unit test commits (or squash everything)?

@abhaygoudannavar

Copy link
Copy Markdown
Contributor Author

@cmainas i have rebased over the main and squashed the non unit test commits.
let me know if anything else is needed.

@cmainas cmainas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hello @abhaygoudannavar ,

thank you for the rebase. Just two more small comments and we are good to go.

Comment thread internal/metrics/metrics.go Outdated
file, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
return nil
logrus.Warnf("Failed to open metrics file %s: %v. Metrics will be disabled.", target, err)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It would be better to return the error and log it form the caller, rather than importing logrus here. This will allow us in the future to handle this error differently.

// Create the metrics writer with timestamps enabled but an invalid path
writer := NewZerologMetrics(true, invalidPath, "container-test")

require.NotNil(t, writer, "expected non-nil writer (fallback to mockWriter), got nil")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Another useful check here would be to ensure that writer is mockWriter.

When timestamps are enabled but the target file cannot be opened,
NewZerologMetrics returned nil. This caused a nil pointer dereference
on subsequent metrics.Capture() calls.

This fix gracefully degrades to a no-op mockWriter and logs a warning.
Adds a regression test to verify the fallback behavior.

Fixes: urunc-dev#595
Signed-off-by: abhaygoudannavar <abhaysgoudnvr@gmail.com>
@abhaygoudannavar

Copy link
Copy Markdown
Contributor Author

@cmainas i have addressed both the comments, All unit tests pass. The commit has been squashed and rebased over main.

@urunc-bot
urunc-bot Bot changed the base branch from main to main-pr596 June 23, 2026 15:49

@cmainas cmainas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you @abhaygoudannavar for the changes.

@cmainas
cmainas merged commit 598a4c2 into urunc-dev:main-pr596 Jun 23, 2026
49 of 52 checks passed
github-actions Bot pushed a commit that referenced this pull request Jun 23, 2026
When timestamps are enabled but the target file cannot be opened,
NewZerologMetrics returned nil. This caused a nil pointer dereference
on subsequent metrics.Capture() calls.

This fix gracefully degrades to a no-op mockWriter and logs a warning.
Adds a regression test to verify the fallback behavior.

PR: #596
Fixes: #595
Signed-off-by: abhaygoudannavar <abhaysgoudnvr@gmail.com>
Reviewed-by: Charalampos Mainas <cmainas@nubificus.co.uk>
Approved-by: Charalampos Mainas <cmainas@nubificus.co.uk>
urunc-bot Bot pushed a commit that referenced this pull request Jun 23, 2026
When timestamps are enabled but the target file cannot be opened,
NewZerologMetrics returned nil. This caused a nil pointer dereference
on subsequent metrics.Capture() calls.

This fix gracefully degrades to a no-op mockWriter and logs a warning.
Adds a regression test to verify the fallback behavior.

PR: #596
Fixes: #595
Signed-off-by: abhaygoudannavar <abhaysgoudnvr@gmail.com>
Reviewed-by: Charalampos Mainas <cmainas@nubificus.co.uk>
Approved-by: Charalampos Mainas <cmainas@nubificus.co.uk>
@abhaygoudannavar
abhaygoudannavar deleted the one/metrics-file branch July 1, 2026 10:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(metrics): NewZerologMetrics returns nil on file open failure causing panic

2 participants