From 9fa3dee44c684e745121d446a3b9b20883f6c9d5 Mon Sep 17 00:00:00 2001 From: "hypershift-jira-solve-ci[bot]" <254971726+hypershift-jira-solve-ci[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2026 18:59:31 +0000 Subject: [PATCH] fix(cli): initialize controller-runtime logger in product-cli The hcp CLI (product-cli) never called ctrl.SetLogger() before using controller-runtime's client.New() via cmd/util.GetClient(). This caused a noisy "[controller-runtime] log.SetLogger(...) was never called" warning with a full goroutine stack trace on every hcp create cluster invocation, degrading the customer experience. Add the same ctrl.SetLogger(zap.New(zap.JSONEncoder(...))) call used by every other binary in the repo to product-cli/main.go, early in main() before any cobra command execution. Signed-off-by: OpenShift CI Bot Co-Authored-By: Claude Opus 4.6 --- product-cli/main.go | 15 ++++++++++++++ product-cli/main_test.go | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 product-cli/main_test.go diff --git a/product-cli/main.go b/product-cli/main.go index 270d232ab501..328acbcc9e06 100644 --- a/product-cli/main.go +++ b/product-cli/main.go @@ -25,10 +25,25 @@ import ( "github.com/openshift/hypershift/product-cli/cmd/create" "github.com/openshift/hypershift/product-cli/cmd/destroy" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + "github.com/go-logr/logr" "github.com/spf13/cobra" + "go.uber.org/zap/zapcore" ) +func newLogger(extraOpts ...zap.Opts) logr.Logger { + opts := []zap.Opts{zap.JSONEncoder(func(o *zapcore.EncoderConfig) { + o.EncodeTime = zapcore.RFC3339TimeEncoder + })} + opts = append(opts, extraOpts...) + return zap.New(opts...) +} + func main() { + ctrl.SetLogger(newLogger()) + cmd := &cobra.Command{ Use: "hcp", SilenceUsage: true, diff --git a/product-cli/main_test.go b/product-cli/main_test.go new file mode 100644 index 000000000000..e9e8b5c39ddc --- /dev/null +++ b/product-cli/main_test.go @@ -0,0 +1,42 @@ +package main + +import ( + "bytes" + "encoding/json" + "testing" + "time" + + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestNewLogger(t *testing.T) { + var buf bytes.Buffer + logger := newLogger(zap.WriteTo(&buf)) + + if !logger.Enabled() { + t.Fatal("expected logger to be enabled") + } + + logger.Info("test message", "key", "value") + + var entry map[string]interface{} + if err := json.Unmarshal(buf.Bytes(), &entry); err != nil { + t.Fatalf("expected JSON log output, got error: %v\nraw output: %s", err, buf.String()) + } + + ts, ok := entry["ts"].(string) + if !ok { + t.Fatalf("expected string 'ts' field, got: %v", entry["ts"]) + } + if _, err := time.Parse(time.RFC3339, ts); err != nil { + t.Errorf("expected RFC3339 timestamp, got %q: %v", ts, err) + } + + if msg, _ := entry["msg"].(string); msg != "test message" { + t.Errorf("expected msg 'test message', got %q", msg) + } + + if v, _ := entry["key"].(string); v != "value" { + t.Errorf("expected key 'value', got %q", v) + } +}