From 94e14f3b4e2dbdff72404ccb44b9d9a8bede5be9 Mon Sep 17 00:00:00 2001 From: Graeme Gillies Date: Thu, 11 Jun 2026 19:17:28 +1000 Subject: [PATCH] fix: Fix broken `trackLogs` functionality in Kubedog tracker (#2630) * fix: Fix broken `trackLogs` functionality in Kubedog tracker When using helmfile with the following setup ``` releases: - name: my-app chart: ./mychart trackMode: kubedog trackLogs: true trackFailOnError: true ``` We don't actually see any logs from the container being printed. This is because when building the options for the Kubedog tracker, we never specify `SaveLogsOnlyForNumberOfReplicas` which means this defaults to 0. Looking at the logic in `pkg/tracker/deployment/tracker.go` we see ``` ignoreLogs := job.ignoreLogs || job.savingLogsReplicas >= job.SaveLogsOnlyForNumberOfReplicas ``` With job.SaveLogsOnlyForNumberOfReplicas always defaulting to 0, this will always ignore logs This change sets it to a reasonable default of tracking logs from up to 10 pods. Signed-off-by: Graeme Gillies * fix formatting Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Graeme Gillies * feat: Refactor out building tracker opts into it's own function, add tests Signed-off-by: Graeme Gillies --------- Signed-off-by: Graeme Gillies Co-authored-by: Graeme Gillies Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- pkg/kubedog/tracker.go | 33 +++++++++++++++++++++++++++------ pkg/kubedog/tracker_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/pkg/kubedog/tracker.go b/pkg/kubedog/tracker.go index cc4e11e5..e31d4b76 100644 --- a/pkg/kubedog/tracker.go +++ b/pkg/kubedog/tracker.go @@ -201,6 +201,32 @@ type trackTarget struct { namespace string } +// defaultSaveLogsReplicas is the number of pods per resource for which kubedog +// will stream logs when log tracking is enabled. kubedog ignores logs unless +// SaveLogsOnlyForNumberOfReplicas is positive (see ignoreLogs in +// pkg/tracker/deployment/tracker.go), so leaving it at 0 silently suppresses +// all log output even when trackLogs is true. +const defaultSaveLogsReplicas = 10 + +// buildTrackerOptions constructs the kubedog tracker options from the tracker's +// configured TrackOptions. It is factored out of TrackResources so the option +// mapping (in particular enabling log streaming) can be unit tested without a +// live cluster. +func (t *Tracker) buildTrackerOptions(ctx context.Context) tracker.Options { + opts := tracker.Options{ + ParentContext: ctx, + Timeout: t.trackOptions.Timeout, + LogsFromTime: time.Now().Add(-t.trackOptions.LogsSince), + IgnoreLogs: !t.trackOptions.Logs, + } + + if t.trackOptions.Logs { + opts.SaveLogsOnlyForNumberOfReplicas = defaultSaveLogsReplicas + } + + return opts +} + func (t *Tracker) TrackResources(ctx context.Context, resources []*resource.Resource) error { if len(resources) == 0 { t.logger.Info("No resources to track") @@ -231,12 +257,7 @@ func (t *Tracker) TrackResources(ctx context.Context, resources []*resource.Reso informer.ConcurrentInformerFactoryOptions{}, ) - opts := tracker.Options{ - ParentContext: ctx, - Timeout: t.trackOptions.Timeout, - LogsFromTime: time.Now().Add(-t.trackOptions.LogsSince), - IgnoreLogs: !t.trackOptions.Logs, - } + opts := t.buildTrackerOptions(ctx) var wg sync.WaitGroup errCh := make(chan error, len(targets)) diff --git a/pkg/kubedog/tracker_test.go b/pkg/kubedog/tracker_test.go index c28f7ec5..96e23f80 100644 --- a/pkg/kubedog/tracker_test.go +++ b/pkg/kubedog/tracker_test.go @@ -1,6 +1,7 @@ package kubedog import ( + "context" "math" "os" "testing" @@ -275,3 +276,31 @@ users: assert.NotNil(t, tr) } } + +func TestBuildTrackerOptions_LogsEnabled(t *testing.T) { + tr := &Tracker{ + trackOptions: NewTrackOptions().WithLogs(true), + } + + opts := tr.buildTrackerOptions(context.Background()) + + // With logs enabled, kubedog must be told to stream logs and to save logs + // for a positive number of replicas, otherwise log output is silently + // suppressed. + assert.False(t, opts.IgnoreLogs) + assert.Equal(t, defaultSaveLogsReplicas, opts.SaveLogsOnlyForNumberOfReplicas) + assert.Equal(t, 5*time.Minute, opts.Timeout) +} + +func TestBuildTrackerOptions_LogsDisabled(t *testing.T) { + tr := &Tracker{ + trackOptions: NewTrackOptions().WithLogs(false), + } + + opts := tr.buildTrackerOptions(context.Background()) + + // With logs disabled, kubedog should ignore logs and not save any replicas' + // logs (leaving the default zero value). + assert.True(t, opts.IgnoreLogs) + assert.Zero(t, opts.SaveLogsOnlyForNumberOfReplicas) +}