diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index 69a815fc..cab21bae 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -18,6 +18,7 @@ import ( "os" "github.com/rs/zerolog" + "github.com/sirupsen/logrus" ) type Writer interface { @@ -57,7 +58,8 @@ func NewZerologMetrics(enabled bool, target string, containerID string) Writer { zerolog.TimeFieldFormat = zerolog.TimeFormatUnixNano 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) + return &mockWriter{} } logger := zerolog.New(file).Level(zerolog.InfoLevel).With().Timestamp().Logger() return &zerologMetrics{ diff --git a/internal/metrics/metrics_test.go b/internal/metrics/metrics_test.go index cb4230d7..db89a2cb 100644 --- a/internal/metrics/metrics_test.go +++ b/internal/metrics/metrics_test.go @@ -52,3 +52,20 @@ func TestZerologMetricsMetadata(t *testing.T) { t.Errorf("timestampOrder = %v, want 0", got) } } + +func TestZerologMetricsInvalidFileDoesNotPanic(t *testing.T) { + // Provide a path to a directory that definitely does not exist + invalidPath := "/does/not/exist/timestamps.log" + + // Create the metrics writer with timestamps enabled but an invalid path + writer := NewZerologMetrics(true, invalidPath, "container-test") + + // Before the fix, writer would be nil here. + if writer == nil { + t.Fatal("Expected NewZerologMetrics to return a fallback writer, got nil") + } + + // This call would panic with a nil pointer dereference without the fix. + // With the fix, it will safely execute the mockWriter's no-op Capture(). + writer.Capture(TS00) +}