Skip to content

logging: route controller-runtime binaries through slog (retire zap) - #535

Open
Philip Lombardi (plombardi89) wants to merge 4 commits into
mainfrom
operator-slog-logger
Open

logging: route controller-runtime binaries through slog (retire zap)#535
Philip Lombardi (plombardi89) wants to merge 4 commits into
mainfrom
operator-slog-logger

Conversation

@plombardi89

@plombardi89 Philip Lombardi (plombardi89) commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Routes all controller-runtime binaries through slog instead of the kubebuilder-default zap backend, so the whole repo logs through log/slog (matching metalman and the agent). Each site swaps:

// before
ctrl.SetLogger(zap.New(zap.UseDevMode(true)))
// after
ctrl.SetLogger(logr.FromSlogHandler(slog.Default().Handler()))

controller-runtime's logging facade is logr, so a manager must set some logr.Logger; logr.FromSlogHandler adapts an slog handler to satisfy it (minimal form, mirroring cmd/metalman/main.go).

Changed sites

  • cmd/unbounded-operator/main.go
  • cmd/machina/machina/controller/manager.go
  • cmd/machine-ops-controller/main.go
  • cmd/playpen-operator/main.go
  • e2e/operator/reaper_e2e_test.go, e2e/operator/slice_window_e2e_test.go (log.IntoContext)

Dependency cleanup

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

slog.Default() is an Info-level handler, and logr V(n) maps to slog level -n, so logr V(1)+ logs (e.g. the migration reaper's routine V(1) lines) are now suppressed by default rather than printed. zap.New(zap.UseDevMode(true)) previously pinned the level to Debug, which made V-level verbosity ineffective. With slog, V(1) becomes a real quiet lever - which also unblocks the fix in #533 (BootstrapMaintainer log churn).

Testing

  • go build ./..., go vet -tags=e2e ./e2e/operator/..., make fmt, make lint (0 issues), go test ./cmd/... ./internal/operator/... all pass.

Closes #534
Refs #533

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.

Copilot AI 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.

Pull request overview

This PR updates unbounded-operator to route controller-runtime logging through the repository-standard log/slog stack (via logr.FromSlogHandler) instead of the kubebuilder zap backend. This aligns the operator’s logging behavior with other binaries (e.g., metalman, agent) and makes logr verbosity levels (V(n)) meaningful by default.

Changes:

  • Switch controller-runtime logger initialization from zap.New(zap.UseDevMode(true)) to logr.FromSlogHandler(slog.Default().Handler()).
  • Drop the operator’s controller-runtime zap logger import and add log/slog + github.com/go-logr/logr imports.
  • Document the intended verbosity behavior (V(1)+ suppressed under the default Info-level slog handler) inline.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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
Copilot AI review requested due to automatic review settings July 22, 2026 05:11
@plombardi89 Philip Lombardi (plombardi89) changed the title operator: log via slog instead of zap logging: route controller-runtime binaries through slog (retire zap) Jul 22, 2026

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment thread go.mod
Comment on lines 149 to 152
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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

go mod tidy was run and both files already reflect its output - go mod tidy -diff reports no pending changes, so CI's tidy-check passes as-is.

go.sum keeps github.com/go-logr/zapr on purpose: it is still in the module graph via sigs.k8s.io/controller-runtime@v0.24.1, which requires zapr in its own go.mod (go mod graph shows sigs.k8s.io/controller-runtime@v0.24.1 github.com/go-logr/zapr@v1.3.0). go.sum must carry checksums for every module in the graph, not just direct requirements. What changed here is only that zapr is no longer a direct dependency, so it correctly leaves the go.mod require block while its go.sum checksums remain. Removing those lines manually would make go mod tidy re-add them and fail the tidy-check.

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment on lines +144 to +147
// 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.
Copilot AI review requested due to automatic review settings July 22, 2026 15:43

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unify repository logging on slog (retire controller-runtime zap backend)

3 participants