Repository: grafana/grafana
Pull request #104979: Advisor: Use contextual logger
Author: login: andresmgot
Labels: name: no-changelog
description: Skip including change in changelog/release notes
Created: 2025-05-06T07:54:32Z | Merged: 2025-05-06T11:58:29Z

<!--

Thank you for sending a pull request! Here are some tips:

1. If this is your first time, please read our contribution guide at https://github.com/grafana/grafana/blob/main/CONTRIBUTING.md

2. Ensure you include and run the appropriate tests as part of your Pull Request.

3. In a new feature or configuration option, an update to the documentation is necessary. Everything related to the documentation is under the docs folder in the root of the repository.

4. If the Pull Request is a work in progress, make use of GitHub's "Draft PR" feature and mark it as such.

5. If you can not merge your Pull Request due to a merge conflict, Rebase it. This gets it in sync with the main branch.

6. Name your PR as "<FeatureArea>: Describe your change", e.g. Alerting: Prevent race condition. If it's a fix or feature relevant for the changelog describe the user impact in the title. The PR title is used to auto-generate the changelog for issues marked with the "add to changelog" label.

7. If your PR content should be added to the What's New document for the next major or minor release, add the **add to what's new** label to your PR. Note that you should add this label to the main PR that introduces the feature; do not add this label to smaller PRs for the feature.

-->

**What is this feature?**

Use app-sdk logger to enrich log lines with information like traceIDs, etc.

I have also added a exponential backoff when retrying the check type registration and increased the number of retries.

cc/ @mgyongyosi since I am modifying the `Run` interface, which may conflict with your work.

[Log sample](https://ops.grafana-ops.net/goto/-7drWYxNg?orgId=1)

**Which issue(s) does this PR fix?**:

<!--

- Automatically closes linked issue when the Pull Request is merged.

Usage: "Fixes #<issue number>", or "Fixes (paste link of issue)"

-->

First part of https://github.com/grafana/grafana-community-team/issues/391

**Special notes for your reviewer:**

Please check that:
- [x] It works as expected from a user's perspective.
- [x] If this is a pre-GA feature, it is behind a feature toggle.
- [x] The docs are updated, and if this is a [notable improvement](https://grafana.com/docs/writers-toolkit/contribute/release-notes/#how-to-determine-if-content-belongs-in-whats-new), it's added to our [What's New](https://grafana.com/docs/writers-toolkit/contribute/release-notes/) doc.



Diff:
diff --git a/apps/advisor/pkg/app/app.go b/apps/advisor/pkg/app/app.go
index 5ce2128131aa2..a68c564093adc 100644
--- a/apps/advisor/pkg/app/app.go
+++ b/apps/advisor/pkg/app/app.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/grafana/grafana-app-sdk/app"
 	"github.com/grafana/grafana-app-sdk/k8s"
+	"github.com/grafana/grafana-app-sdk/logging"
 	"github.com/grafana/grafana-app-sdk/resource"
 	"github.com/grafana/grafana-app-sdk/simple"
 	advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
@@ -14,9 +15,7 @@ import (
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checkscheduler"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checktyperegisterer"
 	"github.com/grafana/grafana/pkg/apimachinery/identity"
-	"github.com/grafana/grafana/pkg/infra/log"
 	"k8s.io/apimachinery/pkg/runtime/schema"
-	"k8s.io/klog/v2"
 )
 
 func New(cfg app.Config) (app.App, error) {
@@ -26,7 +25,7 @@ func New(cfg app.Config) (app.App, error) {
 		return nil, fmt.Errorf("invalid config type")
 	}
 	checkRegistry := specificConfig.CheckRegistry
-	log := log.New("advisor.app")
+	log := logging.DefaultLogger.With("app", "advisor.app")
 
 	// Prepare storage client
 	clientGenerator := k8s.NewClientRegistry(cfg.KubeConfig, k8s.ClientConfig{})
@@ -46,7 +45,7 @@ func New(cfg app.Config) (app.App, error) {
 		KubeConfig: cfg.KubeConfig,
 		InformerConfig: simple.AppInformerConfig{
 			ErrorHandler: func(ctx context.Context, err error) {
-				klog.ErrorS(err, "Informer processing error")
+				log.WithContext(ctx).Error("Informer processing error", "error", err)
 			},
 		},
 		ManagedKinds: []simple.AppManagedKind{
@@ -61,31 +60,33 @@ func New(cfg app.Config) (app.App, error) {
 							}
 							if req.Action == resource.AdmissionActionCreate {
 								go func() {
-									log.Debug("Processing check", "namespace", req.Object.GetNamespace())
+									logger := log.WithContext(ctx).With("check", check.ID())
+									logger.Debug("Processing check", "namespace", req.Object.GetNamespace())
 									requester, err := identity.GetRequester(ctx)
 									if err != nil {
-										log.Error("Error getting requester", "error", err)
+										logger.Error("Error getting requester", "error", err)
 										return
 									}
 									ctx = identity.WithRequester(context.Background(), requester)
-									err = processCheck(ctx, client, req.Object, check)
+									err = processCheck(ctx, logger, client, req.Object, check)
 									if err != nil {
-										log.Error("Error processing check", "error", err)
+										logger.Error("Error processing check", "error", err)
 									}
 								}()
 							}
 							if req.Action == resource.AdmissionActionUpdate {
 								go func() {
-									log.Debug("Updating check", "namespace", req.Object.GetNamespace(), "name", req.Object.GetName())
+									logger := log.WithContext(ctx).With("check", check.ID())
+									logger.Debug("Updating check", "namespace", req.Object.GetNamespace(), "name", req.Object.GetName())
 									requester, err := identity.GetRequester(ctx)
 									if err != nil {
-										log.Error("Error getting requester", "error", err)
+										logger.Error("Error getting requester", "error", err)
 										return
 									}
 									ctx = identity.WithRequester(context.Background(), requester)
-									err = processCheckRetry(ctx, client, req.Object, check)
+									err = processCheckRetry(ctx, logger, client, req.Object, check)
 									if err != nil {
-										log.Error("Error processing check retry", "error", err)
+										logger.Error("Error processing check retry", "error", err)
 									}
 								}()
 							}
@@ -111,14 +112,14 @@ func New(cfg app.Config) (app.App, error) {
 	}
 
 	// Save check types as resources
-	ctr, err := checktyperegisterer.New(cfg)
+	ctr, err := checktyperegisterer.New(cfg, log)
 	if err != nil {
 		return nil, err
 	}
 	a.AddRunnable(ctr)
 
 	// Start scheduler
-	csch, err := checkscheduler.New(cfg)
+	csch, err := checkscheduler.New(cfg, log)
 	if err != nil {
 		return nil, err
 	}
diff --git a/apps/advisor/pkg/app/checks/authchecks/check.go b/apps/advisor/pkg/app/checks/authchecks/check.go
index 9cbb2801c0241..69513bfed909e 100644
--- a/apps/advisor/pkg/app/checks/authchecks/check.go
+++ b/apps/advisor/pkg/app/checks/authchecks/check.go
@@ -5,7 +5,6 @@ import (
 	"fmt"
 
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
-	"github.com/grafana/grafana/pkg/infra/log"
 	"github.com/grafana/grafana/pkg/services/ssosettings"
 )
 
@@ -17,13 +16,11 @@ var _ checks.Check = (*check)(nil)
 
 type check struct {
 	ssoSettingsService ssosettings.Service
-	log                log.Logger
 }
 
 func New(ssoSettingsService ssosettings.Service) checks.Check {
 	return &check{
 		ssoSettingsService: ssoSettingsService,
-		log:                log.New("advisor.ssosettingcheck"),
 	}
 }
 
diff --git a/apps/advisor/pkg/app/checks/authchecks/list_format_validation.go b/apps/advisor/pkg/app/checks/authchecks/list_format_validation.go
index 304d478a6a789..076286935aa8b 100644
--- a/apps/advisor/pkg/app/checks/authchecks/list_format_validation.go
+++ b/apps/advisor/pkg/app/checks/authchecks/list_format_validation.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"strings"
 
+	"github.com/grafana/grafana-app-sdk/logging"
 	advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
 	"github.com/grafana/grafana/pkg/services/login"
@@ -47,7 +48,7 @@ func (s *listFormatValidation) Resolution() string {
 	return "Configure the relevant SSO setting using a valid format, like space-separated (\"opt1 opt2\"), comma-separated values (\"opt1, opt2\") or JSON array format ([\"opt1\", \"opt2\"])."
 }
 
-func (s *listFormatValidation) Run(ctx context.Context, _ *advisor.CheckSpec, objToCheck any) (*advisor.CheckReportFailure, error) {
+func (s *listFormatValidation) Run(ctx context.Context, log logging.Logger, _ *advisor.CheckSpec, objToCheck any) (*advisor.CheckReportFailure, error) {
 	setting, ok := objToCheck.(*models.SSOSettings)
 	if !ok {
 		return nil, fmt.Errorf("invalid item type %T", objToCheck)
diff --git a/apps/advisor/pkg/app/checks/authchecks/list_format_validation_test.go b/apps/advisor/pkg/app/checks/authchecks/list_format_validation_test.go
index 62460fde2191a..c850b6c058c32 100644
--- a/apps/advisor/pkg/app/checks/authchecks/list_format_validation_test.go
+++ b/apps/advisor/pkg/app/checks/authchecks/list_format_validation_test.go
@@ -6,6 +6,7 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/grafana/grafana-app-sdk/logging"
 	advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
 	"github.com/grafana/grafana/pkg/services/login"
@@ -195,7 +196,7 @@ func TestListFormatValidation_Run(t *testing.T) {
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			failure, err := validator.Run(ctx, spec, tt.objToCheck)
+			failure, err := validator.Run(ctx, logging.DefaultLogger, spec, tt.objToCheck)
 
 			if tt.expectedError != "" {
 				require.Error(t, err)
diff --git a/apps/advisor/pkg/app/checks/datasourcecheck/check.go b/apps/advisor/pkg/app/checks/datasourcecheck/check.go
index 64d34c3bfad05..df1223043f4ca 100644
--- a/apps/advisor/pkg/app/checks/datasourcecheck/check.go
+++ b/apps/advisor/pkg/app/checks/datasourcecheck/check.go
@@ -5,11 +5,11 @@ import (
 	"errors"
 	"fmt"
 
+	"github.com/grafana/grafana-app-sdk/logging"
 	"github.com/grafana/grafana-plugin-sdk-go/backend"
 	advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
 	"github.com/grafana/grafana/pkg/apimachinery/identity"
-	"github.com/grafana/grafana/pkg/infra/log"
 	"github.com/grafana/grafana/pkg/plugins"
 	"github.com/grafana/grafana/pkg/plugins/repo"
 	"github.com/grafana/grafana/pkg/services/datasources"
@@ -30,7 +30,6 @@ type check struct {
 	PluginContextProvider pluginContextProvider
 	PluginClient          plugins.Client
 	PluginRepo            repo.Service
-	log                   log.Logger
 }
 
 func New(
@@ -46,7 +45,6 @@ func New(
 		PluginContextProvider: pluginContextProvider,
 		PluginClient:          pluginClient,
 		PluginRepo:            pluginRepo,
-		log:                   log.New("advisor.datasourcecheck"),
 	}
 }
 
@@ -83,12 +81,10 @@ func (c *check) Steps() []checks.Step {
 		&healthCheckStep{
 			PluginContextProvider: c.PluginContextProvider,
 			PluginClient:          c.PluginClient,
-			log:                   c.log,
 		},
 		&missingPluginStep{
 			PluginStore: c.PluginStore,
 			PluginRepo:  c.PluginRepo,
-			log:         c.log,
 		},
 	}
 }
@@ -112,7 +108,7 @@ func (s *uidValidationStep) Resolution() string {
 		"target=_blank>documentation</a> for more information or delete the data source and create a new one."
 }
 
-func (s *uidValidationStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
+func (s *uidValidationStep) Run(ctx context.Context, log logging.Logger, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
 	ds, ok := i.(*datasources.DataSource)
 	if !ok {
 		return nil, fmt.Errorf("invalid item type %T", i)
@@ -134,7 +130,6 @@ func (s *uidValidationStep) Run(ctx context.Context, obj *advisor.CheckSpec, i a
 type healthCheckStep struct {
 	PluginContextProvider pluginContextProvider
 	PluginClient          plugins.Client
-	log                   log.Logger
 }
 
 func (s *healthCheckStep) Title() string {
@@ -153,7 +148,7 @@ func (s *healthCheckStep) ID() string {
 	return HealthCheckStepID
 }
 
-func (s *healthCheckStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
+func (s *healthCheckStep) Run(ctx context.Context, log logging.Logger, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
 	ds, ok := i.(*datasources.DataSource)
 	if !ok {
 		return nil, fmt.Errorf("invalid item type %T", i)
@@ -171,7 +166,7 @@ func (s *healthCheckStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any
 			return nil, nil
 		}
 		// Unable to check health check
-		s.log.Error("Failed to get plugin context", "datasource_uid", ds.UID, "error", err)
+		log.Error("Failed to get plugin context", "datasource_uid", ds.UID, "error", err)
 		return nil, nil
 	}
 	req := &backend.CheckHealthRequest{
@@ -181,13 +176,13 @@ func (s *healthCheckStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any
 	resp, err := s.PluginClient.CheckHealth(ctx, req)
 	if err != nil || resp.Status != backend.HealthStatusOk {
 		if err != nil {
-			s.log.Debug("Failed to check health", "datasource_uid", ds.UID, "error", err)
+			log.Debug("Failed to check health", "datasource_uid", ds.UID, "error", err)
 			if errors.Is(err, plugins.ErrMethodNotImplemented) || errors.Is(err, plugins.ErrPluginUnavailable) {
 				// The plugin does not support backend health checks
 				return nil, nil
 			}
 		} else {
-			s.log.Debug("Failed to check health", "datasource_uid", ds.UID, "status", resp.Status, "message", resp.Message)
+			log.Debug("Failed to check health", "datasource_uid", ds.UID, "status", resp.Status, "message", resp.Message)
 		}
 		return checks.NewCheckReportFailure(
 			advisor.CheckReportFailureSeverityHigh,
@@ -208,7 +203,6 @@ func (s *healthCheckStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any
 type missingPluginStep struct {
 	PluginStore pluginstore.Store
 	PluginRepo  repo.Service
-	log         log.Logger
 }
 
 func (s *missingPluginStep) Title() string {
@@ -227,7 +221,7 @@ func (s *missingPluginStep) ID() string {
 	return MissingPluginStepID
 }
 
-func (s *missingPluginStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
+func (s *missingPluginStep) Run(ctx context.Context, log logging.Logger, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
 	ds, ok := i.(*datasources.DataSource)
 	if !ok {
 		return nil, fmt.Errorf("invalid item type %T", i)
diff --git a/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go b/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go
index 7c538da83f726..b1a47b9bcc6a1 100644
--- a/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go
+++ b/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go
@@ -5,10 +5,10 @@ import (
 	"errors"
 	"testing"
 
+	"github.com/grafana/grafana-app-sdk/logging"
 	"github.com/grafana/grafana-plugin-sdk-go/backend"
 	advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/pkg/apimachinery/identity"
-	"github.com/grafana/grafana/pkg/infra/log"
 	"github.com/grafana/grafana/pkg/plugins"
 	"github.com/grafana/grafana/pkg/plugins/repo"
 	"github.com/grafana/grafana/pkg/services/datasources"
@@ -28,7 +28,7 @@ func runChecks(check *check) ([]advisor.CheckReportFailure, error) {
 	failures := []advisor.CheckReportFailure{}
 	for _, step := range check.Steps() {
 		for _, item := range items {
-			stepFailures, err := step.Run(ctx, &advisor.CheckSpec{}, item)
+			stepFailures, err := step.Run(ctx, logging.DefaultLogger, &advisor.CheckSpec{}, item)
 			if err != nil {
 				return nil, err
 			}
@@ -60,7 +60,6 @@ func TestCheck_Run(t *testing.T) {
 			PluginClient:          mockPluginClient,
 			PluginRepo:            mockPluginRepo,
 			PluginStore:           mockPluginStore,
-			log:                   log.New("advisor.datasourcecheck"),
 		}
 
 		failures, err := runChecks(check)
@@ -85,7 +84,6 @@ func TestCheck_Run(t *testing.T) {
 			PluginClient:          mockPluginClient,
 			PluginRepo:            mockPluginRepo,
 			PluginStore:           mockPluginStore,
-			log:                   log.New("advisor.datasourcecheck"),
 		}
 
 		failures, err := runChecks(check)
@@ -111,7 +109,6 @@ func TestCheck_Run(t *testing.T) {
 			PluginClient:          mockPluginClient,
 			PluginRepo:            mockPluginRepo,
 			PluginStore:           mockPluginStore,
-			log:                   log.New("advisor.datasourcecheck"),
 		}
 
 		failures, err := runChecks(check)
@@ -136,7 +133,6 @@ func TestCheck_Run(t *testing.T) {
 			PluginClient:          mockPluginClient,
 			PluginRepo:            mockPluginRepo,
 			PluginStore:           mockPluginStore,
-			log:                   log.New("advisor.datasourcecheck"),
 		}
 
 		failures, err := runChecks(check)
@@ -160,7 +156,6 @@ func TestCheck_Run(t *testing.T) {
 			PluginClient:          mockPluginClient,
 			PluginRepo:            mockPluginRepo,
 			PluginStore:           mockPluginStore,
-			log:                   log.New("advisor.datasourcecheck"),
 		}
 
 		failures, err := runChecks(check)
@@ -185,7 +180,6 @@ func TestCheck_Run(t *testing.T) {
 			PluginClient:          mockPluginClient,
 			PluginRepo:            mockPluginRepo,
 			PluginStore:           mockPluginStore,
-			log:                   log.New("advisor.datasourcecheck"),
 		}
 
 		failures, err := runChecks(check)
@@ -211,7 +205,6 @@ func TestCheck_Run(t *testing.T) {
 			PluginClient:          mockPluginClient,
 			PluginRepo:            mockPluginRepo,
 			PluginStore:           mockPluginStore,
-			log:                   log.New("advisor.datasourcecheck"),
 		}
 
 		failures, err := runChecks(check)
diff --git a/apps/advisor/pkg/app/checks/ifaces.go b/apps/advisor/pkg/app/checks/ifaces.go
index 0dfd13e4f615d..3e9bdda2d572b 100644
--- a/apps/advisor/pkg/app/checks/ifaces.go
+++ b/apps/advisor/pkg/app/checks/ifaces.go
@@ -3,6 +3,7 @@ package checks
 import (
 	"context"
 
+	"github.com/grafana/grafana-app-sdk/logging"
 	advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 )
 
@@ -29,5 +30,5 @@ type Step interface {
 	// Explains the action that needs to be taken to resolve the issue
 	Resolution() string
 	// Run executes the step for an item and returns a report
-	Run(ctx context.Context, obj *advisorv0alpha1.CheckSpec, item any) (*advisorv0alpha1.CheckReportFailure, error)
+	Run(ctx context.Context, log logging.Logger, obj *advisorv0alpha1.CheckSpec, item any) (*advisorv0alpha1.CheckReportFailure, error)
 }
diff --git a/apps/advisor/pkg/app/checks/plugincheck/check.go b/apps/advisor/pkg/app/checks/plugincheck/check.go
index b5d6edf09fecf..94338c7245db8 100644
--- a/apps/advisor/pkg/app/checks/plugincheck/check.go
+++ b/apps/advisor/pkg/app/checks/plugincheck/check.go
@@ -7,10 +7,10 @@ import (
 	"slices"
 
 	"github.com/Masterminds/semver/v3"
+	"github.com/grafana/grafana-app-sdk/logging"
 	advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
 	"github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
-	"github.com/grafana/grafana/pkg/infra/log"
 	"github.com/grafana/grafana/pkg/plugins/repo"
 	"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
 	"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
@@ -79,7 +79,6 @@ func (c *check) Steps() []checks.Step {
 			PluginPreinstall:   c.PluginPreinstall,
 			ManagedPlugins:     c.ManagedPlugins,
 			ProvisionedPlugins: c.ProvisionedPlugins,
-			log:                log.New("advisor.check.plugin.update"),
 		},
 	}
 }
@@ -105,7 +104,7 @@ func (s *deprecationStep) ID() string {
 	return DeprecationStepID
 }
 
-func (s *deprecationStep) Run(ctx context.Context, _ *advisor.CheckSpec, it any) (*advisor.CheckReportFailure, error) {
+func (s *deprecationStep) Run(ctx context.Context, log logging.Logger, _ *advisor.CheckSpec, it any) (*advisor.CheckReportFailure, error) {
 	p, ok := it.(pluginstore.Plugin)
 	if !ok {
 		return nil, fmt.Errorf("invalid item type %T", it)
@@ -145,7 +144,6 @@ type updateStep struct {
 	ManagedPlugins     managedplugins.Manager
 	ProvisionedPlugins provisionedplugins.Manager
 	provisionedPlugins []string
-	log                log.Logger
 }
 
 func (s *updateStep) Title() string {
@@ -164,7 +162,7 @@ func (s *updateStep) ID() string {
 	return UpdateStepID
 }
 
-func (s *updateStep) Run(ctx context.Context, _ *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
+func (s *updateStep) Run(ctx context.Context, log logging.Logger, _ *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
 	p, ok := i.(pluginstore.Plugin)
 	if !ok {
 		return nil, fmt.Errorf("invalid item type %T", i)
@@ -172,19 +170,19 @@ func (s *updateStep) Run(ctx context.Context, _ *advisor.CheckSpec, i any) (*adv
 
 	// Skip if it's a core plugin
 	if p.IsCorePlugin() {
-		s.log.Debug("Skipping core plugin", "plugin", p.ID)
+		log.Debug("Skipping core plugin", "plugin", p.ID)
 		return nil, nil
 	}
 
 	// Skip if it's managed or pinned
 	if s.isManaged(ctx, p.ID) || s.PluginPreinstall.IsPinned(p.ID) {
-		s.log.Debug("Skipping managed or pinned plugin", "plugin", p.ID)
+		log.Debug("Skipping managed or pinned plugin", "plugin", p.ID)
 		return nil, nil
 	}
 
 	// Skip if it's provisioned
 	if s.isProvisioned(ctx, p.ID) {
-		s.log.Debug("Skipping provisioned plugin", "plugin", p.ID)
+		log.Debug("Skipping provisioned plugin", "plugin", p.ID)
 		return nil, nil
 	}
 
diff --git a/apps/advisor/pkg/app/checks/plugincheck/check_test.go b/apps/advisor/pkg/app/checks/plugincheck/check_test.go
index 34fd0b8e544eb..5095ac2f08ac1 100644
--- a/apps/advisor/pkg/app/checks/plugincheck/check_test.go
+++ b/apps/advisor/pkg/app/checks/plugincheck/check_test.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"testing"
 
+	"github.com/grafana/grafana-app-sdk/logging"
 	advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/pkg/plugins"
 	"github.com/grafana/grafana/pkg/plugins/repo"
@@ -169,7 +170,7 @@ func TestRun(t *testing.T) {
 			failures := []advisor.CheckReportFailure{}
 			for _, step := range check.Steps() {
 				for _, item := range items {
-					stepFailures, err := step.Run(context.Background(), &advisor.CheckSpec{}, item)
+					stepFailures, err := step.Run(context.Background(), logging.DefaultLogger, &advisor.CheckSpec{}, item)
 					assert.NoError(t, err)
 					if stepFailures != nil {
 						failures = append(failures, *stepFailures)
diff --git a/apps/advisor/pkg/app/checkscheduler/checkscheduler.go b/apps/advisor/pkg/app/checkscheduler/checkscheduler.go
index 053a964259b3b..8e2bfc1cb23be 100644
--- a/apps/advisor/pkg/app/checkscheduler/checkscheduler.go
+++ b/apps/advisor/pkg/app/checkscheduler/checkscheduler.go
@@ -9,14 +9,13 @@ import (
 
 	"github.com/grafana/grafana-app-sdk/app"
 	"github.com/grafana/grafana-app-sdk/k8s"
+	"github.com/grafana/grafana-app-sdk/logging"
 	"github.com/grafana/grafana-app-sdk/resource"
 	"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
 	advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
-	"github.com/grafana/grafana/pkg/infra/log"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/klog/v2"
 )
 
 const defaultEvaluationInterval = 24 * time.Hour
@@ -31,11 +30,11 @@ type Runner struct {
 	evaluationInterval time.Duration
 	maxHistory         int
 	namespace          string
-	log                log.Logger
+	log                logging.Logger
 }
 
 // NewRunner creates a new Runner.
-func New(cfg app.Config) (app.Runnable, error) {
+func New(cfg app.Config, log logging.Logger) (app.Runnable, error) {
 	// Read config
 	specificConfig, ok := cfg.SpecificConfig.(checkregistry.AdvisorAppConfig)
 	if !ok {
@@ -68,14 +67,15 @@ func New(cfg app.Config) (app.Runnable, error) {
 		evaluationInterval: evalInterval,
 		maxHistory:         maxHistory,
 		namespace:          namespace,
-		log:                log.New("advisor.checkscheduler"),
+		log:                log.With("runner", "advisor.checkscheduler"),
 	}, nil
 }
 
 func (r *Runner) Run(ctx context.Context) error {
 	lastCreated, err := r.checkLastCreated(ctx)
+	logger := r.log.WithContext(ctx)
 	if err != nil {
-		r.log.Error("Error getting last check creation time", "error", err)
+		logger.Error("Error getting last check creation time", "error", err)
 		// Wait for interval to create the next scheduled check
 		lastCreated = time.Now()
 	} else {
@@ -83,7 +83,7 @@ func (r *Runner) Run(ctx context.Context) error {
 		if lastCreated.IsZero() {
 			err = r.createChecks(ctx)
 			if err != nil {
-				klog.Error("Error creating new check reports", "error", err)
+				logger.Error("Error creating new check reports", "error", err)
 			} else {
 				lastCreated = time.Now()
 			}
@@ -103,12 +103,12 @@ func (r *Runner) Run(ctx context.Context) error {
 		case <-ticker.C:
 			err = r.createChecks(ctx)
 			if err != nil {
-				klog.Error("Error creating new check reports", "error", err)
+				logger.Error("Error creating new check reports", "error", err)
 			}
 
-			err = r.cleanupChecks(ctx)
+			err = r.cleanupChecks(ctx, logger)
 			if err != nil {
-				klog.Error("Error cleaning up old check reports", "error", err)
+				logger.Error("Error cleaning up old check reports", "error", err)
 			}
 
 			if nextSendInterval != r.evaluationInterval {
@@ -116,7 +116,7 @@ func (r *Runner) Run(ctx context.Context) error {
 			}
 			ticker.Reset(nextSendInterval)
 		case <-ctx.Done():
-			r.markUnprocessedChecksAsErrored(ctx)
+			r.markUnprocessedChecksAsErrored(ctx, logger)
 			return ctx.Err()
 		}
 	}
@@ -163,7 +163,7 @@ func (r *Runner) createChecks(ctx context.Context) error {
 }
 
 // cleanupChecks deletes the olders checks if the number of checks exceeds the limit.
-func (r *Runner) cleanupChecks(ctx context.Context) error {
+func (r *Runner) cleanupChecks(ctx context.Context, logger logging.Logger) error {
 	list, err := r.client.List(ctx, r.namespace, resource.ListOptions{Limit: -1})
 	if err != nil {
 		return err
@@ -175,7 +175,7 @@ func (r *Runner) cleanupChecks(ctx context.Context) error {
 		labels := check.GetLabels()
 		checkType, ok := labels[checks.TypeLabel]
 		if !ok {
-			klog.Error("Check type not found in labels", "check", check)
+			logger.Error("Check type not found in labels", "check", check)
 			continue
 		}
 		checksByType[checkType] = append(checksByType[checkType], check)
@@ -230,19 +230,19 @@ func getMaxHistory(pluginConfig map[string]string) (int, error) {
 	return maxHistory, nil
 }
 
-func (r *Runner) markUnprocessedChecksAsErrored(ctx context.Context) {
+func (r *Runner) markUnprocessedChecksAsErrored(ctx context.Context, log logging.Logger) {
 	list, err := r.client.List(ctx, r.namespace, resource.ListOptions{})
 	if err != nil {
-		r.log.Error("Error getting checks", "error", err)
+		log.Error("Error getting checks", "error", err)
 		return
 	}
 
 	for _, check := range list.GetItems() {
 		if checks.GetStatusAnnotation(check) == "" {
-			r.log.Error("Check is unprocessed", "check", check.GetStaticMetadata().Identifier())
+			log.Error("Check is unprocessed", "check", check.GetStaticMetadata().Identifier())
 			err := checks.SetStatusAnnotation(ctx, r.client, check, checks.StatusAnnotationError)
 			if err != nil {
-				r.log.Error("Error setting check status to error", "error", err)
+				log.Error("Error setting check status to error", "error", err)
 			}
 		}
 	}
diff --git a/apps/advisor/pkg/app/checkscheduler/checkscheduler_test.go b/apps/advisor/pkg/app/checkscheduler/checkscheduler_test.go
index 16ff33102d6b1..03b7c18783d90 100644
--- a/apps/advisor/pkg/app/checkscheduler/checkscheduler_test.go
+++ b/apps/advisor/pkg/app/checkscheduler/checkscheduler_test.go
@@ -8,10 +8,10 @@ import (
 	"testing"
 	"time"
 
+	"github.com/grafana/grafana-app-sdk/logging"
 	"github.com/grafana/grafana-app-sdk/resource"
 	advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
-	"github.com/grafana/grafana/pkg/infra/log"
 	"github.com/stretchr/testify/assert"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
@@ -31,7 +31,7 @@ func TestRunner_Run(t *testing.T) {
 		runner := &Runner{
 			checkRegistry:      mockCheckService,
 			client:             mockClient,
-			log:                log.NewNopLogger(),
+			log:                logging.DefaultLogger,
 			evaluationInterval: 1 * time.Hour,
 		}
 
@@ -51,7 +51,7 @@ func TestRunner_checkLastCreated_ErrorOnList(t *testing.T) {
 
 	runner := &Runner{
 		client: mockClient,
-		log:    log.NewNopLogger(),
+		log:    logging.DefaultLogger,
 	}
 
 	lastCreated, err := runner.checkLastCreated(context.Background())
@@ -76,7 +76,7 @@ func TestRunner_createChecks_ErrorOnCreate(t *testing.T) {
 	runner := &Runner{
 		checkRegistry: mockCheckService,
 		client:        mockClient,
-		log:           log.NewNopLogger(),
+		log:           logging.DefaultLogger,
 	}
 
 	err := runner.createChecks(context.Background())
@@ -100,7 +100,7 @@ func TestRunner_createChecks_Success(t *testing.T) {
 	runner := &Runner{
 		checkRegistry: mockCheckService,
 		client:        mockClient,
-		log:           log.NewNopLogger(),
+		log:           logging.DefaultLogger,
 	}
 
 	err := runner.createChecks(context.Background())
@@ -116,10 +116,10 @@ func TestRunner_cleanupChecks_ErrorOnList(t *testing.T) {
 
 	runner := &Runner{
 		client: mockClient,
-		log:    log.NewNopLogger(),
+		log:    logging.DefaultLogger,
 	}
 
-	err := runner.cleanupChecks(context.Background())
+	err := runner.cleanupChecks(context.Background(), logging.DefaultLogger)
 	assert.Error(t, err)
 }
 
@@ -137,10 +137,10 @@ func TestRunner_cleanupChecks_WithinMax(t *testing.T) {
 
 	runner := &Runner{
 		client: mockClient,
-		log:    log.NewNopLogger(),
+		log:    logging.DefaultLogger,
 	}
 
-	err := runner.cleanupChecks(context.Background())
+	err := runner.cleanupChecks(context.Background(), logging.DefaultLogger)
 	assert.NoError(t, err)
 }
 
@@ -167,9 +167,9 @@ func TestRunner_cleanupChecks_ErrorOnDelete(t *testing.T) {
 	runner := &Runner{
 		client:     mockClient,
 		maxHistory: defaultMaxHistory,
-		log:        log.NewNopLogger(),
+		log:        logging.DefaultLogger,
 	}
-	err := runner.cleanupChecks(context.Background())
+	err := runner.cleanupChecks(context.Background(), logging.DefaultLogger)
 	assert.ErrorContains(t, err, "delete error")
 }
 
@@ -203,9 +203,9 @@ func TestRunner_cleanupChecks_Success(t *testing.T) {
 	runner := &Runner{
 		client:     mockClient,
 		maxHistory: defaultMaxHistory,
-		log:        log.NewNopLogger(),
+		log:        logging.DefaultLogger,
 	}
-	err := runner.cleanupChecks(context.Background())
+	err := runner.cleanupChecks(context.Background(), logging.DefaultLogger)
 	assert.NoError(t, err)
 	assert.Equal(t, []string{"check-0"}, itemsDeleted)
 }
@@ -274,9 +274,9 @@ func Test_markUnprocessedChecksAsErrored(t *testing.T) {
 	}
 	runner := &Runner{
 		client: mockClient,
-		log:    log.NewNopLogger(),
+		log:    logging.DefaultLogger,
 	}
-	runner.markUnprocessedChecksAsErrored(context.Background())
+	runner.markUnprocessedChecksAsErrored(context.Background(), logging.DefaultLogger)
 	assert.Equal(t, "check-1", identifier.Name)
 	assert.Equal(t, "/metadata/annotations", patchOperation.Path)
 	expectedAnnotations := map[string]string{
diff --git a/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go
index f8c7e22236802..5487616319ab5 100644
--- a/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go
+++ b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go
@@ -7,11 +7,11 @@ import (
 
 	"github.com/grafana/grafana-app-sdk/app"
 	"github.com/grafana/grafana-app-sdk/k8s"
+	"github.com/grafana/grafana-app-sdk/logging"
 	"github.com/grafana/grafana-app-sdk/resource"
 	advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
-	"github.com/grafana/grafana/pkg/infra/log"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
@@ -23,13 +23,13 @@ type Runner struct {
 	checkRegistry checkregistry.CheckService
 	client        resource.Client
 	namespace     string
-	log           log.Logger
+	log           logging.Logger
 	retryAttempts int
 	retryDelay    time.Duration
 }
 
 // NewRunner creates a new Runner.
-func New(cfg app.Config) (app.Runnable, error) {
+func New(cfg app.Config, log logging.Logger) (app.Runnable, error) {
 	// Read config
 	specificConfig, ok := cfg.SpecificConfig.(checkregistry.AdvisorAppConfig)
 	if !ok {
@@ -52,33 +52,34 @@ func New(cfg app.Config) (app.Runnable, error) {
 		checkRegistry: checkRegistry,
 		client:        client,
 		namespace:     namespace,
-		log:           log.New("advisor.checktyperegisterer"),
-		retryAttempts: 3,
-		retryDelay:    time.Second * 5,
+		log:           log.With("runner", "advisor.checktyperegisterer"),
+		retryAttempts: 5,
+		retryDelay:    time.Second * 10,
 	}, nil
 }
 
-func (r *Runner) createOrUpdate(ctx context.Context, obj resource.Object) error {
+func (r *Runner) createOrUpdate(ctx context.Context, log logging.Logger, obj resource.Object) error {
 	id := obj.GetStaticMetadata().Identifier()
 	_, err := r.client.Create(ctx, id, obj, resource.CreateOptions{})
 	if err != nil {
 		if errors.IsAlreadyExists(err) {
 			// Already exists, update
-			r.log.Debug("Check type already exists, updating", "identifier", id)
+			log.Debug("Check type already exists, updating", "identifier", id)
 			_, err = r.client.Update(ctx, id, obj, resource.UpdateOptions{})
 			if err != nil {
 				// Ignore the error, it's probably due to a race condition
-				r.log.Error("Error updating check type", "error", err)
+				log.Error("Error updating check type", "error", err)
 			}
 			return nil
 		}
 		return err
 	}
-	r.log.Debug("Check type registered successfully", "identifier", id)
+	log.Debug("Check type registered successfully", "identifier", id)
 	return nil
 }
 
 func (r *Runner) Run(ctx context.Context) error {
+	logger := r.log.WithContext(ctx)
 	for _, t := range r.checkRegistry.Checks() {
 		steps := t.Steps()
 		stepTypes := make([]advisorv0alpha1.CheckTypeStep, len(steps))
@@ -105,17 +106,19 @@ func (r *Runner) Run(ctx context.Context) error {
 			},
 		}
 		for i := 0; i < r.retryAttempts; i++ {
-			err := r.createOrUpdate(ctx, obj)
+			err := r.createOrUpdate(ctx, logger, obj)
 			if err != nil {
-				r.log.Error("Error creating check type, retrying", "error", err, "attempt", i+1)
+				logger.Error("Error creating check type, retrying", "error", err, "attempt", i+1)
 				if i == r.retryAttempts-1 {
-					r.log.Error("Unable to register check type")
+					logger.Error("Unable to register check type")
 				} else {
-					time.Sleep(r.retryDelay)
+					// Calculate exponential backoff delay: baseDelay * 2^attempt
+					delay := r.retryDelay * time.Duration(1<<i)
+					time.Sleep(delay)
 				}
 				continue
 			}
-			r.log.Debug("Check type registered successfully", "check_type", t.ID())
+			logger.Debug("Check type registered successfully", "check_type", t.ID())
 			break
 		}
 	}
diff --git a/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go
index 4d4bab9adf3d6..d8fe810c94511 100644
--- a/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go
+++ b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go
@@ -6,10 +6,10 @@ import (
 	"fmt"
 	"testing"
 
+	"github.com/grafana/grafana-app-sdk/logging"
 	"github.com/grafana/grafana-app-sdk/resource"
 	advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
-	"github.com/grafana/grafana/pkg/infra/log"
 	k8sErrs "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 )
@@ -119,7 +119,7 @@ func TestCheckTypesRegisterer_Run(t *testing.T) {
 					updateFunc: tt.updateFunc,
 				},
 				namespace:     "custom-namespace",
-				log:           log.New("test"),
+				log:           logging.DefaultLogger,
 				retryAttempts: 1,
 				retryDelay:    0,
 			}
@@ -180,7 +180,7 @@ func (m *mockStep) Resolution() string {
 	return ""
 }
 
-func (m *mockStep) Run(ctx context.Context, obj *advisorv0alpha1.CheckSpec, item any) (*advisorv0alpha1.CheckReportFailure, error) {
+func (m *mockStep) Run(ctx context.Context, log logging.Logger, obj *advisorv0alpha1.CheckSpec, item any) (*advisorv0alpha1.CheckReportFailure, error) {
 	return nil, nil
 }
 
diff --git a/apps/advisor/pkg/app/utils.go b/apps/advisor/pkg/app/utils.go
index 2dd4caf3de89b..e9f0adaafcd33 100644
--- a/apps/advisor/pkg/app/utils.go
+++ b/apps/advisor/pkg/app/utils.go
@@ -7,6 +7,7 @@ import (
 	"slices"
 	"sync"
 
+	"github.com/grafana/grafana-app-sdk/logging"
 	"github.com/grafana/grafana-app-sdk/resource"
 	advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
@@ -30,7 +31,7 @@ func getCheck(obj resource.Object, checkMap map[string]checks.Check) (checks.Che
 	return c, nil
 }
 
-func processCheck(ctx context.Context, client resource.Client, obj resource.Object, check checks.Check) error {
+func processCheck(ctx context.Context, log logging.Logger, client resource.Client, obj resource.Object, check checks.Check) error {
 	status := checks.GetStatusAnnotation(obj)
 	if status != "" {
 		// Check already processed
@@ -51,7 +52,7 @@ func processCheck(ctx context.Context, client resource.Client, obj resource.Obje
 	}
 	// Run the steps
 	steps := check.Steps()
-	failures, err := runStepsInParallel(ctx, &c.Spec, steps, items)
+	failures, err := runStepsInParallel(ctx, log, &c.Spec, steps, items)
 	if err != nil {
 		setErr := checks.SetStatusAnnotation(ctx, client, obj, checks.StatusAnnotationError)
 		if setErr != nil {
@@ -77,7 +78,7 @@ func processCheck(ctx context.Context, client resource.Client, obj resource.Obje
 	}, resource.PatchOptions{}, obj)
 }
 
-func processCheckRetry(ctx context.Context, client resource.Client, obj resource.Object, check checks.Check) error {
+func processCheckRetry(ctx context.Context, log logging.Logger, client resource.Client, obj resource.Object, check checks.Check) error {
 	status := checks.GetStatusAnnotation(obj)
 	if status == "" || status == checks.StatusAnnotationError {
 		// Check not processed yet or errored
@@ -104,7 +105,7 @@ func processCheckRetry(ctx context.Context, client resource.Client, obj resource
 	}
 	// Run the steps
 	steps := check.Steps()
-	failures, err := runStepsInParallel(ctx, &c.Spec, steps, []any{item})
+	failures, err := runStepsInParallel(ctx, log, &c.Spec, steps, []any{item})
 	if err != nil {
 		setErr := checks.SetStatusAnnotation(ctx, client, obj, checks.StatusAnnotationError)
 		if setErr != nil {
@@ -143,7 +144,7 @@ func processCheckRetry(ctx context.Context, client resource.Client, obj resource
 	}, resource.PatchOptions{}, obj)
 }
 
-func runStepsInParallel(ctx context.Context, spec *advisorv0alpha1.CheckSpec, steps []checks.Step, items []any) ([]advisorv0alpha1.CheckReportFailure, error) {
+func runStepsInParallel(ctx context.Context, log logging.Logger, spec *advisorv0alpha1.CheckSpec, steps []checks.Step, items []any) ([]advisorv0alpha1.CheckReportFailure, error) {
 	reportFailures := []advisorv0alpha1.CheckReportFailure{}
 	var internalErr error
 	var wg sync.WaitGroup
@@ -166,7 +167,8 @@ func runStepsInParallel(ctx context.Context, spec *advisorv0alpha1.CheckSpec, st
 							err = fmt.Errorf("panic recovered in step %s: %v", step.ID(), r)
 						}
 					}()
-					stepErr, err = step.Run(ctx, spec, item)
+					logger := log.With("step", step.ID())
+					stepErr, err = step.Run(ctx, logger, spec, item)
 				}()
 				mu.Lock()
 				defer mu.Unlock()
diff --git a/apps/advisor/pkg/app/utils_test.go b/apps/advisor/pkg/app/utils_test.go
index 5d8e4441a1849..29b4474205b94 100644
--- a/apps/advisor/pkg/app/utils_test.go
+++ b/apps/advisor/pkg/app/utils_test.go
@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"testing"
 
+	"github.com/grafana/grafana-app-sdk/logging"
 	"github.com/grafana/grafana-app-sdk/resource"
 	advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
 	"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
@@ -62,7 +63,7 @@ func TestProcessCheck(t *testing.T) {
 		items: []any{"item"},
 	}
 
-	err = processCheck(ctx, client, obj, check)
+	err = processCheck(ctx, logging.DefaultLogger, client, obj, check)
 	assert.NoError(t, err)
 	assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation])
 }
@@ -89,7 +90,7 @@ func TestProcessMultipleCheckItems(t *testing.T) {
 		items: items,
 	}
 
-	err = processCheck(ctx, client, obj, check)
+	err = processCheck(ctx, logging.DefaultLogger, client, obj, check)
 	assert.NoError(t, err)
 	assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation])
 	r := client.lastValue.(advisorv0alpha1.CheckV0alpha1StatusReport)
@@ -104,7 +105,7 @@ func TestProcessCheck_AlreadyProcessed(t *testing.T) {
 	ctx := context.TODO()
 	check := &mockCheck{}
 
-	err := processCheck(ctx, client, obj, check)
+	err := processCheck(ctx, logging.DefaultLogger, client, obj, check)
 	assert.NoError(t, err)
 }
 
@@ -124,7 +125,7 @@ func TestProcessCheck_RunError(t *testing.T) {
 		err:   errors.New("run error"),
 	}
 
-	err = processCheck(ctx, client, obj, check)
+	err = processCheck(ctx, logging.DefaultLogger, client, obj, check)
 	assert.Error(t, err)
 	assert.Equal(t, "error", obj.GetAnnotations()[checks.StatusAnnotation])
 }
@@ -145,7 +146,7 @@ func TestProcessCheck_RunRecoversFromPanic(t *testing.T) {
 		runPanics: true,
 	}
 
-	err = processCheck(ctx, client, obj, check)
+	err = processCheck(ctx, logging.DefaultLogger, client, obj, check)
 	assert.Error(t, err)
 	assert.Contains(t, err.Error(), "panic recovered in step")
 	assert.Equal(t, "error", obj.GetAnnotations()[checks.StatusAnnotation])
@@ -164,7 +165,7 @@ func TestProcessCheckRetry_NoRetry(t *testing.T) {
 
 	check := &mockCheck{}
 
-	err = processCheckRetry(ctx, client, obj, check)
+	err = processCheckRetry(ctx, logging.DefaultLogger, client, obj, check)
 	assert.NoError(t, err)
 }
 
@@ -187,7 +188,7 @@ func TestProcessCheckRetry_RetryError(t *testing.T) {
 		err:   errors.New("retry error"),
 	}
 
-	err = processCheckRetry(ctx, client, obj, check)
+	err = processCheckRetry(ctx, logging.DefaultLogger, client, obj, check)
 	assert.Error(t, err)
 	assert.Equal(t, "error", obj.GetAnnotations()[checks.StatusAnnotation])
 }
@@ -216,7 +217,7 @@ func TestProcessCheckRetry_Success(t *testing.T) {
 		items: []any{"item"},
 	}
 
-	err = processCheckRetry(ctx, client, obj, check)
+	err = processCheckRetry(ctx, logging.DefaultLogger, client, obj, check)
 	assert.NoError(t, err)
 	assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation])
 	assert.Empty(t, obj.GetAnnotations()[checks.RetryAnnotation])
@@ -262,7 +263,7 @@ type mockStep struct {
 	panics bool
 }
 
-func (m *mockStep) Run(ctx context.Context, obj *advisorv0alpha1.CheckSpec, items any) (*advisorv0alpha1.CheckReportFailure, error) {
+func (m *mockStep) Run(ctx context.Context, log logging.Logger, obj *advisorv0alpha1.CheckSpec, items any) (*advisorv0alpha1.CheckReportFailure, error) {
 	if m.panics {
 		panic("panic")
 	}


Reviews:
user: login: wbrowne
body: LGTM
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T09:34:04Z
user: login: andresmgot
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T11:33:55Z
user: login: andresmgot
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T11:35:15Z

Review comments:
diff_hunk: @@ -175,7 +175,7 @@ func (r *Runner) cleanupChecks(ctx context.Context) error {
 		labels := check.GetLabels()
 		checkType, ok := labels[checks.TypeLabel]
 		if !ok {
-			klog.Error("Check type not found in labels", "check", check)
+			r.log.Error("Check type not found in labels", "check", check)
path: apps/advisor/pkg/app/checkscheduler/checkscheduler.go
user: login: wbrowne
body: I assume this doesn't need the contextual info?
created_at: 2025-05-06T09:30:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -105,17 +106,19 @@ func (r *Runner) Run(ctx context.Context) error {
 			},
 		}
 		for i := 0; i < r.retryAttempts; i++ {
-			err := r.createOrUpdate(ctx, obj)
+			err := r.createOrUpdate(ctx, logger, obj)
 			if err != nil {
-				r.log.Error("Error creating check type, retrying", "error", err, "attempt", i+1)
+				logger.Error("Error creating check type, retrying", "error", err, "attempt", i+1)
 				if i == r.retryAttempts-1 {
-					r.log.Error("Unable to register check type")
+					logger.Error("Unable to register check type")
 				} else {
-					time.Sleep(r.retryDelay)
+					// Calculate exponential backoff delay: baseDelay * 2^attempt
+					delay := r.retryDelay * time.Duration(1<<i)
+					time.Sleep(delay)
path: apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go
user: login: wbrowne
body: Nit: Might be nice to test this - you could extract this to a func that you stub in a test for example
created_at: 2025-05-06T09:33:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -175,7 +175,7 @@ func (r *Runner) cleanupChecks(ctx context.Context) error {
 		labels := check.GetLabels()
 		checkType, ok := labels[checks.TypeLabel]
 		if !ok {
-			klog.Error("Check type not found in labels", "check", check)
+			r.log.Error("Check type not found in labels", "check", check)
path: apps/advisor/pkg/app/checkscheduler/checkscheduler.go
user: login: andresmgot
body: I missed this 👍 
created_at: 2025-05-06T11:33:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -105,17 +106,19 @@ func (r *Runner) Run(ctx context.Context) error {
 			},
 		}
 		for i := 0; i < r.retryAttempts; i++ {
-			err := r.createOrUpdate(ctx, obj)
+			err := r.createOrUpdate(ctx, logger, obj)
 			if err != nil {
-				r.log.Error("Error creating check type, retrying", "error", err, "attempt", i+1)
+				logger.Error("Error creating check type, retrying", "error", err, "attempt", i+1)
 				if i == r.retryAttempts-1 {
-					r.log.Error("Unable to register check type")
+					logger.Error("Unable to register check type")
 				} else {
-					time.Sleep(r.retryDelay)
+					// Calculate exponential backoff delay: baseDelay * 2^attempt
+					delay := r.retryDelay * time.Duration(1<<i)
+					time.Sleep(delay)
path: apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go
user: login: andresmgot
body: it's a bit difficult / cumbersome to test this and if it's mocked we are not getting that much out of it so that's why I skipped it
created_at: 2025-05-06T11:35:15Z
author_association: CONTRIBUTOR

PR comments:
user: login: andresmgot
created_at: 2025-05-06T07:54:51Z
body: /deploy-to-hg 
author_association: CONTRIBUTOR
user: login: ephemeral-instances-bot[bot]
created_at: 2025-05-06T07:55:22Z
body: - Preparing your instance. A comment containing your instance's url will be added to this PR when the instance is ready.
- Your instance will be ready in ~10 minutes. [Follow the workflow progress](https://github.com/grafana/grafana/actions/runs/14854491758)
- Slack channel: #proj-ephemeral-hg-instances
- Building instance with **advisorLog** oss branch and **main** enterprise branch. [How to choose a branch](https://github.com/grafana/hosted-grafana/wiki/Ephemeral-instances#deploying-a-grafana-and-grafana-enterprise-branch-together)
author_association: NONE
user: login: ephemeral-instances-bot[bot]
created_at: 2025-05-06T08:14:28Z
body: - Your instance can be accessed at: https://ephemeral15111821104979andres.grafana-dev.net
- The instance is not using the CDN assets.
- [How to access / How to update instance config / How to build a specific branch](https://github.com/grafana/hosted-grafana/wiki/Ephemeral-instances#choosing-which-oss-and-enterprise-branches-are-used-to-build-the-instance)
author_association: NONE