From b02481ba8ef14e515c3feb87f7782576c83e9e22 Mon Sep 17 00:00:00 2001 From: Philip Lombardi <893096+plombardi89@users.noreply.github.com> Date: Tue, 21 Jul 2026 23:20:44 -0400 Subject: [PATCH 1/2] operator: log via slog instead of zap Route controller-runtime's logr logging through slog (logr.FromSlogHandler(slog.Default().Handler())) instead of the kubebuilder-default zap dev-mode backend, matching metalman (cmd/metalman/main.go) and the agent (cmd/agent/internal/cmd/context.go) and the rest of the repo, which standardize on log/slog. Behavior change: slog.Default() is an Info-level handler, and logr V(n) maps to slog level -n, so logr V(1)+ logs (for example the migration reaper's routine V(1) lines) are now suppressed by default rather than printed. zap dev-mode previously pinned the level to Debug, which rendered V-level verbosity ineffective; with slog, V(1) becomes a real quiet lever. Unifying the remaining zap-based controller binaries (machina, machine-ops-controller, playpen-operator) onto slog is tracked separately. --- cmd/unbounded-operator/main.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/unbounded-operator/main.go b/cmd/unbounded-operator/main.go index 07ad403cb..6a57acfff 100644 --- a/cmd/unbounded-operator/main.go +++ b/cmd/unbounded-operator/main.go @@ -6,11 +6,13 @@ package main import ( "context" "fmt" + "log/slog" "os" "os/signal" "strconv" "syscall" + "github.com/go-logr/logr" "github.com/spf13/cobra" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" appsv1 "k8s.io/api/apps/v1" @@ -25,7 +27,6 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" unboundedv1alpha3 "github.com/Azure/unbounded/api/machina/v1alpha3" @@ -140,7 +141,11 @@ func resolveAPIServerEndpoint(ctx context.Context, override string, clientset ku } func run(ctx context.Context, cfg config) error { - ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + // Route controller-runtime's logr logging through slog, consistent with the + // rest of the repo (metalman, agent). slog.Default() is an Info-level + // handler, so logr V(1)+ maps to sub-Info slog levels and is suppressed by + // default. + ctrl.SetLogger(logr.FromSlogHandler(slog.Default().Handler())) scheme := runtimeScheme() From db2d7f6bf50b603e1e58752cc474cd5c28dbc14f Mon Sep 17 00:00:00 2001 From: Philip Lombardi <893096+plombardi89@users.noreply.github.com> Date: Wed, 22 Jul 2026 01:11:13 -0400 Subject: [PATCH 2/2] logging: route remaining controller-runtime binaries through slog Follow the operator's switch by moving the last zap-based controller binaries onto slog, so the whole repo logs through log/slog. Each replaces ctrl.SetLogger(zap.New(zap.UseDevMode(true))) with ctrl.SetLogger(logr.FromSlogHandler(slog.Default().Handler())) - cmd/machina/machina/controller/manager.go - cmd/machine-ops-controller/main.go - cmd/playpen-operator/main.go - e2e/operator/reaper_e2e_test.go and slice_window_e2e_test.go (log.IntoContext) No source file imports sigs.k8s.io/controller-runtime/pkg/log/zap anymore, so go mod tidy drops github.com/go-logr/zapr. go.uber.org/zap remains only as a transitive dependency of go-libp2p-kad-dht (via internal/gantry/discovery), not of our logging. Behavior change (same as the operator): slog.Default() is an Info-level handler and logr V(n) maps to slog level -n, so logr V(1)+ logs are now suppressed by default rather than printed under zap dev-mode. Closes #534 --- cmd/machina/machina/controller/manager.go | 5 +++-- cmd/machine-ops-controller/main.go | 5 +++-- cmd/playpen-operator/main.go | 5 +++-- e2e/operator/reaper_e2e_test.go | 5 +++-- e2e/operator/slice_window_e2e_test.go | 5 +++-- go.mod | 1 - 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/cmd/machina/machina/controller/manager.go b/cmd/machina/machina/controller/manager.go index 7a1acb9b2..07f519242 100644 --- a/cmd/machina/machina/controller/manager.go +++ b/cmd/machina/machina/controller/manager.go @@ -6,7 +6,9 @@ package controller import ( "context" "fmt" + "log/slog" + "github.com/go-logr/logr" certificatesv1 "k8s.io/api/certificates/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -18,7 +20,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" unboundedv1alpha3 "github.com/Azure/unbounded/api/machina/v1alpha3" @@ -35,7 +36,7 @@ func init() { // RunManager runs the controller manager. func RunManager(ctx context.Context, cfg Config) error { - ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + ctrl.SetLogger(logr.FromSlogHandler(slog.Default().Handler())) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, diff --git a/cmd/machine-ops-controller/main.go b/cmd/machine-ops-controller/main.go index d0d3203cf..6a271138e 100644 --- a/cmd/machine-ops-controller/main.go +++ b/cmd/machine-ops-controller/main.go @@ -9,18 +9,19 @@ import ( "encoding/hex" "errors" "fmt" + "log/slog" "os" "os/signal" "strings" "syscall" + "github.com/go-logr/logr" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" unboundedv1alpha3 "github.com/Azure/unbounded/api/machina/v1alpha3" @@ -86,7 +87,7 @@ type config struct { } func run(ctx context.Context, cfg config) error { - ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + ctrl.SetLogger(logr.FromSlogHandler(slog.Default().Handler())) if (cfg.siteName == "") != (cfg.providerName == "") { return errors.New(errSiteProviderPair) diff --git a/cmd/playpen-operator/main.go b/cmd/playpen-operator/main.go index 7da3377f1..be63127ca 100644 --- a/cmd/playpen-operator/main.go +++ b/cmd/playpen-operator/main.go @@ -6,10 +6,12 @@ package main import ( "context" "fmt" + "log/slog" "os" "os/signal" "syscall" + "github.com/go-logr/logr" "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" @@ -19,7 +21,6 @@ import ( apiregclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log/zap" "github.com/Azure/unbounded/internal/playpen/operator" "github.com/Azure/unbounded/internal/version" @@ -91,7 +92,7 @@ func main() { } func run(ctx context.Context, cfg operator.Config) error { - ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + ctrl.SetLogger(logr.FromSlogHandler(slog.Default().Handler())) scheme := runtimeScheme() restConfig := ctrl.GetConfigOrDie() diff --git a/e2e/operator/reaper_e2e_test.go b/e2e/operator/reaper_e2e_test.go index 975e95986..0e88ce908 100644 --- a/e2e/operator/reaper_e2e_test.go +++ b/e2e/operator/reaper_e2e_test.go @@ -22,6 +22,7 @@ import ( "encoding/json" "errors" "fmt" + "log/slog" "net" "os" "os/exec" @@ -30,6 +31,7 @@ import ( "testing" "time" + "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" authenticationv1 "k8s.io/api/authentication/v1" authorizationv1 "k8s.io/api/authorization/v1" @@ -52,7 +54,6 @@ import ( "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" unboundedv1alpha3 "github.com/Azure/unbounded/api/machina/v1alpha3" netcontroller "github.com/Azure/unbounded/internal/net/controller" @@ -128,7 +129,7 @@ func TestOperatorReaperMigration(t *testing.T) { applyCRDs(t, kubeconfig, repoRoot) cli := newClient(t, kubeconfig) - ctx := log.IntoContext(context.Background(), zap.New(zap.UseDevMode(true))) + ctx := log.IntoContext(context.Background(), logr.FromSlogHandler(slog.Default().Handler())) stageNamespaces(ctx, t, cli) stageLegacyWorkloads(ctx, t, cli) diff --git a/e2e/operator/slice_window_e2e_test.go b/e2e/operator/slice_window_e2e_test.go index f362aedef..a45bcbba0 100644 --- a/e2e/operator/slice_window_e2e_test.go +++ b/e2e/operator/slice_window_e2e_test.go @@ -13,10 +13,12 @@ package operatore2e import ( "context" "fmt" + "log/slog" "net" "testing" "time" + "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -25,7 +27,6 @@ import ( utilwait "k8s.io/apimachinery/pkg/util/wait" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" ) const sliceWindowClusterName = "operator-slice-window-e2e" @@ -57,7 +58,7 @@ func TestSiteControllerPreservesSlicesDuringMigrationWindow(t *testing.T) { applyCRDs(t, kubeconfig, repoRoot) cli := newClient(t, kubeconfig) - ctx := log.IntoContext(context.Background(), zap.New(zap.UseDevMode(true))) + ctx := log.IntoContext(context.Background(), logr.FromSlogHandler(slog.Default().Handler())) // The restricted SiteController identity's ServiceAccount lives in targetNS. mustCreate(ctx, t, cli, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: targetNS}}) diff --git a/go.mod b/go.mod index c13166415..9e4cee453 100644 --- a/go.mod +++ b/go.mod @@ -149,7 +149,6 @@ require ( github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-logr/zapr v1.3.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect