Skip to content

Conversation

@qiujian16
Copy link
Contributor

No description provided.

@coderabbitai
Copy link

coderabbitai bot commented Dec 3, 2025

Walkthrough

Replaces the custom Zap/OCM logger and dynamic viper/fsnotify log config with klog (k8s.io/klog/v2), removes the pkg/logger implementation, and threads context.Context-bound klog loggers through servers, brokers, controllers, dispatchers, event broadcaster, DB listeners, and many public APIs (Start/Serve/Register/constructors).

Changes

Cohort / File(s) Summary
Top-level commands & wiring
cmd/maestro/main.go, cmd/maestro/agent/cmd.go, cmd/maestro/migrate/cmd.go
Remove viper/fsnotify and custom Zap logger usage; switch to standard log/klog; minor comment fix; replace global fatal/error calls with klog/std log variants.
Serve command & orchestration
cmd/maestro/servecmd/cmd.go
Thread context into server constructors and startup/shutdown flows; create per-server klog logger; update constructors to accept ctx and use context-aware logging; propagate ctx to Start/Stop.
OTLP & environment init
cmd/maestro/common/otlp_sdk.go, cmd/maestro/environments/framework.go
Replace Zap logger with klog; change InstallOpenTelemetryTracer signature to accept klog.Logger; migrate startup/error logs to klog and adjust verbosity.
API server & routes
cmd/maestro/server/api_server.go, cmd/maestro/server/routes.go
NewAPIServer, Serve, Start, and routes now accept/use context.Context; per-request logging via klog.FromContext(ctx); register logger middleware during router setup.
gRPC server & broker
cmd/maestro/server/grpc_server.go, cmd/maestro/server/grpc_broker.go
NewGRPCServer/NewGRPCBroker and Start updated to accept ctx; propagate ctx through TLS/mTLS, interceptors, Publish/Subscribe flows; use context-bound klog for structured logs; several signatures changed.
Health & metrics servers
cmd/maestro/server/healthcheck_server.go, cmd/maestro/server/metrics_server.go
Constructors and Serve/Start methods now accept ctx; register logger middleware; migrate startup/shutdown and handler logs to context klog.
Logging infra rewritten
cmd/maestro/server/logging/*
Request logging middleware redesigned to RegisterLoggerMiddleware(ctx, router); LoggingWriter and formatter signatures now accept klog.Logger; debug gates use klog.V(4).Enabled().
Controllers & framework
cmd/maestro/server/controllers.go, pkg/controllers/*, pkg/controllers/framework_test.go, pkg/controllers/status_controller.go
Convert controllers from stop-channel to context.Context patterns (Run, workers, handlers accept ctx); NewControllersServer accepts ctx; logging moved to klog.FromContext; tests updated.
Event broadcaster & event server
cmd/maestro/server/event_server.go, pkg/event/event.go
EventBroadcaster methods (Register/Unregister/Start) accept ctx; event server uses context-bound logging and enriches logs with event/resource fields.
Dispatchers
pkg/dispatcher/*
Thread context/logger into resync and consumer update flows; updateConsumerSet signature changed to accept ctx/logger; callbacks updated to receive logger.
Server core & helpers
cmd/maestro/server/server.go, cmd/maestro/server/auth_interceptor.go
Server interface methods Start and Serve accept ctx; check accepts ctx and uses context logger; auth interceptors use klog.FromContext.
Logging package removed
pkg/logger/logger.go, pkg/logger/zap.go
Custom OCM logger and Zap singleton implementation deleted; callers migrated to klog or removed.
Logging consumers (many files)
pkg/api/*.go, pkg/handlers/*, pkg/auth/*, pkg/client/*, pkg/services/*, pkg/db/*, pkg/db/db_session/*, pkg/db/advisory_locks.go
Replace global logger with klog.FromContext(ctx) across handlers, middleware, clients, services, DB listeners, advisory locks, and migrations; preserve control flow, adjust metric placements where noted.
Errors, metadata & misc API
pkg/errors/errors.go, pkg/api/error.go, pkg/api/metadata.go
Replace prior logger usage with contextual klog; write-failure logs now use klog.FromContext(r.Context()); one undefined-error log removed.
Event API surface changes
pkg/event/event.go
Register(ctx,... ) and Unregister(ctx, ...) signatures updated to accept context and use klog.FromContext.
Tests & helpers
test/*, test/helper.go, test/e2e/*, test/integration/*, test/mocks/*, test/upgrade/*
Tests and helpers updated to use klog and pass contexts to new constructors/Start/Serve methods; some tests add DB cleanup on exit.
Module graph adjusted
go.mod
Removed direct viper/fsnotify/zap requires and moved several modules between direct and indirect; overall dependency rebalancing.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant APIServer
    participant GRPCServer
    participant EventBroadcaster
    participant Database
    Note over Client,APIServer: Request carries ctx with klog logger
    Client->>APIServer: HTTP/gRPC request (ctx)
    APIServer->>APIServer: logger = klog.FromContext(ctx)
    APIServer->>GRPCServer: call operation (ctx)
    GRPCServer->>EventBroadcaster: publish/broadcast (ctx)
    EventBroadcaster->>Database: persist/notify (ctx)
    Database-->>EventBroadcaster: ack
    EventBroadcaster-->>GRPCServer: broadcast to subscribers
    GRPCServer-->>APIServer: operation result
    APIServer-->>Client: response (ctx)
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~150 minutes

Areas needing extra attention:

  • Widespread signature changes: ensure all call sites updated for constructors and Start/Serve/Register methods (servers, broker, EventBroadcaster, controllers, listeners, dispatchers, tests).
  • Context lifecycle conversions: verify stop-channel → ctx.Done() migrations (controllers, status controller, KindControllerManager) to avoid premature cancellation, goroutine leaks, or stalled shutdowns.
  • Context propagation in gRPC: confirm ctx and per-request logger travel through interceptors, authorizers, TLS/mTLS loading, and Publish/Subscribe flows.
  • Removal of pkg/logger and Zap: check Sentry/event-capture integrations previously tied to the deleted logger and confirm equivalent behavior remains.
  • Dispatcher/event broadcaster flow: validate logger threading (ctx/logger) and event propagation for missed ctx usage or deadlocks.
  • DB listeners & advisory locks: validate context handling in listener recreation, notification loops, unlock/metric adjustments to avoid missed cleanup.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.73% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess relevance to the changeset. Add a pull request description explaining the motivation, scope, and impact of migrating to klog's contextual logging for reviewers' benefit.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Use klog's contextual logging' clearly summarizes the main change in this extensive pull request, which replaces custom logging with Kubernetes klog's context-aware logging throughout the codebase.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 7f44cbd and 40ff383.

📒 Files selected for processing (5)
  • cmd/maestro/environments/framework.go (7 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/maestro/environments/framework.go
🧰 Additional context used
🧬 Code graph analysis (3)
cmd/maestro/server/event_server.go (3)
pkg/api/resource_types.go (1)
  • Resource (14-27)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
cmd/maestro/server/grpc_server.go (4)
pkg/services/resource.go (1)
  • ResourceService (26-39)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
pkg/config/grpc_server.go (1)
  • GRPCServerConfig (10-35)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
cmd/maestro/server/grpc_broker.go (3)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/config/config.go (1)
  • ReadFile (110-135)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Red Hat Konflux / maestro-on-pull-request
  • GitHub Check: Red Hat Konflux / maestro-e2e-on-pull-request
  • GitHub Check: migration
  • GitHub Check: e2e-grpc-broker
  • GitHub Check: e2e-with-istio
  • GitHub Check: e2e-broadcast-subscription
  • GitHub Check: e2e
🔇 Additional comments (11)
pkg/client/grpcauthorizer/kube_authorizer.go (3)

10-10: LGTM! Clean migration to klog.

The klog/v2 import aligns with the project-wide shift to contextual logging.


46-54: LGTM! Proper contextual logging with structured fields.

The context-derived logger with unique structured keys and appropriate verbosity level (V(4) for detailed access review traces) follows klog best practices.


55-57: Validation logic is now consistent.

The error message update resolves the inconsistency noted in the previous review—the condition and message now align. The validation enforcing groups when user is specified appears intentional as a defensive check, since TokenReview returns both values together.

cmd/maestro/server/grpc_broker.go (3)

128-130: LGTM! Correct context-aware logger initialization.

The updated constructor signature properly accepts context.Context and derives a logger using klog.FromContext(ctx), which is the recommended pattern for klog's contextual logging.


154-179: LGTM! Consistent error handling with context propagation.

All TLS-related error paths now use check(ctx, ...) which ensures consistent error reporting through the context-aware check function. This properly addresses the previous concern about bypassing Sentry reporting.


216-231: LGTM! Proper context-aware logging in lifecycle methods.

The Start method correctly derives a logger from context and uses it for lifecycle events. The error handling via check(ctx, ...) ensures consistent error reporting even within the goroutine.

cmd/maestro/server/event_server.go (2)

95-97: LGTM! Excellent use of context enrichment pattern.

The logger is correctly enriched with resource-specific fields (resourceID, action), logged, and then stored back into the context. The enriched context is properly passed to downstream functions like handleStatusUpdate, which will inherit these fields automatically.


266-267: LGTM! Proper logger enrichment for broadcast operations.

The logger is enriched with resourceID, instanceID, and eventID fields, providing excellent context for all subsequent log messages within this function.

cmd/maestro/server/grpc_server.go (3)

48-53: LGTM! Context-aware constructor initialization.

The updated signature properly accepts context.Context and derives a logger, enabling contextual logging throughout the gRPC server lifecycle.


193-197: LGTM! Efficient verbose logging implementation.

Excellent practice checking logger.V(4).Enabled() before calling the expensive MarshalJSON() operation. This avoids unnecessary work when verbose logging is disabled.


269-318: LGTM! Proper context-aware logging in Subscribe.

The logger is correctly derived from context and used consistently throughout the subscription lifecycle, including error paths and event broadcasting.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
cmd/maestro/migrate/cmd.go (1)

36-39: Use klog.Fatal consistently for error handling.

Line 38 uses standard library log.Fatal, while line 33 uses klog.Fatal. This creates inconsistent logging within the same file and doesn't fully align with the PR's migration objective.

Apply this diff to use klog consistently:

 	connection := db_session.NewProdFactory(dbConfig)
 	if err := db.Migrate(connection.New(context.Background())); err != nil {
-		log.Fatal(err)
+		klog.Fatal(err)
 	}

After this change, the standard log import on line 6 can be removed.

pkg/db/db_session/test.go (1)

77-79: initDatabase can hang in an infinite loop on connection error

The loop never re-executes dbx.Exec; if the first call returns an error, err stays non‑nil and the loop just sleeps forever.

Consider rewriting to retry the query each iteration:

-    for _, err := dbx.Exec(`select 1`); err != nil; {
-        time.Sleep(100 * time.Millisecond)
-    }
+    for {
+        if _, err := dbx.Exec(`select 1`); err == nil {
+            break
+        }
+        time.Sleep(100 * time.Millisecond)
+    }
cmd/maestro/environments/framework.go (1)

248-257: Bug: inverted hostname error check when setting Sentry ServerName

In InitializeSentry:

hostname, err := os.Hostname()
if err != nil && hostname != "" {
    options.ServerName = hostname
}

This only sets ServerName when os.Hostname() returns an error, which is the opposite of what you want. It should set ServerName when the call succeeds (and hostname is non-empty):

- hostname, err := os.Hostname()
- if err != nil && hostname != "" {
+ hostname, err := os.Hostname()
+ if err == nil && hostname != "" {
    options.ServerName = hostname
}

That will ensure Sentry gets a meaningful server name instead of the default.

cmd/maestro/main.go (1)

18-21: Remove unused constants.

The constants logConfigFile and varLogLevel are no longer used after removing the dynamic log level configuration via viper/fsnotify. These should be removed to avoid confusion.

-const (
-	logConfigFile = "/configs/logging/config.yaml"
-	varLogLevel   = "log_level"
-)
cmd/maestro/server/grpc_server.go (1)

304-326: Replace context.TODO() with ctx for proper context propagation.

Line 315 uses context.TODO() when converting the CloudEvent to protobuf. This should use the actual ctx parameter instead to ensure proper cancellation support and deadline propagation when the stream context is cancelled:

-		if err = grpcprotocol.WritePBMessage(context.TODO(), binding.ToMessage(evt), pbEvt); err != nil {
+		if err = grpcprotocol.WritePBMessage(ctx, binding.ToMessage(evt), pbEvt); err != nil {
🧹 Nitpick comments (35)
test/e2e/pkg/suite_test.go (1)

246-252: Consider using klog's contextual logging API.

Since the PR title emphasizes "contextual logging" and the ctx parameter is available in this function, consider using klog.FromContext(ctx) instead of the global klog.Infof functions. This would enable context-aware logging with additional metadata propagated through the context.

Example refactor:

+	logger := klog.FromContext(ctx)
 	klog.Infof("=========================================== POD LOGS START ===========================================")
-	klog.Infof("Pod %s/%s phase: %s", pod.Name, podNamespace, string(pod.Status.Phase))
+	logger.Info("Pod phase", "pod", pod.Name, "namespace", podNamespace, "phase", pod.Status.Phase)
 	for _, containerStatus := range pod.Status.ContainerStatuses {
-		klog.Infof("Container %s status: %v", containerStatus.Name, containerStatus.State)
+		logger.Info("Container status", "container", containerStatus.Name, "state", containerStatus.State)
 	}
-	klog.Infof("Pod %s/%s logs: \n%s", pod.Name, podNamespace, buf.String())
+	logger.Info("Pod logs", "pod", pod.Name, "namespace", podNamespace, "logs", buf.String())
 	klog.Infof("=========================================== POD LOGS STOP ===========================================")

Note: This also converts to structured logging with key-value pairs, which is the idiomatic klog v2 approach.

pkg/services/generic.go (1)

7-7: Klog contextual logging usage looks correct; consider adding structured fields

Using k8s.io/klog/v2 with logger := klog.FromContext(listCtx.ctx) and logger.Info(...) here is consistent with the PR goal of contextual logging and preserves the previous behavior of these size‑handling branches.

As an optional improvement, you might want to take advantage of klog’s structured logging by attaching key/value fields (e.g., requested size, max size, username, resource type) to make these events easier to filter and correlate:

-   case args.Size > MAX_LIST_SIZE:
-       logger.Info("A query with a size greater than the maximum was requested.")
+   case args.Size > MAX_LIST_SIZE:
+       logger.Info(
+           "A query with a size greater than the maximum was requested.",
+           "requestedSize", args.Size,
+           "maxSize",      MAX_LIST_SIZE,
+           "resourceType", listCtx.resourceType,
+           "username",     listCtx.username,
+       )

(Similar key/values could be added to the other branches if desired.)

Also applies to: 220-241

pkg/dispatcher/noop_dispatcher.go (1)

80-88: Consider contextual logging for onInstanceUpdate if you can pass a context

onInstanceUpdate now uses the package-level klog.Infof / klog.Errorf, while the rest of the file uses klog.FromContext(ctx) + a contextual logger. That mix is fine functionally, but slightly inconsistent.

If the NewListener API can be evolved to pass a context.Context into the callback, you could switch onInstanceUpdate to:

  • Accept a ctx context.Context parameter, and
  • Use logger := klog.FromContext(ctx) for structured, contextual logs (with fields like the instance IDs or state).

If the callback signature is fixed for now, keeping the package-level klog calls is acceptable; just confirm this is intentional given the PR’s goal of contextual logging.

pkg/db/db_session/test.go (1)

57-64: Use structured klog.ErrorS instead of formatted Errorf

To align with klog’s structured/contextual logging style, consider switching to ErrorS:

-        if err := initDatabase(config, db.Migrate); err != nil {
-            klog.Errorf("error initializing test database: %s", err)
+        if err := initDatabase(config, db.Migrate); err != nil {
+            klog.ErrorS(err, "error initializing test database")
             return
         }

-        if err := resetDB(config); err != nil {
-            klog.Errorf("error resetting test database: %s", err)
+        if err := resetDB(config); err != nil {
+            klog.ErrorS(err, "error resetting test database")
             return
         }

Please verify that ErrorS is available in the klog version you depend on and matches your logging conventions elsewhere in the repo.

pkg/db/transaction_middleware.go (1)

6-7: Consider using the original request context for operation ID in the error path

Currently, when NewContext fails, operationID is derived from ctx even though the context creation failed. While klog.FromContext(ctx) is safe (it falls back to the global logger if the context is nil or has no logger), using r.Context() for the operation ID lookup is still preferable because:

  • The operation ID is conceptually attached to the incoming request context (injected by the operation-id middleware), not the newly-created ctx
  • Using r.Context() ensures you capture the operation ID that correlates with the original request, making error logs traceable back to the client request
  • logger is only used in the error branch, so instantiating it after checking err is a minor optimization

A clearer pattern would be:

     ctx, err := NewContext(r.Context(), connection)
-    logger := klog.FromContext(ctx)
     if err != nil {
+        logger := klog.FromContext(r.Context())
         logger.Error(err, "Could not create transaction")
         // use default error to avoid exposing internals to users
         err := errors.GeneralError("")
-        operationID := loggertracing.GetOperationID(ctx)
+        operationID := loggertracing.GetOperationID(r.Context())
         writeJSONResponse(w, err.HttpCode, err.AsOpenapiError(operationID))
         return
     }
pkg/db/db_session/default.go (1)

141-167: Contextual logging in waitForNotification looks good; consider enriching the ping‑failure log

Using logger := klog.FromContext(ctx) once and reusing it through the loop is a solid pattern, and the added channel / extra fields improve observability. For the ping failure case you might want more consistency and severity:

  • Include the channel field so all listener recreation paths are filterable by channel.
  • Consider using Error instead of Info for ping failures, since those represent actual connection problems.

For example:

-		case <-time.After(10 * time.Second):
-			if err := l.Ping(); err != nil {
-				logger.Info("recreate the listener due to ping failed", "error", err)
-				l.Close()
-				// recreate the listener
-				l = newListener(ctx, dbConfig, channel)
-			}
+		case <-time.After(10 * time.Second):
+			if err := l.Ping(); err != nil {
+				logger.Error(err, "Recreating listener due to ping failure", "channel", channel)
+				l.Close()
+				// recreate the listener
+				l = newListener(ctx, dbConfig, channel)
+			}

Please confirm that this change in log level (Info → Error) aligns with your logging policy and alerting thresholds before applying it. You can also double‑check the Logger.Error signature in the klog docs to ensure it matches the proposed usage.

pkg/db/migrations.go (1)

31-38: klog.Fatalf migration looks correct; consider future ctx-aware logging here

Switching to klog.Fatalf preserves the previous fatal-exit behavior and looks fine. Longer term, you might want to plumb a context.Context into MigrateTo and use a contextual logger instead of context.Background(), but that can be deferred.

pkg/db/context.go (1)

26-58: Contextual logging usage is correct; minor nit on error construction

Using klog.FromContext(ctx) and logger.Info/Error here is consistent and correct. The only nit is the pattern:

  • logger.Error(errors.New("..."), "")

You allocate a new error just to log it and pass an empty message. Consider either:

  • Logging a static message without an error (if you don’t care about a stack), or
  • Using logger.Error (or ErrorS) with a real message and optional key/value fields.

Not blocking, just a small cleanup opportunity.

pkg/auth/helpers.go (1)

13-25: Context-based logging and operationID wiring look good; tweak error log message

Deriving both the logger and operationID from ctx here is aligned with the rest of the PR and looks correct. One small improvement: instead of logger.Error(err, ""), consider giving the error log a non-empty message and maybe structured fields (e.g. code, err.HttpCode) so these entries are easier to search and filter.

pkg/handlers/framework.go (1)

33-43: Per-request logger usage is correct; consider trimming logged error payload

Using a context-derived logger here and splitting 4xx as Info vs others as Error is sound. If *errors.ServiceError contains large or potentially sensitive fields, consider logging only selected fields (e.g. ID/code/HTTP status) instead of the full struct, to keep logs lean and safer to ship.

cmd/maestro/environments/framework.go (1)

69-112: Mix of std log.Fatalf and klog: consider consolidating on klog

Initialize now logs startup and several info/debug messages via klog but still uses log.Fatalf for fatal error paths (unknown env, Visit* failures, etc.), and Teardown also uses log.Fatalf. Functionally this works, but for consistency with the rest of the PR you may want to swap these to klog.Fatalf (or contextual loggers if/when a ctx is available) so all logging goes through the same backend and configuration.

pkg/api/error.go (1)

101-109: Prefer structured ErrorS over deprecated klog.Error in init

The panic-body initialization fallback currently does:

klog.Error(err)
sentry.CaptureException(err)
os.Exit(1)

Per the klog/v2 docs, the global Error helper is deprecated in favor of ErrorS (or a contextual Logger.Error).(pkg.go.dev) Consider updating this to something like:

klog.ErrorS(err, "cannot create the panic error body")

to align with current klog best practices.

Please confirm this matches the klog version you vendor (and whether you want to silence any deprecation warnings) before changing it.

pkg/dispatcher/hash_dispatcher.go (2)

100-133: Leverage context in updateConsumerSet instead of context.TODO()

check now derives a contextual logger and passes it into updateConsumerSet, which is good. Inside updateConsumerSet, you still call:

consumers, err := d.consumerDao.All(context.TODO())

Given check already has a ctx, it’d be cleaner and more cancellable to either:

  • Change the signature to updateConsumerSet(ctx context.Context, logger klog.Logger) and pass ctx through to consumerDao.All, or
  • Make updateConsumerSet derive its own logger from ctx and drop the logger parameter.

Right now the DB call ignores cancellation and timeouts from the caller.

Also applies to: 151-203


76-90: Minor: fix typos in resync log messages

Both in resyncOnReconnect and processNextResync, the error messages say "failed to resync resourcs status...". Consider correcting to "failed to resync resource status..." to keep logs readable:

- "failed to resync resourcs status for consumers"
+ "failed to resync resource status for consumers"

- "failed to resync resourcs status for consumer"
+ "failed to resync resource status for consumer"

Purely cosmetic, but helps when grepping logs.

Also applies to: 230-233

test/integration/integration_test.go (1)

3-11: Import grouping could be improved.

The k8s.io/klog/v2 import on line 5 is placed between standard library imports (flag and os). Consider grouping imports properly: standard library first, then external packages.

 import (
 	"flag"
-	"k8s.io/klog/v2"
 	"os"
 	"runtime"
 	"testing"
+
+	"k8s.io/klog/v2"
 
 	"github.com/openshift-online/maestro/test"
 )
pkg/controllers/event_filter.go (1)

3-9: Import grouping could be improved.

The k8s.io/klog/v2 import is placed between standard library imports and local packages. Consider proper grouping.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
+
+	"k8s.io/klog/v2"
 
 	"github.com/openshift-online/maestro/pkg/db"
 )
cmd/maestro/main.go (1)

49-51: Consider using klog.Fatal for consistency.

Since the codebase is migrating to klog, using klog.Fatal or klog.Fatalf here would maintain consistency with the rest of the logging infrastructure.

 	if err := rootCmd.Execute(); err != nil {
-		log.Fatalf("error running command: %v", err)
+		klog.Fatalf("error running command: %v", err)
 	}

If you apply this change, you can also remove the "log" import on line 5.

cmd/maestro/server/logging/formatter_json.go (1)

3-8: Import grouping could be improved.

 import (
 	"encoding/json"
 	"io"
-	"k8s.io/klog/v2"
 	"net/http"
+
+	"k8s.io/klog/v2"
 )
cmd/maestro/server/logging/writer.go (1)

3-6: Import grouping could be improved.

 import (
-	"k8s.io/klog/v2"
 	"net/http"
+
+	"k8s.io/klog/v2"
 )
pkg/api/metadata.go (2)

21-27: Import grouping could be improved.

 import (
 	"encoding/json"
-	"k8s.io/klog/v2"
 	"net/http"
 
+	"k8s.io/klog/v2"
+
 	"github.com/getsentry/sentry-go"
 )

58-58: Inconsistent error message casing.

The error messages use different casing styles:

  • Line 58: "cannot send response body for request" (lowercase)
  • Line 95: "Can't send response body for request" (title case)

Consider standardizing to one style for consistency.

-		logger.Error(err, "Can't send response body for request", "path", r.URL.Path)
+		logger.Error(err, "cannot send response body for request", "path", r.URL.Path)

Also applies to: 95-95

cmd/maestro/common/otlp_sdk.go (1)

3-18: Import grouping could be improved.

The k8s.io/klog/v2 import is placed between standard library imports (context and os), breaking conventional Go import grouping. Consider grouping imports as: standard library, then external packages, then internal packages.

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"os"
 	"time"

 	"go.opentelemetry.io/contrib/exporters/autoexport"
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/propagation"
 	"go.opentelemetry.io/otel/sdk/resource"
 	tracesdk "go.opentelemetry.io/otel/sdk/trace"
 	semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
+	"k8s.io/klog/v2"

 	"github.com/openshift-online/maestro/pkg/constants"
 	errors "github.com/zgalor/weberr"
 )
cmd/maestro/server/metrics_server.go (1)

3-14: Import grouping could be improved.

Same as other files - k8s.io/klog/v2 is placed between standard library imports.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net"
 	"net/http"

 	"github.com/gorilla/mux"
+	"k8s.io/klog/v2"

 	"github.com/openshift-online/maestro/pkg/api"
 	"github.com/openshift-online/maestro/pkg/handlers"
 )
cmd/maestro/server/server.go (1)

3-14: Import grouping could be improved.

The k8s.io/klog/v2 import is placed between standard library imports.

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"net"
 	"net/http"
 	"os"
 	"strings"

 	"github.com/getsentry/sentry-go"
+	"k8s.io/klog/v2"

 	"github.com/openshift-online/maestro/cmd/maestro/environments"
 )
cmd/maestro/server/grpc_broker.go (1)

3-30: Import grouping could be improved.

The k8s.io/klog/v2 import is placed between standard library imports, inconsistent with Go conventions.

cmd/maestro/server/event_server.go (1)

170-170: Consider removing "WARN:" prefix from log message.

With structured logging, severity is typically indicated by the log level rather than embedding it in the message. Since klog.Logger doesn't expose a Warning method directly, consider either removing the prefix or using logger.V(0).Info with a severity field if warning distinction is needed.

-			logger.Info("WARN: skipping resource as it is not found")
+			logger.Info("skipping resource as it is not found")
cmd/maestro/server/auth_interceptor.go (1)

150-151: Stream interceptor captures logger at creation time, not per-request.

The logger is initialized from the context passed during interceptor creation (line 151), but the unary interceptor correctly obtains the logger from the per-request context (line 101). For consistency and to ensure proper per-request logging context, consider obtaining the logger from ss.Context() inside the returned function.

 func newAuthStreamInterceptor(ctx context.Context, authNType string, authorizer grpcauthorizer.GRPCAuthorizer) grpc.StreamServerInterceptor {
-	logger := klog.FromContext(ctx)
 	return func(
 		srv interface{},
 		ss grpc.ServerStream,
 		info *grpc.StreamServerInfo,
 		handler grpc.StreamHandler,
 	) error {
+		logger := klog.FromContext(ss.Context())
 		var user string
 		var groups []string
 		var err error
cmd/maestro/servecmd/cmd.go (1)

77-78: Consider using klog.Fatal for fatal errors.

The pattern of logger.Error followed by os.Exit(1) works, but klog.Fatal or klog.Fatalf provides the same behavior more concisely and is already used elsewhere in this file (line 46).

 		default:
-			logger.Error(errors.New("Unsupported subscription type"), "", "subscriptionType", subscriptionType)
-			os.Exit(1)
+			klog.Fatalf("Unsupported subscription type: %s", subscriptionType)
 		}
cmd/maestro/server/controllers.go (1)

13-15: Unused logger variable in NewControllersServer.

The logger is created from context but never used in this function. Either remove it or use it for logging during initialization.

If the logger is intended for future use or debugging during construction, consider adding a log statement or removing the unused variable:

 func NewControllersServer(ctx context.Context, eventServer EventServer, eventFilter controllers.EventFilter) *ControllersServer {
-	logger := klog.FromContext(ctx)
-
 	s := &ControllersServer{

Or, if you want to keep it for initialization logging:

 func NewControllersServer(ctx context.Context, eventServer EventServer, eventFilter controllers.EventFilter) *ControllersServer {
 	logger := klog.FromContext(ctx)
+	logger.Info("Creating controllers server")
 
 	s := &ControllersServer{
cmd/maestro/server/healthcheck_server.go (1)

7-9: Import ordering does not follow Go conventions.

The k8s.io/klog/v2 import is placed between standard library imports. Go conventions group standard library imports separately from third-party imports.

 import (
 	"context"
 	e "errors"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net/http"
 	"time"
 
 	"github.com/gorilla/mux"
+	"k8s.io/klog/v2"
+
 	"github.com/openshift-online/maestro/pkg/api"
test/helper.go (1)

8-9: Import ordering does not follow Go conventions.

Standard library imports (log) should be grouped with other standard library imports, and third-party imports (k8s.io/klog/v2) should be in a separate group.

 import (
 	"context"
 	"crypto/rsa"
 	"encoding/json"
 	"fmt"
-	"k8s.io/klog/v2"
 	"log"
 	"os"
 	"path/filepath"

Then add klog with other third-party imports in the appropriate import group.

cmd/maestro/server/api_server.go (1)

6-9: Import ordering does not follow Go conventions.

The imports mix standard library (fmt, net, net/http, os, time) with third-party (k8s.io/klog/v2). Group standard library imports together.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net"
 	"net/http"
-	"os"
+	"os"
 	"time"
 
 	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
+	"k8s.io/klog/v2"
pkg/controllers/status_controller.go (1)

6-7: Import ordering does not follow Go conventions.

The k8s.io/klog/v2 import should be grouped with other third-party imports, not between standard library imports.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"time"
 
 	"github.com/openshift-online/maestro/pkg/api"
 	"github.com/openshift-online/maestro/pkg/dao"
 	"github.com/openshift-online/maestro/pkg/services"
 	"k8s.io/apimachinery/pkg/util/wait"
+	"k8s.io/klog/v2"
 	"k8s.io/client-go/util/workqueue"
 )
pkg/controllers/framework.go (2)

6-7: Import ordering does not follow Go conventions.

The k8s.io/klog/v2 import should be grouped with other third-party imports, not between standard library imports.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"time"
 
 	"github.com/openshift-online/maestro/pkg/api"
 	"github.com/openshift-online/maestro/pkg/services"
 
 	"k8s.io/apimachinery/pkg/util/wait"
+	"k8s.io/klog/v2"
 	"k8s.io/client-go/util/workqueue"
 )

214-218: Consider passing the enriched context to handleEvent for consistency.

The logger at line 214 enriches with "key", but the original ctx (without this enrichment) is passed to handleEvent, which then creates its own logger with EventID. While both represent the same value, passing the enriched context would ensure consistent logging throughout the call chain.

 	logger := klog.FromContext(ctx).WithValues("key", key)
+	enrichedCtx := klog.NewContext(ctx, logger)
 
-	if reconciled, err := km.handleEvent(ctx, key); !reconciled {
+	if reconciled, err := km.handleEvent(enrichedCtx, key); !reconciled {
 		if err != nil {
 			logger.Error(err, "Failed to handle the event")
 		}

Alternatively, since handleEvent already enriches the logger with EventID (which equals key), the current behavior is functionally correct and this is purely a consistency suggestion.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 76ac7dc and a7cae33.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (47)
  • cmd/maestro/agent/cmd.go (1 hunks)
  • cmd/maestro/common/otlp_sdk.go (4 hunks)
  • cmd/maestro/environments/framework.go (6 hunks)
  • cmd/maestro/main.go (1 hunks)
  • cmd/maestro/migrate/cmd.go (2 hunks)
  • cmd/maestro/servecmd/cmd.go (4 hunks)
  • cmd/maestro/server/api_server.go (6 hunks)
  • cmd/maestro/server/auth_interceptor.go (4 hunks)
  • cmd/maestro/server/controllers.go (3 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • cmd/maestro/server/healthcheck_server.go (6 hunks)
  • cmd/maestro/server/logging/formatter_json.go (3 hunks)
  • cmd/maestro/server/logging/logging.go (0 hunks)
  • cmd/maestro/server/logging/writer.go (3 hunks)
  • cmd/maestro/server/metrics_server.go (2 hunks)
  • cmd/maestro/server/routes.go (3 hunks)
  • cmd/maestro/server/server.go (3 hunks)
  • go.mod (3 hunks)
  • pkg/api/error.go (5 hunks)
  • pkg/api/metadata.go (4 hunks)
  • pkg/auth/helpers.go (1 hunks)
  • pkg/client/cloudevents/source_client.go (4 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
  • pkg/controllers/event_filter.go (3 hunks)
  • pkg/controllers/framework.go (9 hunks)
  • pkg/controllers/framework_test.go (2 hunks)
  • pkg/controllers/status_controller.go (7 hunks)
  • pkg/db/advisory_locks.go (8 hunks)
  • pkg/db/context.go (2 hunks)
  • pkg/db/db_session/default.go (4 hunks)
  • pkg/db/db_session/test.go (2 hunks)
  • pkg/db/migrations.go (2 hunks)
  • pkg/db/transaction_middleware.go (2 hunks)
  • pkg/dispatcher/hash_dispatcher.go (8 hunks)
  • pkg/dispatcher/noop_dispatcher.go (5 hunks)
  • pkg/errors/errors.go (0 hunks)
  • pkg/event/event.go (5 hunks)
  • pkg/handlers/framework.go (2 hunks)
  • pkg/logger/logger.go (0 hunks)
  • pkg/logger/zap.go (0 hunks)
  • pkg/services/generic.go (3 hunks)
  • pkg/services/resource.go (5 hunks)
  • test/e2e/pkg/suite_test.go (3 hunks)
  • test/helper.go (10 hunks)
  • test/integration/integration_test.go (1 hunks)
💤 Files with no reviewable changes (4)
  • pkg/errors/errors.go
  • pkg/logger/zap.go
  • cmd/maestro/server/logging/logging.go
  • pkg/logger/logger.go
🧰 Additional context used
🧬 Code graph analysis (15)
pkg/client/cloudevents/source_client.go (4)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/services/resource.go (1)
  • ResourceService (26-39)
pkg/api/metadata_types.go (1)
  • Meta (51-56)
pkg/client/cloudevents/codec.go (1)
  • Codec (17-19)
pkg/handlers/framework.go (1)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
cmd/maestro/server/logging/writer.go (1)
cmd/maestro/server/logging/formatter.go (1)
  • LogFormatter (5-8)
cmd/maestro/server/healthcheck_server.go (2)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/db/advisory_locks.go (1)
  • Instances (25-25)
cmd/maestro/server/routes.go (2)
cmd/maestro/environments/types.go (1)
  • Services (42-48)
pkg/auth/authz_middleware_mock.go (1)
  • NewAuthzMiddlewareMock (11-13)
pkg/auth/helpers.go (2)
pkg/errors/errors.go (2)
  • ServiceErrorCode (61-61)
  • New (102-116)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
pkg/controllers/status_controller.go (2)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
pkg/db/transaction_middleware.go (2)
pkg/errors/errors.go (1)
  • GeneralError (161-163)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
cmd/maestro/server/auth_interceptor.go (1)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
cmd/maestro/server/grpc_server.go (4)
pkg/services/resource.go (1)
  • ResourceService (26-39)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
pkg/config/grpc_server.go (1)
  • GRPCServerConfig (10-35)
pkg/api/resource_types.go (1)
  • Resource (14-27)
cmd/maestro/server/event_server.go (3)
pkg/api/resource_types.go (1)
  • Resource (14-27)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
cmd/maestro/server/api_server.go (2)
cmd/maestro/server/server.go (1)
  • Server (16-21)
cmd/maestro/server/grpc_server.go (2)
  • NewGRPCServer (48-146)
  • GRPCServer (36-45)
cmd/maestro/server/controllers.go (6)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/controllers/framework.go (1)
  • KindControllerManager (52-57)
cmd/maestro/environments/types.go (1)
  • Database (31-33)
pkg/db/session.go (1)
  • SessionFactory (13-21)
pkg/controllers/status_controller.go (1)
  • StatusController (20-26)
pkg/controllers/framework.go (3)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/event.go (1)
  • EventType (9-9)
pkg/api/openapi/model_error.go (1)
  • Error (21-28)
test/helper.go (3)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
cmd/maestro/server/grpc_broker.go (1)
  • NewGRPCBroker (128-212)
cmd/maestro/server/api_server.go (1)
  • NewAPIServer (40-144)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Red Hat Konflux / maestro-on-pull-request
  • GitHub Check: e2e-grpc-broker
  • GitHub Check: migration
  • GitHub Check: e2e-with-istio
  • GitHub Check: e2e-broadcast-subscription
  • GitHub Check: e2e
🔇 Additional comments (61)
cmd/maestro/agent/cmd.go (2)

66-66: Comment typo fix improves clarity.

The comment correction from "leader leader election flags" to "leader election flags" removes a duplicate word and improves readability.


41-41: Verify context propagation for logging initialization.

Line 41 uses context.TODO() when creating the command context. Given this PR's goal of propagating context throughout server initialization for structured klog logging, verify that this placeholder context is intentional and that proper application context (with logging values) is propagated downstream to logging operations and request handlers.

Confirm whether context.TODO() should be replaced with a meaningful context that carries logging-related values or context cancellation signals needed for the klog migration.

cmd/maestro/migrate/cmd.go (2)

5-5: LGTM: klog import aligns with migration objective.

The addition of klog/v2 import correctly supports the PR's goal of migrating to Kubernetes contextual logging.


30-34: LGTM: Correct usage of klog.Fatal.

The migration from custom logger to klog.Fatal for configuration read errors aligns with the PR objective.

test/e2e/pkg/suite_test.go (2)

9-9: LGTM!

The klog import is correctly added.


213-213: LGTM!

The migration from log.Errorf to klog.Errorf is correct. Note that contextual logging (klog.FromContext(ctx)) is not applicable here since the ReportAfterSuite callback doesn't have access to a context.

pkg/services/resource.go (1)

162-162: LGTM! Proper contextual logging initialization.

The logger is correctly derived from context and enriched with resourceID for better traceability across all status update operations.

go.mod (1)

56-56: k8s.io/klog/v2 v2.130.1 is the current stable version with no known security advisories.

The dependency versions in this migration are current and secure. k8s.io/klog/v2 v2.130.1 is the latest stable release (June 2024) with no published CVEs. The indirect dependencies are also free of disclosed security issues: fsnotify v1.7.0, go.uber.org/zap v1.27.1, and google.golang.org/genproto all have clean security records.

pkg/client/cloudevents/source_client.go (5)

8-8: LGTM!

The klog import is correctly added to support contextual logging throughout this file.


90-115: LGTM!

The OnUpdate method follows the same correct klog contextual logging pattern as OnCreate, maintaining consistency across the codebase.


117-146: LGTM!

The OnDelete method consistently applies the klog contextual logging pattern, maintaining uniformity with OnCreate and OnUpdate.


57-88: Verify context initialization in OnCreate callers.

The logging pattern in OnCreate (lines 58-59, 64, 72, 76, 83) correctly uses klog contextual logging: extracting the logger, enriching it with resourceID, and re-attaching to context. However, this pattern depends on callers providing contexts with initialized loggers via klog.NewContext(). Verify that all callers of OnCreate properly initialize their contexts with a logger before invocation to ensure the logging enrichment works as intended.


152-164: LGTM!

The Resync method correctly applies the klog contextual logging pattern with appropriate enrichment (consumers instead of resourceID), which makes sense for this method's operational context.

pkg/client/grpcauthorizer/kube_authorizer.go (1)

10-10: klog import addition is consistent with the logging migration

Importing k8s.io/klog/v2 here matches the PR’s move to contextual klog usage and looks correct.

pkg/dispatcher/noop_dispatcher.go (1)

6-6: Contextual klog usage in Start/resyncOnReconnect looks good

Using klog.FromContext(ctx) and the logr-style logger.Info / logger.Error calls is consistent with klog v2’s contextual logging and correctly tied to the lifecycle of ctx (including in the goroutine). No correctness issues here.

If you want extra structure in logs, consider (optionally) adding something like logger = logger.WithName("noop-dispatcher") or key fields (e.g. dispatcher type) so these messages are easier to filter. Please double‑check against the klog v2 docs that this aligns with your global logging setup.

Also applies to: 36-42, 50-72

pkg/db/db_session/test.go (1)

7-7: klog/v2 import looks correct

Using k8s.io/klog/v2 here is consistent with the migration goal; no issues with this import from this file’s perspective.

Please confirm klog is initialized appropriately in your test binaries (e.g., via klog.InitFlags(nil) or equivalent) so these errors surface as expected.

pkg/db/db_session/default.go (1)

7-7: Ensure klog contextual logging is initialized globally

The k8s.io/klog/v2 import is correct. Verify that klog's contextual logging is initialized once during startup (typically via klog.SetLogger(klog.NewKlogr()) or similar in your main/init) so that klog.FromContext(ctx) uses your structured backend instead of the bare global logger. Check for klog initialization patterns like InitFlags, SetLoggerWithOptions, or EnableContextualLogging elsewhere in the codebase to confirm this is in place.

pkg/api/error.go (1)

38-79: HTTP error handlers: contextual logging is wired correctly

Using klog.FromContext(r.Context()) in the HTTP helpers and logging write failures with a structured "path" field is a nice improvement and matches the klog API. Behavior on write error (log + Sentry + return) is unchanged and looks correct.

pkg/db/advisory_locks.go (1)

91-136: Advisory lock logging migration looks correct and improves observability

The switch to a context-derived logger in NewAdvisoryLock, NewNonBlockingLock, and Unlock is correct and the structured fields (owner, lockID, lockType) in Unlock should make diagnosing lock issues much easier. No functional regressions spotted.

Also applies to: 155-187

test/integration/integration_test.go (1)

13-21: LGTM!

The migration from the custom logger to klog.Infof is appropriate here. Since TestMain doesn't have a request context, using klog.Infof directly (rather than klog.FromContext) is the correct approach.

pkg/controllers/event_filter.go (1)

45-64: LGTM!

Good use of context-derived structured logging with klog.FromContext(ctx).WithValues(EventID, id). This properly propagates contextual information and adds the event ID for traceability.

cmd/maestro/server/logging/formatter_json.go (2)

18-34: LGTM!

Using klog.V(4).Enabled() to conditionally include request headers/body at higher verbosity levels is appropriate. Since the LogFormatter interface (from formatter.go) doesn't pass context, using global verbosity here is the pragmatic choice.


36-46: LGTM!

Consistent use of klog.V(4).Enabled() for response body inclusion.

cmd/maestro/server/logging/writer.go (2)

8-19: LGTM!

Excellent implementation of per-request context-derived logging. Extracting the logger from the request context in NewLoggingWriter and storing it in the struct ensures consistent contextual logging throughout the request lifecycle.


31-38: LGTM!

Good logging pattern: V(4).Info for debug-level successful logs and Error(err, msg) for error conditions. The verbosity level is consistent with formatter_json.go.

pkg/api/metadata.go (1)

30-62: LGTM!

Good implementation of per-request context-derived logging with structured fields ("path", r.URL.Path). The pattern of extracting the logger early in the handler is clean.

cmd/maestro/server/routes.go (1)

18-24: LGTM on context propagation.

The addition of ctx context.Context parameter and its use in check() calls aligns well with the broader migration to context-aware error handling and logging.

pkg/controllers/framework_test.go (2)

87-89: LGTM!

The test correctly passes the context to handleEvent, aligning with the updated production signature handleEvent(ctx context.Context, id string).


198-200: LGTM!

Consistent context propagation matching the updated handleEvent signature.

cmd/maestro/common/otlp_sdk.go (2)

26-27: LGTM!

Function signature correctly accepts klog.Logger (by value, as intended for klog), and the structured logging call follows klog conventions.


59-61: LGTM!

Error handler correctly uses klog's Error(err, msg) pattern for structured error logging.

cmd/maestro/server/metrics_server.go (1)

47-49: LGTM!

Context-aware logging setup follows the established pattern in this PR.

cmd/maestro/server/server.go (2)

16-21: LGTM!

Server interface correctly updated to require context for lifecycle methods, enabling context-aware logging and cancellation propagation throughout server components.


31-38: LGTM!

The check function correctly derives a logger from context and maintains the existing error handling flow (log → Sentry capture → flush → exit).

cmd/maestro/server/grpc_broker.go (3)

128-130: LGTM!

Constructor correctly accepts context and derives logger for use throughout initialization, consistent with the PR's logging migration pattern.


230-234: LGTM!

Graceful shutdown correctly waits for context cancellation before stopping the gRPC server.


271-287: LGTM!

Context-derived logging with appropriate verbosity level (V(4)) for the resource deletion path.

cmd/maestro/server/event_server.go (3)

77-88: LGTM!

The logger initialization from context and shutdown logging are properly implemented.


94-97: LGTM!

Good use of WithValues to enrich the logger with resourceID and action, and proper context propagation via klog.NewContext.


255-295: LGTM!

The broadcastStatusEvent function properly initializes the logger with relevant context values and uses structured logging consistently.

cmd/maestro/server/auth_interceptor.go (1)

100-114: LGTM!

The unary interceptor correctly obtains the logger from the per-request context and logs authentication errors appropriately.

cmd/maestro/servecmd/cmd.go (1)

52-55: LGTM!

Good initialization of the context-aware logger with a descriptive name and proper context propagation.

cmd/maestro/server/controllers.go (1)

58-76: LGTM!

The Start method properly creates a named logger, propagates the updated context, and uses consistent logging throughout the controller lifecycle.

pkg/event/event.go (3)

41-57: LGTM!

The Register method properly accepts context and uses structured logging with relevant fields.


60-74: LGTM!

Good use of WithValues to pre-attach the id field to the logger for consistent logging throughout the method.


82-106: LGTM!

The Start method properly initializes the logger from context and uses structured logging with resourceID for error cases.

cmd/maestro/server/healthcheck_server.go (1)

50-53: LGTM on context-based logging setup.

The pattern of creating a logger from context, enriching it with instanceID, and storing the enriched logger back in the context is correct and idiomatic for klog contextual logging.

test/helper.go (1)

198-208: LGTM on context-aware API server startup.

The logger is correctly derived from helper.Ctx and the context is properly passed to NewAPIServer and Start. This aligns with the PR's migration to contextual logging.

cmd/maestro/server/api_server.go (2)

40-43: LGTM on context propagation through API server construction.

The NewAPIServer function correctly accepts a context parameter and propagates it to routes(ctx) and later to NewGRPCServer. This ensures consistent context-based logging throughout the API server lifecycle.


180-193: LGTM on context-aware server lifecycle.

The Start method correctly obtains a logger from context, passes the context to the gRPC server's Start method, and propagates it to Serve. The error handling pattern (log then exit) is appropriate for fatal startup failures.

pkg/controllers/status_controller.go (2)

104-106: LGTM on context enrichment pattern.

The pattern of creating an enriched logger with StatusEventID, attaching it to a new context via klog.NewContext, and then adding the event ID as a context value is correct. This allows both structured logging and context value access throughout the event handling chain.


51-66: LGTM on context-aware controller lifecycle.

The Run method correctly uses wait.JitterUntilWithContext and wait.UntilWithContext for context-aware periodic execution and worker management. The shutdown is handled by waiting on ctx.Done().

pkg/controllers/framework.go (2)

88-104: LGTM on context-aware controller lifecycle.

The Run method correctly uses context-aware utilities (JitterUntilWithContext, UntilWithContext) and properly shuts down by waiting on ctx.Done(). The logger is correctly derived from the context.


118-121: LGTM on request context enrichment.

The pattern of creating an enriched logger with EventID, attaching it via klog.NewContext, and adding the EventID as a context value is consistent with StatusController and correctly enables both structured logging and context-based value access.

cmd/maestro/server/grpc_server.go (7)

167-194: LGTM! Proper contextual logging in Publish method.

The method correctly extracts the logger from context and uses structured logging with appropriate fields. The verbose logging with logger.V(4) is appropriately gated for detailed event information.


445-488: LGTM! Proper contextual logging in respondResyncStatusRequest.

The method correctly extracts the logger from context and uses structured logging. Context is properly propagated to the resourceService methods.


149-159: Context-aware Start method looks good.

The Start method now accepts context.Context and properly extracts the logger for startup and error logging. This is a breaking API change—ensure all call sites of GRPCServer.Start() have been updated to pass a context parameter.


77-116: Verify the check() function signature.

Multiple calls to check() have been updated to pass context.Context as the first parameter. Ensure that the check() function definition has been updated accordingly.


354-359: Verify EventBroadcaster.Unregister signature accepts context.Context.

The calls to eventBroadcaster.Unregister at lines 355 and 358 now pass ctx as the first parameter. Confirm that the Unregister method signature has been updated to accept context.Context as the first parameter, matching the pattern of the Register method.


98-98: Verify newAuthStreamInterceptor signature.

The call to newAuthStreamInterceptor on line 98 now passes ctx as the first parameter. Ensure that the function definition has been updated to accept context.Context as the first parameter.


48-53: Context-aware constructor follows klog best practices.

The addition of context.Context as the first parameter and extraction of the logger from context using klog.FromContext(ctx) aligns with proper contextual logging patterns and enables better log attribution.

Ensure all call sites of NewGRPCServer in the codebase have been updated to pass the context parameter as the first argument.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
cmd/maestro/migrate/cmd.go (1)

38-38: Inconsistent error logging: use klog.Fatal for uniformity.

Line 33 was migrated to klog.Fatal, but this line still uses the standard library's log.Fatal. For consistency with the PR's goal of migrating to klog-based logging, both fatal error paths should use klog.Fatal.

Apply this diff:

-		log.Fatal(err)
+		klog.Fatal(err)

After applying this change, you can remove the unused standard log import on line 6.

pkg/dispatcher/hash_dispatcher.go (2)

76-90: Typo: "resourcs" should be "resources".

The error message on line 86 contains a typo.

 		if err := d.sourceClient.Resync(ctx, d.consumerSet.ToSlice()); err != nil {
-			logger.Error(err, "failed to resync resourcs status for consumers", "consumers", d.consumerSet.ToSlice())
+			logger.Error(err, "failed to resync resources status for consumers", "consumers", d.consumerSet.ToSlice())
 		}

207-238: Typo: "resourcs" should be "resources" (same issue as line 86).

 	if err := d.sourceClient.Resync(ctx, []string{consumerName}); err != nil {
-		logger.Error(err, "failed to resync resourcs status for consumer", "consumer", consumerName)
+		logger.Error(err, "failed to resync resources status for consumer", "consumer", consumerName)
cmd/maestro/server/api_server.go (1)

180-199: Start’s listen failure should use check(ctx, ...) for consistent fatal handling

In Start, a failure from s.Listen() is logged and followed by os.Exit(1) directly, which again bypasses the centralized check(ctx, ...) path that logs, reports to Sentry, and exits.

 func (s apiServer) Start(ctx context.Context) {
 	logger := klog.FromContext(ctx)
 	if env().Config.GRPCServer.EnableGRPCServer {
 		// start the grpc server
 		defer s.grpcServer.Stop()
 		go s.grpcServer.Start(ctx)
 	}

 	listener, err := s.Listen()
-	if err != nil {
-		logger.Error(err, "Unable to start API server")
-		os.Exit(1)
-	}
+	check(ctx, err, "Unable to start API server")
 	s.Serve(ctx, listener)

 	// after the server exits but before the application terminates

If you prefer to keep the explicit logger.Error message, you can log first and still delegate exit behaviour to check(ctx, err, ...).

♻️ Duplicate comments (8)
pkg/services/resource.go (1)

225-226: Reminder: Address the camelCase inconsistency flagged in previous review.

As noted in the previous review, "wantsequenceID" on line 226 should be "wantSequenceID" to match the camelCase convention used for "wantVersion" on line 185.

cmd/maestro/server/event_server.go (1)

95-98: Remove leftover %s placeholder in skip log message.

The skip message currently includes a %s placeholder but no corresponding value, so the literal %s will appear in the logs and is slightly confusing. Since you already have resourceID and action as structured fields on the logger, you can just drop the placeholder from the message.

-				logger.Info("skipping resource status update %s as it is not owned by the current instance")
+				logger.Info("skipping resource status update as it is not owned by the current instance")

Also applies to: 103-103

cmd/maestro/server/metrics_server.go (1)

47-50: Fix logged port for TLS metrics server to match Metrics bind port

In the TLS branch you’re still logging env().Config.HTTPServer.BindPort, but the server is configured with env().Config.Metrics.BindPort (see Addr construction). This makes the log misleading.

 func (s metricsServer) Start(ctx context.Context) {
 	var err error
 	logger := klog.FromContext(ctx)
@@
 	if env().Config.Metrics.EnableHTTPS {
@@
-		// Serve with TLS
-		logger.Info("Serving Metrics with TLS", "port", env().Config.HTTPServer.BindPort)
+		// Serve with TLS
+		logger.Info("Serving Metrics with TLS", "port", env().Config.Metrics.BindPort)

Also applies to: 59-60, 62-67

cmd/maestro/server/healthcheck_server.go (2)

71-74: Incorrect printf-style formatting in klog structured logging.

The logger.Info() calls use %s placeholders which won't be substituted in klog's structured logging. This has been flagged in a previous review.


160-172: Malformed klog.Error calls with printf-style specifiers.

The logger.Error() calls on lines 163 and 170 mix printf-style format specifiers (%s) with structured key-value logging. This has been flagged in a previous review.

cmd/maestro/servecmd/cmd.go (1)

113-115: Bug: Wrong error variable logged for tracing shutdown failure.

This logs the err variable from line 93 (OpenTelemetry installation error) instead of the shutdown error. This has been flagged in a previous review.

test/helper.go (1)

376-396: Typo in reset log message: “Reseting” → “Resetting”

The new klog-based log in Reset still contains the typo noted previously.

 func (helper *Helper) Reset() {
 	logger := klog.FromContext(helper.Ctx)
-	logger.Info("Reseting testing environment")
+	logger.Info("Resetting testing environment")
cmd/maestro/server/grpc_broker.go (1)

215-234: Fatal broker errors bypass centralized Sentry reporting; use check(ctx, ...) instead of os.Exit(1)

The Start method logs and calls os.Exit(1) directly on listen/serve failures, which skips the centralized check(ctx, ...) error path that also reports to Sentry. Aligning these fatal paths with check improves observability and consistency.

 func (bkr *GRPCBroker) Start(ctx context.Context) {
-	logger := klog.FromContext(ctx)
-	ln, err := net.Listen("tcp", bkr.bindAddress)
-	if err != nil {
-		logger.Error(err, "Failed to listen on", "bindAddress", bkr.bindAddress)
-		os.Exit(1)
-	}
+	logger := klog.FromContext(ctx)
+	ln, err := net.Listen("tcp", bkr.bindAddress)
+	check(ctx, err, "Failed to start gRPC broker listener")

 	go func() {
-		if err := bkr.grpcServer.Serve(ln); err != nil {
-			logger.Error(err, "Failed to start gRPC broker", "bindAddress", bkr.bindAddress)
-			os.Exit(1)
-		}
+		if err := bkr.grpcServer.Serve(ln); err != nil {
+			logger.Error(err, "Failed to start gRPC broker", "bindAddress", bkr.bindAddress)
+			check(ctx, err, "gRPC broker terminated with errors")
+		}
 	}()
🧹 Nitpick comments (10)
pkg/dispatcher/hash_dispatcher.go (2)

3-20: Import ordering: Group klog with external imports.

The k8s.io/klog/v2 import on line 6 is placed between standard library imports (fmt and sync). Go convention and most linters expect imports to be grouped: standard library first, then external packages.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"sync"
 	"time"

 	"github.com/buraksezer/consistent"
 	"github.com/cespare/xxhash"
 	mapset "github.com/deckarep/golang-set/v2"
 	"github.com/openshift-online/maestro/pkg/api"
 	"github.com/openshift-online/maestro/pkg/client/cloudevents"
 	"github.com/openshift-online/maestro/pkg/config"
 	"github.com/openshift-online/maestro/pkg/dao"
 	"github.com/openshift-online/maestro/pkg/db"
 	"k8s.io/apimachinery/pkg/util/wait"
 	"k8s.io/client-go/util/workqueue"
+	"k8s.io/klog/v2"
 )

99-133: Inconsistent context usage: context.TODO() should be replaced with a proper context.

The updateConsumerSet function now receives a logger (presumably derived from a context), but line 106 still uses context.TODO() for the DAO call. This is inconsistent with the contextual logging migration and loses context propagation benefits (tracing, cancellation).

Consider passing the context as a parameter alongside the logger, or using klog.NewContext to embed the logger into a context.

-func (d *HashDispatcher) updateConsumerSet(logger klog.Logger) error {
+func (d *HashDispatcher) updateConsumerSet(ctx context.Context) error {
+	logger := klog.FromContext(ctx)
 	// return if the hashing ring is not ready
 	if d.consistent == nil || len(d.consistent.GetMembers()) == 0 {
 		return nil
 	}
 	// get all consumers and update the consumer set for the current instance
-	consumers, err := d.consumerDao.All(context.TODO())
+	consumers, err := d.consumerDao.All(ctx)

Then update the call site in check:

-	if err := d.updateConsumerSet(logger); err != nil {
+	if err := d.updateConsumerSet(ctx); err != nil {
cmd/maestro/server/event_server.go (2)

164-166: Align log message wording with log level in handleStatusUpdate.

Using an info-level log whose message begins with WARN: is a bit misleading when scanning logs, especially since this 404 case is being treated as non-fatal. The rest of the new info logs in this function look good; I’d just simplify the “WARN” prefix.

-			logger.Info("WARN: skipping resource as it is not found")
+			logger.Info("skipping resource as it is not found")

Also applies to: 170-170, 230-230, 248-248


266-267: Optionally store the enriched logger back into the context in broadcastStatusEvent.

You’re already enriching the logger with resourceID, instanceID, and eventID; mirroring the pattern from startSubscription by putting this logger back into ctx would let any downstream code that calls klog.FromContext(ctx) inherit the same fields.

-	logger := klog.FromContext(ctx).WithValues("resourceID", resourceID, "instanceID", instanceID, "eventID", eventID)
+	logger := klog.FromContext(ctx).WithValues("resourceID", resourceID, "instanceID", instanceID, "eventID", eventID)
+	ctx = klog.NewContext(ctx, logger)

The existing logs at Lines 285 and 295 look fine and will automatically benefit from this if you choose to make the change.

Also applies to: 285-285, 295-295

test/mocks/workserver/main.go (1)

155-159: Consider flushing klog before os.Exit in the shutdown path

In the signal handler you log with klog and then call os.Exit(0), which will skip any defers and may drop buffered log entries. Consider flushing explicitly before exiting, e.g.:

 func main() {
-	server := NewWorkServer()
+	server := NewWorkServer()
 	server.ParseFlags()
@@
 	go func() {
 		<-sigCh
 		klog.Infof("Shutting down mock server...")
 		if err := server.Shutdown(); err != nil {
 			klog.Errorf("Error during shutdown: %v", err)
 		}
-		os.Exit(0)
+		klog.Flush()
+		os.Exit(0)
 	}()

Also applies to: 172-172, 269-269, 279-281, 286-287

cmd/maestro/main.go (1)

5-5: Use klog for fatal CLI errors instead of the standard log package

Since you already initialize klog flags, using klog.Fatalf here keeps logging consistent with the rest of the binary and avoids pulling in log just for this call:

-import (
-	"flag"
-	"log"
-	"os"
+import (
+	"flag"
+	"os"
@@
-	if err := rootCmd.Execute(); err != nil {
-		log.Fatalf("error running command: %v", err)
-	}
+	if err := rootCmd.Execute(); err != nil {
+		klog.Fatalf("error running command: %v", err)
+	}

Also applies to: 49-51

pkg/handlers/framework.go (1)

7-7: Optionally include operationID in the structured log fields

You already compute operationID from the context; adding it to the log fields would make correlating logs with client-visible error IDs easier:

 func handleError(ctx context.Context, w http.ResponseWriter, err *errors.ServiceError) {
 	operationID := loggertracing.GetOperationID(ctx)
 	logger := klog.FromContext(ctx)
 	// If this is a 400 error, its the user's issue, log as info rather than error
 	if err.HttpCode >= 400 && err.HttpCode <= 499 {
-		logger.Info("user request error", "error", err)
+		logger.Info("user request error", "error", err, "operationID", operationID)
 	} else {
-		logger.Error(err, "user request error")
+		logger.Error(err, "user request error", "operationID", operationID)
 	}
 	writeJSONResponse(w, err.HttpCode, err.AsOpenapiError(operationID))
 }

Also applies to: 11-11, 34-41

pkg/db/context.go (1)

5-7: Simplify error logging and drop the synthetic errors.New allocations

You’re creating new error values solely for logging, then passing an empty message string. You can log a clear message with a nil error and remove the errors import entirely:

 import (
 	"context"
-	"errors"
-	"k8s.io/klog/v2"
+	"k8s.io/klog/v2"
@@
 func Resolve(ctx context.Context) {
 	logger := klog.FromContext(ctx)
 	tx, ok := dbContext.Transaction(ctx)
 	if !ok {
-		logger.Error(errors.New("Could not retrieve transaction from context"), "")
+		logger.Error(nil, "Could not retrieve transaction from context")
 		return
 	}
@@
 	if tx.MarkedForRollback() {
 		if err := tx.Rollback(); err != nil {
 			logger.Error(err, "Could not rollback transaction")
 			return
 		}
 		logger.Info("Rolled back transaction")
@@
 func MarkForRollback(ctx context.Context, err error) {
 	logger := klog.FromContext(ctx)
 	transaction, ok := dbContext.Transaction(ctx)
 	if !ok {
-		logger.Error(errors.New("failed to mark transaction for rollback: could not retrieve transaction from context"), "")
+		logger.Error(nil, "failed to mark transaction for rollback: could not retrieve transaction from context")
 		return
 	}
 	transaction.SetRollbackFlag(true)
 	logger.Info("Marked transaction for rollback", "error", err)
 }

Also applies to: 26-26, 29-30, 35-39, 42-43, 50-51, 53-54, 57-58

test/helper.go (2)

3-20: klog import and mixed logging in tests are acceptable

Bringing in k8s.io/klog/v2 and using it for structured test logs alongside the standard log package for fatal conditions is reasonable for test code. If you later want fully uniform logging, you could consider migrating the remaining log.* calls to klog, but that’s optional.


516-538: CleanDB logging improvement is good; consider using helper.Ctx for DB sessions (optional)

Using a context-derived klog logger and structured fields for table deletion errors is an improvement. The DB session is still created with context.Background(), though, so these operations aren’t tied to the helper context. If you want DB cleanup to honour test cancellation and share the same trace context, you could switch to helper.Ctx here in a follow-up.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between a7cae33 and 0261b12.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (48)
  • cmd/maestro/agent/cmd.go (1 hunks)
  • cmd/maestro/common/otlp_sdk.go (4 hunks)
  • cmd/maestro/environments/framework.go (6 hunks)
  • cmd/maestro/main.go (1 hunks)
  • cmd/maestro/migrate/cmd.go (2 hunks)
  • cmd/maestro/servecmd/cmd.go (4 hunks)
  • cmd/maestro/server/api_server.go (6 hunks)
  • cmd/maestro/server/auth_interceptor.go (4 hunks)
  • cmd/maestro/server/controllers.go (3 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • cmd/maestro/server/healthcheck_server.go (6 hunks)
  • cmd/maestro/server/logging/formatter_json.go (3 hunks)
  • cmd/maestro/server/logging/logging.go (0 hunks)
  • cmd/maestro/server/logging/writer.go (3 hunks)
  • cmd/maestro/server/metrics_server.go (2 hunks)
  • cmd/maestro/server/routes.go (3 hunks)
  • cmd/maestro/server/server.go (3 hunks)
  • go.mod (3 hunks)
  • pkg/api/error.go (5 hunks)
  • pkg/api/metadata.go (4 hunks)
  • pkg/auth/helpers.go (1 hunks)
  • pkg/client/cloudevents/source_client.go (4 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
  • pkg/controllers/event_filter.go (3 hunks)
  • pkg/controllers/framework.go (9 hunks)
  • pkg/controllers/framework_test.go (2 hunks)
  • pkg/controllers/status_controller.go (7 hunks)
  • pkg/db/advisory_locks.go (8 hunks)
  • pkg/db/context.go (2 hunks)
  • pkg/db/db_session/default.go (4 hunks)
  • pkg/db/db_session/test.go (2 hunks)
  • pkg/db/migrations.go (2 hunks)
  • pkg/db/transaction_middleware.go (2 hunks)
  • pkg/dispatcher/hash_dispatcher.go (8 hunks)
  • pkg/dispatcher/noop_dispatcher.go (5 hunks)
  • pkg/errors/errors.go (0 hunks)
  • pkg/event/event.go (5 hunks)
  • pkg/handlers/framework.go (2 hunks)
  • pkg/logger/logger.go (0 hunks)
  • pkg/logger/zap.go (0 hunks)
  • pkg/services/generic.go (3 hunks)
  • pkg/services/resource.go (5 hunks)
  • test/e2e/pkg/suite_test.go (3 hunks)
  • test/helper.go (10 hunks)
  • test/integration/integration_test.go (1 hunks)
  • test/mocks/workserver/main.go (5 hunks)
💤 Files with no reviewable changes (4)
  • pkg/logger/zap.go
  • pkg/errors/errors.go
  • pkg/logger/logger.go
  • cmd/maestro/server/logging/logging.go
🚧 Files skipped from review as they are similar to previous changes (20)
  • cmd/maestro/agent/cmd.go
  • pkg/controllers/event_filter.go
  • pkg/api/metadata.go
  • pkg/auth/helpers.go
  • cmd/maestro/server/logging/formatter_json.go
  • go.mod
  • pkg/api/error.go
  • cmd/maestro/server/logging/writer.go
  • pkg/client/grpcauthorizer/kube_authorizer.go
  • cmd/maestro/common/otlp_sdk.go
  • cmd/maestro/server/grpc_server.go
  • cmd/maestro/server/routes.go
  • pkg/services/generic.go
  • test/integration/integration_test.go
  • pkg/db/advisory_locks.go
  • pkg/db/db_session/test.go
  • pkg/controllers/framework_test.go
  • pkg/dispatcher/noop_dispatcher.go
  • cmd/maestro/server/auth_interceptor.go
  • pkg/db/migrations.go
🧰 Additional context used
🧬 Code graph analysis (6)
pkg/client/cloudevents/source_client.go (4)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/services/resource.go (1)
  • ResourceService (26-39)
pkg/api/metadata_types.go (1)
  • Meta (51-56)
pkg/client/cloudevents/codec.go (1)
  • Codec (17-19)
cmd/maestro/server/api_server.go (2)
cmd/maestro/server/server.go (1)
  • Server (16-21)
cmd/maestro/server/grpc_server.go (1)
  • GRPCServer (36-45)
cmd/maestro/servecmd/cmd.go (7)
cmd/maestro/environments/framework.go (1)
  • Environment (59-61)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
cmd/maestro/environments/types.go (2)
  • MessageBroker (35-36)
  • Database (31-33)
cmd/maestro/server/grpc_broker.go (1)
  • NewGRPCBroker (128-212)
cmd/maestro/server/api_server.go (1)
  • NewAPIServer (40-144)
cmd/maestro/server/controllers.go (1)
  • NewControllersServer (13-48)
cmd/maestro/common/otlp_sdk.go (2)
  • TracingEnabled (68-71)
  • InstallOpenTelemetryTracer (26-64)
cmd/maestro/server/grpc_broker.go (3)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/config/config.go (1)
  • ReadFile (110-135)
cmd/maestro/environments/framework.go (5)
cmd/maestro/environments/types.go (1)
  • Clients (50-54)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
pkg/client/grpcauthorizer/mock_authorizer.go (1)
  • NewMockGRPCAuthorizer (9-11)
pkg/client/ocm/client.go (1)
  • Config (17-24)
cmd/maestro/server/grpc_server.go (1)
  • GRPCServer (36-45)
pkg/controllers/status_controller.go (2)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Red Hat Konflux / maestro-on-pull-request
  • GitHub Check: migration
  • GitHub Check: e2e-grpc-broker
  • GitHub Check: e2e
  • GitHub Check: e2e-broadcast-subscription
  • GitHub Check: e2e-with-istio
🔇 Additional comments (50)
cmd/maestro/migrate/cmd.go (1)

5-6: LGTM: Import additions support the logging migration.

The klog/v2 import aligns with the PR's objective to migrate to contextual logging.

pkg/db/db_session/default.go (4)

7-7: LGTM!

The klog import is correctly added and follows standard Go conventions.


142-161: LGTM!

The migration to klog's contextual logging is well-executed:

  • Logger initialization via klog.FromContext(ctx) is correct
  • Verbosity level V(4) for detailed notification logs is appropriate
  • Structured fields are descriptive and properly formatted

171-175: LGTM!

The error logging migration is correct:

  • Logger initialization follows the standard pattern
  • logger.Error is called with the correct signature: error, message, and structured key-value pairs
  • The eventType field properly captures the listener event type

200-203: LGTM!

The migration from printf-style to structured logging is correct, with the channel field properly captured.

pkg/services/resource.go (4)

5-5: LGTM!

The klog import is correctly added to support contextual logging migration.


162-163: LGTM!

The contextual logger creation follows klog best practices and enriches all subsequent logs with the resourceID for better correlation.


184-185: LGTM!

The structured logging correctly captures version mismatch with clear, camelCase keys for easy parsing.


199-200: LGTM!

The logging levels are appropriately chosen: Info for the operation and V(4) for detailed event data, following klog verbosity conventions.

pkg/dispatcher/hash_dispatcher.go (1)

150-203: LGTM on the check function's logging migration.

The context-derived logger usage and structured logging with key-value pairs (addedMembers, removedMembers) are well implemented.

cmd/maestro/server/event_server.go (2)

6-6: klog import and usage look consistent.

The new k8s.io/klog/v2 import is used coherently throughout this file for context-based logging; no issues here.


78-79: Context-based startup/shutdown logging is correctly wired.

Deriving the logger from ctx and using it for start/shutdown messages keeps lifecycle logs consistent with the rest of the server; nothing to change.

Also applies to: 88-88

pkg/db/transaction_middleware.go (1)

6-7: Contextual transaction error logging looks correct

Deriving the logger from ctx and using it for the “Could not create transaction” path, while keeping the user-facing error generic and keyed by operationID, is consistent with the rest of the logging refactor and preserves behavior.

Also applies to: 22-25, 27-28

pkg/client/cloudevents/source_client.go (1)

8-8: Good use of per-call contextual loggers in CloudEvents client

Using klog.FromContext(ctx).WithValues(...) and then klog.NewContext(ctx, logger) in OnCreate/OnUpdate/OnDelete/Resync cleanly scopes logs with resourceID/consumers and propagates the enriched logger downstream. The updated Info/Error calls around publish and not-found paths look correct and preserve existing behavior.

Also applies to: 57-88, 90-115, 117-146, 152-157

pkg/event/event.go (1)

5-5: Context-aware broadcaster logging is consistent and useful

Register/Unregister now accept ctx and use klog.FromContext(ctx) (with id/source fields) plus Start uses the same logger for lifecycle and handler error logs. This aligns with the rest of the klog refactor and should make tracking per-source events much easier without changing behavior.

Also applies to: 41-57, 60-74, 82-86, 93-101

cmd/maestro/server/healthcheck_server.go (3)

51-53: LGTM!

Proper context-aware logger setup using klog.FromContext with structured key-value pairs via WithValues. The logger is correctly injected back into the context for downstream use.


87-122: LGTM!

The pulse method correctly derives a logger from context and uses proper structured logging with key-value pairs for all logger.Error and logger.V(4).Info calls.


176-201: LGTM!

The healthCheckHandler correctly derives a per-request logger from the request context with instance ID attached, and uses proper structured logging throughout the handler.

cmd/maestro/servecmd/cmd.go (3)

52-55: LGTM!

Good setup pattern: creating a named logger with klog.NewKlogr().WithName(), then injecting it into the context with klog.NewContext(). This enables context-aware logging throughout the server lifecycle.


85-88: LGTM!

Context is correctly propagated to the server constructors (NewAPIServer, NewControllersServer), aligning with the updated constructor signatures that now accept context.Context.


122-124: LGTM!

Context is correctly passed to the Start methods of the servers, enabling context-aware lifecycle management and logging throughout the server components.

pkg/controllers/status_controller.go (4)

51-66: LGTM!

The Run method correctly derives a logger from context, uses wait.JitterUntilWithContext and wait.UntilWithContext for context-aware goroutine management, and properly waits on ctx.Done() for graceful shutdown.


76-99: LGTM!

The processNextEvent method correctly propagates context to handleStatusEvent and uses structured logging with key-value pairs for error reporting.


104-106: LGTM!

Good pattern: creating a per-event logger with the event ID attached via WithValues, then creating a new context that carries both the enriched logger and the StatusEventID value for downstream handlers.


161-190: LGTM!

The syncStatusEvents method correctly derives a logger from context and uses proper structured logging throughout, including informational messages with key-value pairs and error logging.

test/e2e/pkg/suite_test.go (2)

213-216: LGTM!

Appropriate use of klog.Errorf for test reporting. Using printf-style logging in test suites is acceptable and simpler than structured logging for diagnostic output.


246-252: LGTM!

The pod log dumping uses klog.Infof appropriately for test diagnostic output. The verbose log formatting with separators helps with test debugging.

cmd/maestro/environments/framework.go (4)

73-78: LGTM!

Using klog.Infof for initialization logging and retaining log.Fatalf for fatal errors is appropriate. Fatal errors need immediate termination which log.Fatalf provides.


159-170: LGTM!

Appropriate use of klog.V(4).Info for debug-level verbose logging when using mock clients. The verbosity level 4 keeps these logs hidden in normal operation.


196-214: LGTM!

Good use of klog.V(4).Info and klog.V(4).Infof for debug-level logging in the GRPC authorizer setup path. The fallback logging on line 203 appropriately uses printf-style for the detailed error message.


227-233: LGTM!

Proper use of klog.V(4).Infof and klog.V(4).Info for Sentry initialization logging at debug verbosity level.

cmd/maestro/server/server.go (1)

16-21: Context-aware Server interface and check helper look consistent

Switching Server.Start/Serve and check to accept context.Context and using klog.FromContext(ctx) for fatal logging keeps existing behaviour (including the http.ErrServerClosed special-case) while enabling contextual logs. Looks good and matches how callers now pass ctx.

Also applies to: 30-39

cmd/maestro/server/grpc_broker.go (2)

127-188: NewGRPCBroker context plumbing and TLS handling look correct

Deriving logger := klog.FromContext(ctx) and routing all TLS / CA configuration failures through check(ctx, ...) gives you consistent fatal handling (log + Sentry + exit) and context-aware logging. The TLS config and log messages for TLS vs non‑TLS startup also look coherent.


271-288: PredicateEvent’s contextual logging is well integrated

Using logger := klog.FromContext(ctx) and logger.V(4).Info for the “resource deleted” path adds useful detail (source ID, reconciliation) without making normal logs noisy. The rest of the predicate logic is unchanged and now benefits from the per-request logger.

cmd/maestro/server/api_server.go (2)

40-44: NewAPIServer now threads context correctly through routes, auth, and gRPC init

Accepting ctx in NewAPIServer, passing it into routes(ctx) and NewGRPCServer(ctx, ...), and using check(ctx, err, ...) for the auth logger/handler setup keeps behaviour the same while ensuring failures are centrally reported (including Sentry) with contextual logs. This is a solid, consistent migration.

Also applies to: 62-83, 140-142


148-171: Serve(ctx, listener) context-aware logging and error handling look good

Deriving logger := klog.FromContext(ctx), validating TLS files via check(ctx, ...), and then using check(ctx, err, "Web server terminated with errors") after Serve/ServeTLS correctly distinguishes normal shutdown (nil/http.ErrServerClosed) from fatal termination while keeping logs and Sentry reporting context-aware. The TLS / non‑TLS informational logs on the configured port are also appropriate.

cmd/maestro/server/controllers.go (2)

13-27: NewControllersServer context/logging integration looks correct

Accepting ctx and using logger := klog.FromContext(ctx) only for the informational “Message broker is enabled...” log keeps construction side-effect-free while making the message contextual. The rest of the wiring (status controller, kind controller manager) remains unchanged.


58-76: ControllersServer.Start(ctx) correctly scopes and propagates a named logger

Deriving logger := klog.FromContext(ctx).WithName("maestro-controllers"), re‑embedding it via klog.NewContext, and then passing that context into KindControllerManager.Run, StatusController.Run, and the DB listeners provides consistent, component-scoped logging. The <-ctx.Done() wait matches the new context-based shutdown semantics.

pkg/controllers/framework.go (4)

88-104: Run(ctx) uses context-aware loops and shutdown correctly

Switching to Run(ctx context.Context) with wait.JitterUntilWithContext for syncEvents and wait.UntilWithContext for runWorker, plus a final <-ctx.Done() and deferred eventsQueue.ShutDown(), keeps the original behaviour while making shutdown driven by ctx. This matches upstream controller patterns.


118-194: handleEvent(ctx, id) context and logging refactor looks sound

Creating an event-scoped logger (WithValues(EventID, id)) and a reqContext that carries both the logger (klog.NewContext) and EventID key, then consistently using that context for eventFilter.Filter/DeferredAction, events.Get/Replace, and handler functions preserves behaviour while improving traceability. The metrics and reconciliation logic are unchanged and correctly cover all branches.


196-230: Worker loop and per-item logging are correctly adapted to context

runWorker(ctx) now simply loops on processNextEvent(ctx), and processNextEvent derives a per-item logger with the key field and delegates to handleEvent(ctx, key). Requeueing via AddRateLimited on non‑reconciled events and Forget on success is unchanged; the refactor only adds contextual logging and shutdown via queue shutdown/caller context.


232-258: syncEvents(ctx) now respects context and adds useful structured logs

Using klog.FromContext(ctx) to log “purge all reconciled events” and “sync all unreconciled events”, and passing ctx down into DeleteAllReconciledEvents and FindAllUnreconciledEvents, adds cancellation support and better observability without changing behaviour. Error paths still increment the appropriate metrics and return early.

test/helper.go (8)

99-180: Helper initialization now wires shared context through GRPC broker and test servers correctly

Creating ctx, cancel := context.WithCancel(context.Background()) once and using that same context for NewGRPCBroker(ctx, helper.EventBroadcaster), startHealthCheckServer(), and startEventServer() ensures all test-managed components share a single cancellation root (ContextCancelFunc). This should make teardown via sendShutdownSignal behave predictably. No functional issues spotted.


198-209: startAPIServer uses context-aware server APIs and logs lifecycle

Using logger := klog.FromContext(helper.Ctx), constructing the API server with server.NewAPIServer(helper.Ctx, helper.EventBroadcaster), and then starting it in a goroutine with contextual V(4) logs for start/stop aligns with the new Server.Start(ctx) signature and provides useful test logs.


218-226: startMetricsServer context/logging changes are consistent

The metrics server is now started with helper.Ctx and wrapped in a goroutine that logs start/stop at V(4) using a context-derived klog logger. This matches the API server pattern and should respect the same cancellation semantics.


235-241: startHealthCheckServer now respects helper context and logs lifecycle

Starting the health check server with helper.Ctx and surrounding it with V(4) lifecycle logs is consistent with how the other servers are managed and will shut down cleanly when the helper context is cancelled.


249-255: startEventServer adopts the same context-aware pattern

Using klog.FromContext(helper.Ctx) for logs and helper.EventServer.Start(helper.Ctx) in a goroutine integrates the event server into the shared test context lifecycle, mirroring the API and metrics servers.


258-264: startEventBroadcaster now has contextual logging around Start

Wrapping EventBroadcaster.Start(helper.Ctx) with V(4) logs for start/stop adds useful visibility in tests, and using helper.Ctx hooks broadcaster lifetime into the same cancellation mechanism as the servers.


362-367: RestartServer now emits debug logs using the shared context logger

After stopping and restarting the API server, logging “Test API server restarted” at V(4) via klog.FromContext(helper.Ctx) is consistent with the rest of the helper’s logging and should aid debugging without changing behaviour.


369-374: RestartMetricsServer adds symmetric debug logging

The new V(4) “Test metrics server restarted” log using the context-derived logger mirrors the API server restart logging and is a straightforward observability improvement.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmd/maestro/migrate/cmd.go (1)

37-39: Use klog consistently for all error logging.

Line 38 uses the standard library log.Fatal, while Line 33 uses klog.Fatal. Since this PR explicitly migrates to klog's contextual logging, both fatal errors should use klog for consistency.

Apply this diff to use klog consistently:

 	connection := db_session.NewProdFactory(dbConfig)
 	if err := db.Migrate(connection.New(context.Background())); err != nil {
-		log.Fatal(err)
+		klog.Fatal(err)
 	}

After applying this change, you can remove the standard library log import from line 6, as it will no longer be needed:

 import (
 	"context"
 	"k8s.io/klog/v2"
-	"log"
 
 	"github.com/openshift-online/maestro/pkg/db/db_session"
♻️ Duplicate comments (11)
pkg/dispatcher/noop_dispatcher.go (1)

71-71: Fix typo: "resourcs" should be "resource".

The log message contains a typo that was previously flagged but remains unfixed.

Apply this diff:

-				logger.Error(err, "failed to resync resourcs status for consumers", "consumers", consumerIDs)
+				logger.Error(err, "failed to resync resource status for consumers", "consumers", consumerIDs)
pkg/dispatcher/hash_dispatcher.go (1)

230-235: Missing Forget call on successful resync.

After a successful resync (no error), d.workQueue.Forget(key) should be called to prevent unnecessary rate-limiting on future requeues of the same key. Currently, only the error path calls AddRateLimited, but without Forget on success, the rate limiter's backoff state for this key persists.

Apply this diff to add the Forget call:

 	logger.Info("processing status resync request for consumer", "consumer", consumerName)
 	if err := d.sourceClient.Resync(ctx, []string{consumerName}); err != nil {
 		logger.Error(err, "failed to resync resources status for consumer", "consumer", consumerName)
 		// Put the item back on the workqueue to handle any transient errors.
 		d.workQueue.AddRateLimited(key)
+	} else {
+		// Resync succeeded, forget the key to reset the rate limiter.
+		d.workQueue.Forget(key)
 	}
cmd/maestro/server/healthcheck_server.go (2)

71-74: Incorrect printf-style formatting in klog structured logging.

The logger.Info calls use printf-style %s format specifiers, which will appear literally in the log output. Klog's structured logging requires key-value pairs instead.

Apply this diff:

-		logger.Info("Serving HealthCheck with TLS at %s", env().Config.HealthCheck.BindPort)
+		logger.Info("Serving HealthCheck with TLS", "port", env().Config.HealthCheck.BindPort)
 		err = s.httpServer.ListenAndServeTLS(env().Config.HTTPServer.HTTPSCertFile, env().Config.HTTPServer.HTTPSKeyFile)
 	} else {
-		logger.Info("Serving HealthCheck without TLS at %s", env().Config.HealthCheck.BindPort)
+		logger.Info("Serving HealthCheck without TLS", "port", env().Config.HealthCheck.BindPort)

163-170: Malformed klog.Error calls with printf-style specifiers.

The logger.Error calls mix printf-style format specifiers with structured key-value logging. The %s placeholders will appear literally and not be substituted.

Apply this diff:

 	if len(activeInstanceIDs) > 0 {
 		// batch mark active instances.
 		if err := s.instanceDao.MarkReadyByIDs(ctx, activeInstanceIDs); err != nil {
-			logger.Error(err, "Unable to mark active maestro instances %s", "activeInstanceIDs", activeInstanceIDs)
+			logger.Error(err, "Unable to mark active maestro instances", "activeInstanceIDs", activeInstanceIDs)
 		}
 	}
 
 	if len(inactiveInstanceIDs) > 0 {
 		// batch mark inactive instances.
 		if err := s.instanceDao.MarkUnreadyByIDs(ctx, inactiveInstanceIDs); err != nil {
-			logger.Error(err, "Unable to mark inactive maestro instances (%s): %s", "inactiveInstanceIDs", inactiveInstanceIDs)
+			logger.Error(err, "Unable to mark inactive maestro instances", "inactiveInstanceIDs", inactiveInstanceIDs)
 		}
 	}
cmd/maestro/server/routes.go (2)

37-39: Undefined variable err when EnableJWT is false.

This issue was already flagged in a previous review. The err variable is only declared inside the if env().Config.HTTPServer.EnableJWT block (line 33), so this code will fail to compile when JWT is disabled.


41-45: Undefined variable err when EnableJWT is false.

This issue was already flagged in a previous review. The check(ctx, err, ...) call references err which is only in scope if EnableJWT was true.

cmd/maestro/server/grpc_broker.go (1)

215-227: Inconsistent error handling bypasses Sentry reporting.

This was flagged in a previous review. The direct os.Exit(1) calls bypass the check() function's Sentry error capture. Consider using check(ctx, err, "...") for consistency with error reporting elsewhere.

cmd/maestro/server/event_server.go (1)

103-103: Format specifier %s in log message with no arguments.

This log message contains %s but no arguments are passed. This was identified in a previous review.

-				logger.Info("skipping resource status update %s as it is not owned by the current instance")
+				logger.Info("skipping resource status update as it is not owned by the current instance")
cmd/maestro/servecmd/cmd.go (2)

77-78: Incorrect klog.Error usage with empty message string.

The second argument to logger.Error should be a descriptive message, not an empty string. This was identified in a previous review.

-			logger.Error(errors.New("Unsupported subscription type"), "", "subscriptionType", subscriptionType)
+			logger.Error(nil, "Unsupported subscription type", "subscriptionType", subscriptionType)

113-115: Bug: Wrong error variable logged for tracing shutdown failure.

The condition checks tracingShutdown(ctx) != nil but logs the err variable from line 92-93, not the shutdown error. This was identified in a previous review.

-		if tracingShutdown != nil && tracingShutdown(ctx) != nil {
-			logger.Error(err, "OpenTelemetry trace provider failed to shutdown")
+		if tracingShutdown != nil {
+			if shutdownErr := tracingShutdown(ctx); shutdownErr != nil {
+				logger.Error(shutdownErr, "OpenTelemetry trace provider failed to shutdown")
+			}
 		}
test/helper.go (1)

377-378: Typo in log message: "Reseting" should be "Resetting".

The log message contains a spelling error that should be corrected for consistency.

Apply this diff to fix the typo:

-	logger.Info("Reseting testing environment")
+	logger.Info("Resetting testing environment")
🧹 Nitpick comments (15)
pkg/handlers/framework.go (1)

34-42: Contextual logging and operation ID wiring look correct; optionally include opID in log fields

Using loggertracing.GetOperationID(ctx) together with klog.FromContext(ctx) and distinguishing 4xx as Info vs others as Error is consistent and safe; this fits the contextual-logging goal well. You might consider also adding the operation ID as a structured field on these logs (e.g., "operation_id", operationID) so operators can correlate logs and responses without having to inspect the payload alone, but this is purely a nice-to-have.

If you want to double‑check best practices for klog contextual usage and structured fields, please confirm against the current klog v2 docs.

pkg/db/db_session/test.go (1)

54-70: Consider contextual logging for consistency with PR objectives.

The PR aims to use klog's contextual logging, but Init uses global klog.Errorf instead of klog.FromContext(ctx). This is because Init lacks a context.Context parameter.

If test setup can provide a context, consider updating the signature to:

func (f *Test) Init(ctx context.Context, config *config.DatabaseConfig)

and using:

klog.FromContext(ctx).Error(err, "error initializing test database")

If context is unavailable during test initialization, the current approach is acceptable.

Additionally, note that errors logged inside testOnce.Do are not propagated, which may obscure initialization failures in tests.

pkg/dispatcher/noop_dispatcher.go (2)

77-90: Consider context-aware logging for consistency.

The onInstanceUpdate callback uses global klog functions (lines 80, 87) while the rest of the file uses contextual logging. This inconsistency reduces observability uniformity.

If feasible, consider updating the listener API to pass context to callbacks, enabling:

func (d *NoopDispatcher) onInstanceUpdate(ctx context.Context, ids string) {
	logger := klog.FromContext(ctx)
	// ...
	logger.Info("watched server instances updated with invalid ids", "ids", ids)
	// ...
	logger.Error(err, "failed to call OnInstancesDown")
}

98-117: Thread context through for better observability.

The use of context.TODO() (line 102) creates a fresh context that loses the parent context chain, including trace IDs, logger configuration, and cancellation signals.

Consider refactoring onInstanceDown to accept a context parameter:

func (d *NoopDispatcher) onInstanceDown(ctx context.Context) error {
	consumerIDs := []string{}
	consumers, err := d.consumerDao.All(ctx)
	// ... rest of implementation
}

This would require upstream changes to onInstanceUpdate to also accept and propagate context (see previous comment).

cmd/maestro/main.go (2)

3-6: Prefer klog for fatal path and ensure logs are flushed

Since this binary is now klog-centric, using log.Fatalf here means the last error message is formatted differently from the rest of the logs and won’t go through klog’s machinery.

Consider instead:

klog.ErrorS(err, "error running command")
os.Exit(1)

and add a flush near initialization:

klog.InitFlags(nil)
defer klog.Flush()

This keeps logging consistent and ensures buffered klog output is flushed before exit.

Also applies to: 49-51


18-21: Validate whether logConfigFile / varLogLevel are still needed

These constants look tied to the removed viper/fsnotify-based logging config and are not referenced in this file. If they’re not used elsewhere in package main, they’ll trigger “declared but not used” build errors and add confusion.

Please either remove them or confirm they’re still used from another file in this package.

test/e2e/pkg/suite_test.go (1)

9-9: Consider grouping imports idiomatically.

The k8s.io/klog/v2 import is placed between standard library imports. Go convention groups imports as: standard library, external packages, then internal packages.

 import (
 	"bytes"
 	"context"
 	"crypto/tls"
 	"flag"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net/http"
 	"os"
 	"testing"
 	"time"

 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/rand"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/tools/clientcmd"
+	"k8s.io/klog/v2"
cmd/maestro/server/server.go (1)

4-5: Consider grouping imports idiomatically.

The k8s.io/klog/v2 import should be grouped with other external packages rather than placed between standard library imports.

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"net"
 	"net/http"
 	"os"
 	"strings"

 	"github.com/getsentry/sentry-go"
+	"k8s.io/klog/v2"

 	"github.com/openshift-online/maestro/cmd/maestro/environments"
 )
cmd/maestro/server/grpc_broker.go (1)

8-8: Consider grouping imports idiomatically.

The k8s.io/klog/v2 import should be grouped with other external packages.

 import (
 	"context"
 	"crypto/tls"
 	"crypto/x509"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net"
 	"os"
 	"time"

 	ce "github.com/cloudevents/sdk-go/v2"
 	...
 	kubeerrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/klog/v2"
pkg/event/event.go (1)

5-5: Consider grouping imports idiomatically.

The k8s.io/klog/v2 import should be grouped with other external packages rather than placed between standard library imports.

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"sync"

 	"github.com/google/uuid"
+	"k8s.io/klog/v2"
+
 	"github.com/openshift-online/maestro/pkg/api"
 )
cmd/maestro/server/event_server.go (1)

170-170: Avoid embedding log level in message text.

The "WARN:" prefix in the message is unconventional with klog. Since klog lacks a dedicated warn method, consider either removing the prefix (the message is self-explanatory) or using a higher verbosity level if this is meant to be less prominent.

-			logger.Info("WARN: skipping resource as it is not found")
+			logger.Info("skipping resource status update, resource not found")
pkg/controllers/status_controller.go (3)

68-99: Context‑aware worker loop and queue processing look sound

Passing ctx through runWorker into processNextEvent and on to handleStatusEvent aligns the whole processing path with contextual logging and cancellation, and the queue semantics (Done, Forget, AddRateLimited on error, quit handling) remain unchanged.

If you want slightly better observability on shutdown, consider logging once when eventsQueue.Get() returns quit == true (queue draining) so operators can distinguish “no work” from “controller exiting”.


104-145: Context‑scoped logger and per‑event context are wired correctly

Deriving a per‑event logger from klog.FromContext(ctx) and wrapping it back into reqContext keeps logs and downstream calls (service/DAO + handlers) aligned on the same event, while preserving the existing metrics and reconciliation logic.

If StatusEventID is not read from ctx.Value anywhere else, you could drop the additional context.WithValue layer and rely solely on WithValues for logging; otherwise, leave as-is. A quick repo search for StatusEventID usages can confirm this.


161-190: Sync loop now respects context and uses structured logging

Making syncStatusEvents context‑aware and deriving the logger from ctx integrates nicely with the rest of the controller; DB errors are logged and surfaced via metrics, and successful cleanup is still counted.

For very large clusters, consider logging only the count (or a capped sample) of readyInstanceIDs instead of the full slice to keep logs compact, unless you explicitly need the full list for troubleshooting.

test/mocks/workserver/main.go (1)

10-10: Initialize klog flags before parsing CLI flags for proper log configuration

You're using klog/v2 alongside the standard flag package. The recommended pattern is to call klog.InitFlags(nil) before flag.Parse() to register klog's standard flags (e.g., -v, -logtostderr) so they're available for runtime configuration. This applies even to test mock binaries that may need log level tuning during debugging.

 func (s *WorkServer) ParseFlags() {
+	klog.InitFlags(nil)
 	flag.StringVar(&s.apiServerAddress, "api-server", "", "Maestro Restful API server address")
 	flag.StringVar(&s.grpcServerAddress, "grpc-server", "", "Maestro gRPC server address")
 	flag.StringVar(&s.consumerName, "consumer-name", "", "Consumer name is used to identify the consumer")
 	flag.StringVar(&s.bindAddress, "bind-address", ":8080", "Address to bind the mock server HTTP API")
 	flag.Parse()
 }

Also consider calling klog.Flush() before exit in main() to ensure buffered logs are written.

Also applies to: 10, 65–71, 264–288

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 0261b12 and 37bb676.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (49)
  • cmd/maestro/agent/cmd.go (1 hunks)
  • cmd/maestro/common/otlp_sdk.go (4 hunks)
  • cmd/maestro/environments/framework.go (6 hunks)
  • cmd/maestro/main.go (1 hunks)
  • cmd/maestro/migrate/cmd.go (2 hunks)
  • cmd/maestro/servecmd/cmd.go (4 hunks)
  • cmd/maestro/server/api_server.go (6 hunks)
  • cmd/maestro/server/auth_interceptor.go (4 hunks)
  • cmd/maestro/server/controllers.go (3 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • cmd/maestro/server/healthcheck_server.go (6 hunks)
  • cmd/maestro/server/logging/formatter_json.go (3 hunks)
  • cmd/maestro/server/logging/logging.go (0 hunks)
  • cmd/maestro/server/logging/writer.go (3 hunks)
  • cmd/maestro/server/metrics_server.go (2 hunks)
  • cmd/maestro/server/routes.go (3 hunks)
  • cmd/maestro/server/server.go (3 hunks)
  • go.mod (3 hunks)
  • pkg/api/error.go (5 hunks)
  • pkg/api/metadata.go (4 hunks)
  • pkg/auth/helpers.go (1 hunks)
  • pkg/client/cloudevents/source_client.go (4 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
  • pkg/controllers/event_filter.go (3 hunks)
  • pkg/controllers/framework.go (9 hunks)
  • pkg/controllers/framework_test.go (2 hunks)
  • pkg/controllers/status_controller.go (7 hunks)
  • pkg/db/advisory_locks.go (8 hunks)
  • pkg/db/context.go (2 hunks)
  • pkg/db/db_session/default.go (4 hunks)
  • pkg/db/db_session/test.go (2 hunks)
  • pkg/db/migrations.go (2 hunks)
  • pkg/db/transaction_middleware.go (2 hunks)
  • pkg/dispatcher/hash_dispatcher.go (8 hunks)
  • pkg/dispatcher/noop_dispatcher.go (5 hunks)
  • pkg/errors/errors.go (0 hunks)
  • pkg/event/event.go (5 hunks)
  • pkg/handlers/framework.go (2 hunks)
  • pkg/logger/logger.go (0 hunks)
  • pkg/logger/zap.go (0 hunks)
  • pkg/services/generic.go (3 hunks)
  • pkg/services/resource.go (5 hunks)
  • test/e2e/pkg/suite_test.go (3 hunks)
  • test/helper.go (10 hunks)
  • test/integration/integration_test.go (1 hunks)
  • test/mocks/workserver/main.go (5 hunks)
  • test/upgrade/pkg/suite_test.go (2 hunks)
💤 Files with no reviewable changes (4)
  • pkg/errors/errors.go
  • pkg/logger/zap.go
  • cmd/maestro/server/logging/logging.go
  • pkg/logger/logger.go
🚧 Files skipped from review as they are similar to previous changes (13)
  • cmd/maestro/server/logging/formatter_json.go
  • pkg/services/resource.go
  • pkg/db/context.go
  • pkg/auth/helpers.go
  • test/integration/integration_test.go
  • pkg/db/migrations.go
  • cmd/maestro/agent/cmd.go
  • cmd/maestro/server/metrics_server.go
  • pkg/db/advisory_locks.go
  • cmd/maestro/server/auth_interceptor.go
  • pkg/db/db_session/default.go
  • pkg/controllers/event_filter.go
  • pkg/client/grpcauthorizer/kube_authorizer.go
🧰 Additional context used
🧬 Code graph analysis (8)
cmd/maestro/server/logging/writer.go (1)
cmd/maestro/server/logging/formatter.go (1)
  • LogFormatter (5-8)
cmd/maestro/server/controllers.go (4)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/controllers/framework.go (1)
  • KindControllerManager (52-57)
cmd/maestro/environments/types.go (1)
  • Database (31-33)
pkg/db/session.go (1)
  • SessionFactory (13-21)
cmd/maestro/server/api_server.go (2)
cmd/maestro/server/server.go (1)
  • Server (16-21)
cmd/maestro/server/grpc_server.go (2)
  • NewGRPCServer (48-146)
  • GRPCServer (36-45)
pkg/controllers/framework.go (3)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/event.go (1)
  • EventType (9-9)
pkg/api/openapi/model_error.go (1)
  • Error (21-28)
pkg/db/transaction_middleware.go (2)
pkg/errors/errors.go (1)
  • GeneralError (161-163)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
cmd/maestro/server/event_server.go (3)
pkg/api/resource_types.go (1)
  • Resource (14-27)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
cmd/maestro/server/grpc_broker.go (3)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/config/config.go (1)
  • ReadFile (110-135)
pkg/handlers/framework.go (1)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: e2e-with-istio
  • GitHub Check: migration
  • GitHub Check: e2e
  • GitHub Check: e2e-broadcast-subscription
  • GitHub Check: e2e-grpc-broker
  • GitHub Check: Red Hat Konflux / maestro-e2e-on-pull-request
  • GitHub Check: Red Hat Konflux / maestro-on-pull-request
🔇 Additional comments (70)
cmd/maestro/migrate/cmd.go (2)

5-5: Good addition of klog import.

The addition of k8s.io/klog/v2 aligns with the PR objective to migrate to klog's contextual logging.


31-34: LGTM!

The migration from the custom logger to klog.Fatal for config read errors is appropriate and consistent with the PR objective.

go.mod (2)

93-93: Verify dependency graph consistency after logging infrastructure migration.

The changes reflect the transition from Zap/Viper (removed from direct requires) to klog. Now marked as indirect:

  • fsnotify/fsnotify v1.7.0 (line 93)
  • go.uber.org/zap v1.27.1 (line 173)
  • google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 (line 186, newly added)

Confirm that: (1) viper was indeed a direct dependency and is now fully removed, (2) google.golang.org/genproto version is current and secure, and (3) no transitive klog dependencies are missing from the indirect block.


56-56: klog/v2 v2.130.1 is compatible with k8s.io v0.33.4.

This version pairing is used in upstream Kubernetes projects and represents the correct alignment for the migration from Zap-based logging to klog contextual logging.

pkg/db/db_session/test.go (1)

7-7: LGTM!

Import addition for klog is correct and necessary for the logging changes below.

pkg/client/cloudevents/source_client.go (5)

8-8: LGTM! klog import added for contextual logging.

The klog import is correctly added to support the migration from custom logging to Kubernetes structured logging.


57-88: Excellent contextual logging implementation in OnCreate.

The method correctly:

  • Extracts and enriches the logger with resourceID for request tracing
  • Propagates the enriched context to downstream calls (ResourceService.Get, ResourceService.Delete, CloudEventSourceClient.Publish)
  • Uses structured logging with logger.Info() and logger.Error(err, msg) following klog best practices

90-115: LGTM! OnUpdate follows the same contextual logging pattern.

The implementation is consistent with OnCreate, properly enriching the logger and propagating context throughout the method.


117-146: LGTM! OnDelete consistently implements contextual logging.

The method follows the established pattern with proper logger enrichment and context propagation.


152-164: LGTM! Resync method properly implements contextual logging.

The method appropriately enriches the logger with the consumers list, making it easy to trace resync operations across multiple consumers.

pkg/dispatcher/hash_dispatcher.go (3)

6-6: LGTM: klog import added correctly.

The import aligns with the PR's objective to migrate to klog-based contextual logging.


151-203: LGTM: Context propagation and logging migration done correctly.

The check method properly extracts the logger from context and uses it consistently for all log statements. Context is correctly passed to instanceDao.All(ctx).


100-109: Inconsistent context usage in updateConsumerSet.

The method signature now accepts a logger parameter for contextual logging, but Line 106 still uses context.TODO() for the database call. This is inconsistent with the PR's objective of propagating context throughout the codebase.

Consider either:

  1. Accepting a context.Context parameter alongside the logger, or
  2. Extracting the context from the logger if klog supports it, or
  3. Threading context from the call sites where the caller already has context
cmd/maestro/server/logging/writer.go (1)

8-10: LGTM!

Correctly derives the logger from the request context using klog.FromContext(), aligning with the project-wide migration to context-aware logging.

test/upgrade/pkg/suite_test.go (1)

6-6: LGTM! Clean migration to klog.

The replacement of the local logger with klog.Errorf is correct and maintains the same logging behavior.

Also applies to: 65-65

pkg/services/generic.go (1)

7-7: LGTM! Correct context-aware logging implementation.

The migration to context-derived logging using klog.FromContext is correct, and the logger.Info calls properly use plain messages without printf-style format specifiers.

Also applies to: 220-240

cmd/maestro/environments/framework.go (1)

5-6: LGTM! Appropriate logging migration with correct verbosity levels.

The migration to klog is well-executed:

  • Normal logging uses klog with appropriate verbosity levels (V(4) for debug)
  • Fatal initialization errors appropriately retain log.Fatalf
  • Format string usage with klog.V(4).Infof is correct

Also applies to: 73-73, 159-232

pkg/api/error.go (1)

6-6: LGTM! Excellent per-request structured logging.

The migration to context-derived logging is well-implemented:

  • Per-request logger properly derived from r.Context()
  • Structured logging with key-value pairs (e.g., "path", r.URL.Path)
  • Consistent error logging pattern throughout

Also applies to: 42-43, 64-65, 76-77, 108-108

pkg/api/metadata.go (1)

23-23: LGTM! Consistent per-request logging pattern.

The context-derived logging follows the same correct pattern as in error.go:

  • Logger properly derived from request context
  • Structured key-value logging
  • Clean and consistent implementation

Also applies to: 34-34, 58-58, 69-69, 95-95

pkg/db/transaction_middleware.go (1)

6-7: LGTM! Correct context-aware logging with proper namespace handling.

The migration is well-executed:

  • Logger derived from transaction context
  • Import aliasing (loggertracing) properly avoids naming conflicts
  • Structured error logging follows klog patterns

Also applies to: 22-27

cmd/maestro/common/otlp_sdk.go (1)

5-5: LGTM! Correct API signature update for klog integration.

The function signature change to accept klog.Logger is consistent with the PR objectives:

  • All logging properly uses the passed logger
  • Structured logging with logger.Info and logger.Error
  • Breaking change is intentional and aligns with the broader migration

Also applies to: 26-27, 60-60

cmd/maestro/server/healthcheck_server.go (1)

51-53: LGTM! Correct context-aware logging implementation.

The migration to context-derived logging is well-implemented:

  • Logger properly enriched with instanceID and propagated through context
  • Context passed correctly to periodic functions (pulse, checkInstances)
  • Structured logging with proper key-value pairs in most locations
  • Per-request logger in healthCheckHandler

Also applies to: 78-84, 88-122, 132-146, 177-202

pkg/controllers/framework_test.go (2)

87-89: LGTM!

The context propagation to handleEvent calls is correct and aligns with the signature change. Using the existing ctx from context.Background() is appropriate for unit tests.


198-200: LGTM!

Consistent context propagation matching the first test function.

test/e2e/pkg/suite_test.go (2)

213-213: LGTM!

Correctly migrated to klog.Errorf for error logging in the report generation failure path.


246-252: LGTM!

The pod log dumping now uses klog.Infof consistently. The structured output for container status and pod logs is appropriate.

cmd/maestro/server/routes.go (1)

18-18: LGTM!

The routes method correctly accepts a context parameter for propagating context-aware error handling.

cmd/maestro/server/server.go (2)

16-21: LGTM!

The Server interface correctly updated to require context in Start and Serve methods, enabling context-aware logging and cancellation throughout the server lifecycle.


31-38: LGTM!

The check function correctly:

  • Extracts a logger from context using klog.FromContext(ctx)
  • Uses structured logging with logger.Error(err, msg)
  • Preserves Sentry error capture for observability
  • Maintains the fatal exit behavior for critical errors
cmd/maestro/server/grpc_broker.go (3)

128-130: LGTM!

The constructor correctly accepts context and derives a per-context logger for structured logging during initialization.


154-188: LGTM!

TLS configuration and error handling correctly use context-aware check(ctx, ...) calls, and startup logging uses the context-derived logger with structured key-value pairs.


271-296: LGTM!

The PredicateEvent method correctly uses context-derived logging with V(4) verbosity level for debug messages, which is appropriate for high-frequency event processing.

pkg/event/event.go (3)

41-57: LGTM!

The Register method correctly:

  • Accepts context as the first parameter
  • Derives a per-context logger using klog.FromContext(ctx)
  • Uses structured logging with key-value pairs ("id", "source")

60-74: LGTM!

Good use of logger.WithValues("id", id) to enrich all log messages in this method with the client ID context.


82-106: LGTM!

The Start method correctly implements the event loop with:

  • Context-derived logger
  • Proper context cancellation handling
  • RLock for concurrent-safe client iteration
  • Structured error logging with resource ID
cmd/maestro/server/event_server.go (3)

78-79: LGTM!

The context-derived logger pattern is correctly implemented with proper startup and shutdown logging.


95-97: LGTM!

Good use of structured logging with WithValues for resourceID and action, and properly propagating the enriched logger back into the context.


266-267: LGTM!

Proper structured logging with relevant context fields (resourceID, instanceID, eventID) for broadcast status events.

cmd/maestro/server/controllers.go (2)

13-26: LGTM!

The constructor correctly accepts context for logger extraction, and the conditional V(4) debug logging for message broker setup is appropriate for this initialization path.


58-72: LGTM!

Good pattern: creating a named logger in Start() and propagating it to the context. The Run(ctx) call correctly aligns with the updated KindControllerManager.Run signature that now accepts context instead of ctx.Done().

cmd/maestro/server/api_server.go (3)

40-43: LGTM!

The constructor correctly accepts context and propagates it to route construction. This enables context-aware error handling throughout the initialization chain.


148-170: LGTM!

The Serve method correctly extracts the logger from context and uses structured logging with key-value pairs for the port. The TLS/non-TLS paths are clearly logged.


180-193: LGTM!

The Start method properly uses context-derived logging. Using logger.Error followed by os.Exit(1) is appropriate for fatal startup errors, maintaining the expected behavior while using structured logging.

cmd/maestro/servecmd/cmd.go (2)

52-55: LGTM!

Good pattern for initializing the context-bound logger with a named component ("maestro-server") and propagating it through the context for downstream use.


85-88: LGTM!

Context is correctly propagated to the updated constructors that now require context.Context as the first parameter.

pkg/controllers/framework.go (4)

88-104: LGTM!

The Run method correctly uses context-derived logging and properly uses wait.JitterUntilWithContext and wait.UntilWithContext for context-aware scheduling. Shutdown logging is appropriately placed after <-ctx.Done().


118-134: LGTM!

Good pattern: enriching the logger with EventID via WithValues and storing the event ID in context via both klog.NewContext (for logging) and context.WithValue (for downstream access). The deferred action pattern ensures cleanup regardless of early returns.


204-230: LGTM!

The processNextEvent method correctly extracts a logger from context, adds the key field for traceability, and properly handles error logging with structured output.


232-257: LGTM!

The syncEvents method properly uses context-derived logging and correctly passes context to downstream service calls (DeleteAllReconciledEvents, FindAllUnreconciledEvents).

cmd/maestro/server/grpc_server.go (8)

48-53: LGTM! Context parameter and logger derivation are correct.

The addition of context.Context as the first parameter to NewGRPCServer aligns with the PR's objective to propagate context throughout the codebase. Logger derivation using klog.FromContext(ctx) follows the standard klog pattern for contextual logging.


77-117: LGTM! Consistent context propagation to check() calls.

All check() calls in the TLS and mTLS setup paths now properly receive the context parameter, ensuring consistent error handling and logging throughout the initialization flow.


123-134: LGTM! Structured logging statements are properly formatted.

The logging statements correctly use klog's structured logging format with key-value pairs, providing clear information about the TLS configuration at startup.


149-158: LGTM! Start method correctly updated for context propagation.

The Start method signature now accepts a context parameter, derives a logger from it, and uses structured logging. This aligns with the PR's objective to propagate context throughout the server lifecycle.


167-195: LGTM! Proper contextual logging in Publish method.

The method correctly derives a logger from the request context and uses appropriate verbosity levels for logging (V(4) for detailed event data). This provides good observability while keeping verbose details at higher log levels.


243-361: LGTM! Subscribe method correctly implements context propagation and logging.

The method properly:

  • Derives a logger from the context
  • Propagates context to eventBroadcaster.Register() and Unregister() calls
  • Uses structured logging for error conditions and informational messages
  • Handles the heartbeat channel overflow case with appropriate logging

445-488: LGTM! Resync request handler correctly uses contextual logging.

The method properly derives a logger from the context and uses it for informational logging with structured key-value pairs. The logging provides useful context for debugging resync behavior.


98-98: Verify that newAuthStreamInterceptor properly utilizes the context.

The interceptor now receives a context parameter. Ensure that the implementation of newAuthStreamInterceptor actually uses this context for logging, cancellation, or other context-aware operations rather than accepting it unused.

test/helper.go (9)

158-158: LGTM! Context propagation to NewGRPCBroker is correct.

The call to server.NewGRPCBroker now properly passes the context as the first parameter, consistent with the API changes in the gRPC server components.


178-179: LGTM! Helper methods correctly use internal context.

These methods access helper.Ctx internally to derive loggers and pass context to server start methods, maintaining consistent context propagation throughout the test infrastructure.


200-208: LGTM! API server startup correctly implements contextual logging.

The method properly derives a logger from helper.Ctx and propagates the context to both the NewAPIServer constructor and the Start method, with appropriate structured logging for test observability.


218-226: LGTM! Metrics server startup correctly uses contextual logging.

The method follows the same pattern as the API server, properly deriving a logger from context and using it for structured logging around the server lifecycle.


235-242: LGTM! Health check server startup follows consistent pattern.

The method correctly derives a logger from context and propagates the context to the health check server's Start method with appropriate logging.


249-256: LGTM! Event server startup correctly implements contextual logging.

The method follows the established pattern, properly deriving a logger and propagating context to the event server's Start method.


258-265: LGTM! Event broadcaster startup follows consistent pattern.

The method correctly derives a logger from context and propagates the context to the event broadcaster's Start method with appropriate structured logging.


362-374: LGTM! Server restart methods correctly use contextual logging.

Both RestartServer and RestartMetricsServer properly derive loggers from helper.Ctx and use structured logging to track server restarts in tests.


516-538: LGTM! Database cleanup method uses proper contextual logging.

The method correctly derives a logger from context and uses structured error logging with appropriate context (table name) for debugging database cleanup failures.

pkg/controllers/status_controller.go (2)

3-14: Logging import fits the new contextual-logging pattern

Using the dedicated logging package here is consistent with the PR-wide move to contextual logging; nothing else needed in this import block.

Please double-check that the version of the logging package in go.mod matches the rest of your Kubernetes client libraries to avoid subtle incompatibilities.


51-66: Controller lifecycle correctly tied to context.Context

Run(ctx) now cleanly binds the controller lifetime to ctx.Done(), starts the sync and worker loops with *WithContext, and shuts down the workqueue via defer sc.eventsQueue.ShutDown(), which should allow workers to exit once the queue is draining.

It’s worth confirming at call sites that you always pass a non-nil, cancellation-capable ctx (e.g., server or process root context) into Run so shutdown behaves as expected.

test/mocks/workserver/main.go (2)

155-159: klog migration for initialization/startup logs looks good

The initialization and startup logs have been cleanly switched to klog.Infof, and the messages still provide the same useful visibility into configuration (API server, gRPC server, consumer, bind address). No functional issues here.

Also applies to: 172-172


269-269: klog usage in error and shutdown paths is consistent

The failure and shutdown paths now using klog.Fatalf / klog.Errorf / klog.Infof are consistent with the rest of the migration and keep behavior equivalent to previous fatal/error logging for this mock binary. Nothing to fix from a correctness standpoint.

Also applies to: 279-280, 286-287

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (5)
pkg/dispatcher/hash_dispatcher.go (3)

86-86: Typo fixed from previous review.

The typo "resourcs" → "resources" has been corrected.


232-232: Typo fixed from previous review.

The typo "resourcs" → "resources" has been corrected.


235-237: Missing Forget call addressed from previous review.

The Forget call on successful resync has been added, resolving the rate limiter backoff issue.

cmd/maestro/servecmd/cmd.go (1)

113-115: Bug: Wrong error variable logged for tracing shutdown failure.

This issue was flagged in a previous review but remains unfixed. The code checks tracingShutdown(ctx) != nil but logs the err variable from line 93 (the OpenTelemetry installation error), not the actual shutdown error.

-		if tracingShutdown != nil && tracingShutdown(ctx) != nil {
-			logger.Error(err, "OpenTelemetry trace provider failed to shutdown")
+		if tracingShutdown != nil {
+			if shutdownErr := tracingShutdown(ctx); shutdownErr != nil {
+				logger.Error(shutdownErr, "OpenTelemetry trace provider failed to shutdown")
+			}
 		}
cmd/maestro/server/grpc_broker.go (1)

217-221: Inconsistent error handling bypasses centralized reporting.

Line 220 uses os.Exit(1) directly, which bypasses the check() function's centralized error handling and Sentry reporting (see cmd/maestro/server/server.go). This is inconsistent with line 225, which uses check() for the serve error.

Replace the direct exit with check() for consistency:

 	ln, err := net.Listen("tcp", bkr.bindAddress)
 	if err != nil {
-		logger.Error(err, "Failed to listen on", "bindAddress", bkr.bindAddress)
-		os.Exit(1)
+		check(ctx, err, "Failed to start gRPC broker listener")
 	}
🧹 Nitpick comments (13)
pkg/db/db_session/default.go (1)

141-168: Context‑scoped logging in waitForNotification looks good; consider including channel on ping failures

Using logger := klog.FromContext(ctx) and structured fields for context cancellation, notifications, and connection loss is clear and consistent. One small improvement: the ping failure log at Line 161 currently only logs the error; adding "channel", channel there would make it easier to correlate reconnect storms across multiple channels.

pkg/db/db_session/test.go (1)

58-59: Migration from legacy logger to klog is correct.

The changes properly replace log.Errorf with klog.Errorf. Since the Init function doesn't have a context parameter, using the global klog logger is appropriate for this test setup code.

Consider using klog's structured logging format:

klog v2 recommends structured logging with key-value pairs rather than format strings. This provides better structured output and aligns with Kubernetes logging conventions.

Apply this diff to use structured logging:

 		if err := initDatabase(config, db.Migrate); err != nil {
-			klog.Errorf("error initializing test database: %s", err)
+			klog.Error(err, "error initializing test database")
 			return
 		}
 
 		if err := resetDB(config); err != nil {
-			klog.Errorf("error resetting test database: %s", err)
+			klog.Error(err, "error resetting test database")
 			return
 		}

Also applies to: 63-64

pkg/auth/helpers.go (1)

13-25: Consider structured logging for 4xx errors.

Line 19 uses logger.Info(err.Error()) which loses the structured error information. Consider using structured fields for consistency with klog best practices.

Apply this diff to improve structured logging:

-		logger.Info(err.Error())
+		logger.Info("client error", "error", err.Error(), "code", err.HttpCode)
pkg/controllers/framework.go (1)

118-121: Consider simplifying the context construction.

The EventID is added both to the logger (line 119) and as a context value (line 120). While this works, storing the same value in two places could lead to drift if one is updated and the other isn't.

If the EventID context value is needed downstream (e.g., for non-logging purposes), this is fine. Otherwise, consider relying solely on the logger's WithValues.

pkg/controllers/framework_test.go (2)

87-89: Consider checking handleEvent return values.

The handleEvent method now returns (bool, error), but the return values are ignored here. While the tests validate side effects (counters and ReconciledDate), capturing and asserting on the return values would make test failures more explicit.

-	mgr.handleEvent(ctx, "1")
-	mgr.handleEvent(ctx, "2")
-	mgr.handleEvent(ctx, "3")
+	reconciled, err := mgr.handleEvent(ctx, "1")
+	Expect(err).To(BeNil())
+	Expect(reconciled).To(BeTrue())
+
+	reconciled, err = mgr.handleEvent(ctx, "2")
+	Expect(err).To(BeNil())
+	Expect(reconciled).To(BeTrue())
+
+	reconciled, err = mgr.handleEvent(ctx, "3")
+	Expect(err).To(BeNil())
+	Expect(reconciled).To(BeTrue())

198-200: Same suggestion: Consider checking return values for clarity.

Similar to the earlier test, the return values from handleEvent are ignored. Given that event "2" and "3" are expected to not be processed (counters remain 0), checking the reconciled return value would make the test intent clearer.

pkg/db/context.go (1)

29-29: Consider providing a meaningful message in the Error call.

The logger.Error signature is Error(err error, msg string, keysAndValues ...interface{}). Using an empty string for the message while putting the descriptive text in the error is unconventional. Consider restructuring for clarity:

-	logger.Error(errors.New("Could not retrieve transaction from context"), "")
+	logger.Error(nil, "Could not retrieve transaction from context")

Or if an error value is needed for structured processing:

-	logger.Error(errors.New("Could not retrieve transaction from context"), "")
+	logger.Error(errors.New("missing transaction"), "Could not retrieve transaction from context")

The same pattern applies to line 53.

pkg/api/metadata.go (1)

94-97: Inconsistency: Missing sentry.CaptureException and message casing differs.

Two minor inconsistencies compared to SendAPI:

  1. Message casing differs: "Can't send..." vs "cannot send..." on line 58
  2. sentry.CaptureException(err) is called in SendAPI (line 59) but not here

Consider aligning both for consistency:

 	if err != nil {
-		logger.Error(err, "Can't send response body for request", "path", r.URL.Path)
+		logger.Error(err, "cannot send response body for request", "path", r.URL.Path)
+		sentry.CaptureException(err)
 		return
 	}
pkg/client/cloudevents/source_client.go (1)

38-45: Consider accepting context in NewSourceClient constructor for proper context propagation.

The constructor uses context.Background() which bypasses caller-controlled cancellation, timeouts, and tracing context. This prevents downstream operations in cegeneric.NewCloudEventSourceClient from respecting caller-imposed deadlines or cancellation signals.

Update the signature to accept context from the caller:

-func NewSourceClient(sourceOptions *ceoptions.CloudEventsSourceOptions, resourceService services.ResourceService) (SourceClient, error) {
-	ctx := context.Background()
+func NewSourceClient(ctx context.Context, sourceOptions *ceoptions.CloudEventsSourceOptions, resourceService services.ResourceService) (SourceClient, error) {
cmd/maestro/server/routes.go (1)

38-40: Redundant nil check: authMiddleware is always initialized.

Line 32 unconditionally assigns &auth.AuthMiddlewareMock{} to authMiddleware, making the nil check on line 38 unreachable.

Consider removing this dead code:

 	if authMiddleware == nil {
-		check(ctx, errors.New("authMiddleware is not set"), "Unable to create auth middleware: missing middleware")
 	}
cmd/maestro/server/metrics_server.go (1)

62-62: Minor: Inconsistent log message phrasing.

The "at" preposition is unnecessary with structured key-value logging and is inconsistent with the TLS message on line 59.

-		logger.Info("Serving Metrics without TLS at", "port", env().Config.Metrics.BindPort)
+		logger.Info("Serving Metrics without TLS", "port", env().Config.Metrics.BindPort)
cmd/maestro/server/api_server.go (2)

148-171: Consider wiring ctx into HTTP server shutdown, not just logging

Serve(ctx, listener) currently uses ctx only to derive a logger and to pass into check, but the HTTP server lifecycle itself isn’t driven by ctx. If the caller expects canceling ctx to eventually stop the HTTP server, you may want to add a goroutine that waits on ctx.Done() and calls s.httpServer.Shutdown(ctx) (or use http.Server.BaseContext) so cancellation semantics match the method signature.


188-199: Reconsider ordering of gRPC shutdown vs DB pool close

After s.Serve(ctx, listener) returns, you close env().Database.SessionFactory and only then (via defer set earlier) stop the gRPC server. That means gRPC requests could still be in flight while the DB pool is being closed. Consider explicitly stopping the gRPC server before closing the DB (and dropping the defer) so all request-serving components are quiesced before tearing down shared dependencies.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 37bb676 and 4a3cf9b.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (49)
  • cmd/maestro/agent/cmd.go (1 hunks)
  • cmd/maestro/common/otlp_sdk.go (4 hunks)
  • cmd/maestro/environments/framework.go (6 hunks)
  • cmd/maestro/main.go (1 hunks)
  • cmd/maestro/migrate/cmd.go (2 hunks)
  • cmd/maestro/servecmd/cmd.go (4 hunks)
  • cmd/maestro/server/api_server.go (6 hunks)
  • cmd/maestro/server/auth_interceptor.go (4 hunks)
  • cmd/maestro/server/controllers.go (3 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • cmd/maestro/server/healthcheck_server.go (6 hunks)
  • cmd/maestro/server/logging/formatter_json.go (3 hunks)
  • cmd/maestro/server/logging/logging.go (0 hunks)
  • cmd/maestro/server/logging/writer.go (3 hunks)
  • cmd/maestro/server/metrics_server.go (2 hunks)
  • cmd/maestro/server/routes.go (3 hunks)
  • cmd/maestro/server/server.go (3 hunks)
  • go.mod (3 hunks)
  • pkg/api/error.go (5 hunks)
  • pkg/api/metadata.go (4 hunks)
  • pkg/auth/helpers.go (1 hunks)
  • pkg/client/cloudevents/source_client.go (4 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
  • pkg/controllers/event_filter.go (3 hunks)
  • pkg/controllers/framework.go (9 hunks)
  • pkg/controllers/framework_test.go (2 hunks)
  • pkg/controllers/status_controller.go (7 hunks)
  • pkg/db/advisory_locks.go (8 hunks)
  • pkg/db/context.go (2 hunks)
  • pkg/db/db_session/default.go (4 hunks)
  • pkg/db/db_session/test.go (2 hunks)
  • pkg/db/migrations.go (2 hunks)
  • pkg/db/transaction_middleware.go (2 hunks)
  • pkg/dispatcher/hash_dispatcher.go (8 hunks)
  • pkg/dispatcher/noop_dispatcher.go (5 hunks)
  • pkg/errors/errors.go (0 hunks)
  • pkg/event/event.go (5 hunks)
  • pkg/handlers/framework.go (2 hunks)
  • pkg/logger/logger.go (0 hunks)
  • pkg/logger/zap.go (0 hunks)
  • pkg/services/generic.go (3 hunks)
  • pkg/services/resource.go (5 hunks)
  • test/e2e/pkg/suite_test.go (3 hunks)
  • test/helper.go (10 hunks)
  • test/integration/integration_test.go (1 hunks)
  • test/mocks/workserver/main.go (5 hunks)
  • test/upgrade/pkg/suite_test.go (2 hunks)
💤 Files with no reviewable changes (4)
  • cmd/maestro/server/logging/logging.go
  • pkg/errors/errors.go
  • pkg/logger/logger.go
  • pkg/logger/zap.go
🚧 Files skipped from review as they are similar to previous changes (13)
  • pkg/services/generic.go
  • test/upgrade/pkg/suite_test.go
  • pkg/api/error.go
  • cmd/maestro/agent/cmd.go
  • test/e2e/pkg/suite_test.go
  • cmd/maestro/main.go
  • test/mocks/workserver/main.go
  • pkg/services/resource.go
  • cmd/maestro/environments/framework.go
  • pkg/dispatcher/noop_dispatcher.go
  • cmd/maestro/server/logging/formatter_json.go
  • pkg/handlers/framework.go
  • cmd/maestro/server/logging/writer.go
🧰 Additional context used
🧬 Code graph analysis (14)
cmd/maestro/server/routes.go (2)
cmd/maestro/environments/types.go (1)
  • Services (42-48)
pkg/auth/authz_middleware_mock.go (1)
  • NewAuthzMiddlewareMock (11-13)
cmd/maestro/migrate/cmd.go (3)
pkg/db/db_session/default.go (1)
  • NewProdFactory (38-42)
pkg/db/migrations.go (1)
  • Migrate (15-26)
pkg/errors/errors.go (1)
  • New (102-116)
pkg/controllers/event_filter.go (1)
pkg/controllers/framework.go (1)
  • EventID (38-38)
pkg/controllers/status_controller.go (2)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
pkg/auth/helpers.go (2)
pkg/errors/errors.go (2)
  • ServiceErrorCode (61-61)
  • New (102-116)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
cmd/maestro/server/grpc_broker.go (2)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/controllers/framework.go (3)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/event.go (1)
  • EventType (9-9)
pkg/api/openapi/model_error.go (1)
  • Error (21-28)
cmd/maestro/server/healthcheck_server.go (2)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/db/advisory_locks.go (1)
  • Instances (25-25)
cmd/maestro/server/grpc_server.go (3)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
pkg/config/grpc_server.go (1)
  • GRPCServerConfig (10-35)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
cmd/maestro/server/api_server.go (2)
cmd/maestro/server/server.go (1)
  • Server (16-21)
cmd/maestro/server/grpc_server.go (2)
  • NewGRPCServer (48-146)
  • GRPCServer (36-45)
cmd/maestro/server/event_server.go (2)
pkg/api/resource_types.go (1)
  • Resource (14-27)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
pkg/db/context.go (1)
pkg/errors/errors.go (1)
  • New (102-116)
cmd/maestro/server/auth_interceptor.go (1)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
cmd/maestro/server/controllers.go (7)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/controllers/event_filter.go (1)
  • EventFilter (18-25)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/controllers/framework.go (1)
  • KindControllerManager (52-57)
cmd/maestro/environments/types.go (1)
  • Database (31-33)
pkg/db/session.go (1)
  • SessionFactory (13-21)
pkg/controllers/status_controller.go (1)
  • StatusController (20-26)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Red Hat Konflux / maestro-e2e-on-pull-request
  • GitHub Check: Red Hat Konflux / maestro-on-pull-request
  • GitHub Check: e2e-grpc-broker
  • GitHub Check: migration
  • GitHub Check: e2e-broadcast-subscription
  • GitHub Check: e2e-with-istio
  • GitHub Check: e2e
🔇 Additional comments (47)
pkg/db/db_session/default.go (2)

170-197: Listener callback logging with contextual logger is appropriate

Deriving the logger from the incoming ctx and using it inside the plog callback keeps DB listener state logs tied to the request/operation context and uses structured fields (eventType, error) correctly. No issues from a correctness or behavior standpoint.


199-205: NewListener context propagation and startup log are consistent with the new logging model

Creating the listener with the passed ctx, then logging a structured “Starting listener” message before spawning waitForNotification maintains existing behavior while aligning with per‑context logging. This is a clean migration; no further changes needed here.

pkg/db/db_session/test.go (1)

7-7: LGTM!

The klog import is correctly added to support the logging migration.

pkg/controllers/event_filter.go (3)

6-6: LGTM! Appropriate logging framework for Kubernetes projects.

The addition of klog/v2 aligns with Kubernetes ecosystem best practices for contextual logging.


46-46: LGTM! Proper context-aware structured logging.

The logger correctly derives from context and enriches it with the event ID for traceability. The EventID key matches the constant defined in framework.go:37.


59-59: LGTM! Clean migration to context-aware logging.

The log call correctly uses the context-aware logger with appropriate info level for this concurrent processing notification.

cmd/maestro/migrate/cmd.go (2)

7-7: LGTM: klog import added.

The addition of klog/v2 aligns with the repository-wide migration to klog-based logging.


28-37: Verify alignment with contextual logging objectives.

The PR title emphasizes "contextual logging," but this implementation uses package-level klog.Fatal() calls and context.Background() rather than context-aware logging.

Consider:

  • Using klog.FromContext(ctx) to obtain a logger from context (though Fatal calls may be an exception)
  • Passing cmd.Context() instead of context.Background() to propagate the cobra command's context
pkg/controllers/status_controller.go (5)

6-6: LGTM: Import aligns with contextual logging migration.

The addition of k8s.io/klog/v2 is consistent with the PR's objective to replace custom Zap-based logging with klog.


51-66: LGTM: Clean context-aware lifecycle implementation.

The Run method correctly:

  • Derives the logger from context for structured logging
  • Propagates context to both workers (syncStatusEvents and runWorker)
  • Respects context cancellation
  • Ensures proper resource cleanup with deferred queue shutdown

68-99: LGTM: Context propagation and error handling are correct.

The worker methods properly:

  • Accept and propagate context through the processing pipeline
  • Derive loggers from context for consistent structured logging
  • Handle errors with appropriate requeue logic and structured error messages

104-145: LGTM: Proper context enhancement for observability.

The enhanced context creation on lines 105-106 follows a sound pattern:

  • The logger is enhanced with StatusEventID for automatic inclusion in log messages
  • The context value stores StatusEventID for programmatic access by downstream handlers
  • The enhanced logger is embedded via klog.NewContext for contextual logging

This dual approach ensures both logging consistency and handler flexibility.


161-190: LGTM: Context-aware database operations with proper error handling.

The method correctly:

  • Derives the logger from context for consistent logging
  • Propagates context to all database operations (FindReadyIDs, GetEventsAssociatedWithInstances, DeleteAllEvents)
  • Uses structured error logging with relevant context
  • Tracks operations with prometheus metrics
test/integration/integration_test.go (1)

5-5: LGTM!

The migration from custom logger to klog is correct for this test setup code. Using global klog.Infof is appropriate in TestMain where no request context is available.

Also applies to: 15-15

pkg/db/advisory_locks.go (1)

8-8: LGTM!

The migration to klog is well-executed:

  • Context-derived loggers used consistently
  • Structured logging with appropriate fields (e.g., WithValues("owner", uuid))
  • Proper verbosity levels (V(4) for debug messages)

Also applies to: 92-92, 115-115, 157-157

pkg/db/transaction_middleware.go (1)

18-50: LGTM!

The context-derived logger usage is correct:

  • Logger obtained from context after NewContext
  • Error logging uses structured format
  • Operation ID retrieval updated to use loggertracing package
pkg/event/event.go (2)

42-42: LGTM!

Context-derived logger usage is correct throughout:

  • Structured logging with appropriate fields
  • WithValues used for adding contextual information
  • Error logging includes resource IDs for debugging

Also applies to: 61-61, 83-83


41-41: Verify all callers updated for signature changes.

The Register and Unregister methods now accept context.Context as the first parameter. These are breaking API changes that require all callers to be updated to pass a context. Search the codebase for calls to .Register( and .Unregister( to confirm all have been updated with the required context parameter.

pkg/dispatcher/hash_dispatcher.go (1)

77-77: LGTM!

Context-derived logger usage is correct throughout the dispatcher:

  • Loggers obtained from context in all major functions
  • Structured logging with appropriate fields
  • Logger passed to private updateConsumerSet function to avoid redundant context lookups

Also applies to: 152-152, 208-208

go.mod (1)

93-93: LGTM!

Dependency reorganization aligns with the klog migration:

  • go.uber.org/zap moved to indirect (no longer directly used)
  • github.com/fsnotify/fsnotify moved to indirect (likely transitive)
  • Consistent with removing custom logger in favor of klog

Also applies to: 173-173, 186-186

cmd/maestro/common/otlp_sdk.go (1)

26-26: Verify all callers updated for signature change.

The function signature changed from accepting *zap.SugaredLogger to klog.Logger. Ensure all callers of InstallOpenTelemetryTracer have been updated to pass a klog.Logger instance.

cmd/maestro/server/controllers.go (2)

13-15: LGTM! Context-aware constructor with logger extraction.

The constructor now properly accepts a context and extracts a logger from it, aligning with the klog contextual logging pattern used throughout this PR.


58-72: LGTM! Context-scoped logger with component name.

The Start method correctly:

  1. Extracts the logger from context and adds a component name (maestro-controllers)
  2. Re-injects the enriched logger into the context for downstream use
  3. Uses the logger consistently for all log statements

This ensures proper log attribution and context propagation to child goroutines via the ctx parameter passed to Run, NewListener, etc.

pkg/controllers/framework.go (3)

88-104: LGTM! Context-aware Run method with proper lifecycle.

The method correctly:

  1. Extracts logger from context
  2. Uses wait.JitterUntilWithContext and wait.UntilWithContext for context-aware scheduling
  3. Blocks on ctx.Done() for graceful shutdown

196-230: LGTM! Context propagation through worker and event processing.

The runWorker and processNextEvent methods correctly accept and propagate context. The logger is extracted per-event with the key value for traceability, and errors are logged with proper context.


232-258: LGTM! Context-aware event synchronization.

The syncEvents method properly extracts the logger from context and passes ctx to downstream service calls (DeleteAllReconciledEvents, FindAllUnreconciledEvents), enabling cancellation and trace propagation.

cmd/maestro/servecmd/cmd.go (4)

52-56: LGTM! Context initialization with named logger.

Proper setup of a context-scoped logger with component name (maestro-server) that is then propagated to all server components.


77-78: Previous feedback addressed.

The logger.Error call now correctly uses a descriptive message string as the second argument, followed by the key-value pairs.


84-88: LGTM! Context propagation to server constructors.

The API server, controllers server, and GRPC broker constructors now receive the context, enabling proper context-scoped logging throughout the application lifecycle.


122-129: LGTM! Context-aware server startup.

All server Start methods now receive the context, enabling proper cancellation propagation and context-scoped logging.

pkg/db/migrations.go (1)

5-5: LGTM! Migration to klog for fatal logging.

The change from the custom logger to klog.Fatalf is consistent with the broader logging migration. Since MigrateTo is primarily for testing purposes and doesn't have a context available, using the package-level klog.Fatalf is appropriate.

Also applies to: 36-36

pkg/client/grpcauthorizer/kube_authorizer.go (1)

46-54: LGTM!

The contextual logging implementation is correct. The previous duplicate "resource" key issue has been properly addressed with distinct keys (resourceType and resource). The V(4) verbosity level is appropriate for debug-level access review logging.

pkg/db/context.go (1)

57-57: Good use of structured logging for rollback context.

Logging the triggering error as a key-value pair provides useful debugging context.

pkg/api/metadata.go (1)

58-59: LGTM on logging migration.

Correctly derives logger from request context and uses structured logging with the path key.

cmd/maestro/server/server.go (2)

31-38: LGTM on the check helper function.

Correctly derives logger from context and maintains existing error handling behavior (sentry capture, flush, and exit).


16-21: Verify all Server interface implementations have been updated to accept context.Context parameters.

The Server interface now requires context.Context in Start(ctx context.Context) and Serve(ctx context.Context, listener net.Listener) methods. This is a breaking change—confirm that all implementations of the Server interface throughout the codebase have been updated with the new signatures.

pkg/client/cloudevents/source_client.go (1)

57-88: LGTM on contextual logging pattern.

The pattern of deriving a logger with WithValues, then re-attaching it to context with klog.NewContext ensures downstream calls receive the enriched logger. This is correctly applied across OnCreate, OnUpdate, OnDelete, and Resync.

cmd/maestro/server/auth_interceptor.go (1)

150-151: LGTM: Context-aware logging properly integrated.

The updated signature and context-derived logger usage align with the broader migration to per-context klog-based logging across the codebase.

cmd/maestro/server/event_server.go (1)

77-89: LGTM: Contextual logging properly implemented.

The migration to context-derived loggers with structured key-value pairs is consistent with the broader PR objective. The startup and shutdown logging flows are correctly updated.

cmd/maestro/server/healthcheck_server.go (1)

50-85: LGTM: Health check server properly migrated to contextual logging.

The context propagation and structured logging implementation is correct. All previously flagged formatting issues have been resolved.

cmd/maestro/server/grpc_server.go (2)

48-53: LGTM: Constructor signature correctly updated for context propagation.

The addition of the ctx parameter and context-derived logger initialization aligns with the broader migration to contextual logging across all server components.


149-158: LGTM: Start method properly updated with context parameter.

The context-aware startup flow and error handling are correctly implemented.

test/helper.go (2)

377-378: LGTM: Typo corrected and contextual logging applied.

The spelling correction and context-derived logger usage are correct.


198-209: LGTM: Test helper correctly updated for context-aware API server.

The updated NewAPIServer call and Start method invocation with context parameters align with the new server API signatures.

cmd/maestro/server/api_server.go (3)

6-9: klog and os imports are appropriate and used correctly

The new imports for contextual logging and process exit are used in this file (klog.FromContext and os.Exit) and there are no obvious issues or redundancies here.


40-44: Context propagation into router, auth handler, and gRPC server looks consistent

Passing ctx into s.routes(ctx) and NewGRPCServer(ctx, ...), and updating the check calls to check(ctx, err, ...), aligns with the new Server interface (Start(ctx), Serve(ctx, ...)) and the overall move to context-aware logging. This wiring looks coherent; I don’t see functional regressions introduced here.

Also applies to: 62-83, 140-142


180-187: gRPC server start is now context-aware; that change looks good

Propagating ctx into s.grpcServer.Start(ctx) and deriving a per-context logger in Start(ctx) is consistent with the rest of the PR. This should give you contextual logs for gRPC as well as HTTP without changing existing startup ordering.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
pkg/db/advisory_locks.go (1)

178-185: Unlock metrics report both ERROR and OK on failure

In Unlock, if lock.unlock() returns an error you increment "ERROR" and then unconditionally increment "OK" as well:

if err := lock.unlock(); err != nil {
    UpdateAdvisoryUnlockCountMetric(lockType, "ERROR")
    logger.Error(err, "error unlocking advisory lock", "lockID", lockID, "lockType", lockType)
}
UpdateAdvisoryUnlockCountMetric(lockType, "OK")
UpdateAdvisoryLockDurationMetric(lockType, "OK", lock.startTime)

This makes the metrics misleading for error cases. Consider only recording "OK" and duration on success:

-	if err := lock.unlock(); err != nil {
-		UpdateAdvisoryUnlockCountMetric(lockType, "ERROR")
-		logger.Error(err, "error unlocking advisory lock", "lockID", lockID, "lockType", lockType)
-	}
-
-	UpdateAdvisoryUnlockCountMetric(lockType, "OK")
-	UpdateAdvisoryLockDurationMetric(lockType, "OK", lock.startTime)
+	if err := lock.unlock(); err != nil {
+		UpdateAdvisoryUnlockCountMetric(lockType, "ERROR")
+		logger.Error(err, "error unlocking advisory lock", "lockID", lockID, "lockType", lockType)
+	} else {
+		UpdateAdvisoryUnlockCountMetric(lockType, "OK")
+		UpdateAdvisoryLockDurationMetric(lockType, "OK", lock.startTime)
+	}

That keeps the unlock metrics consistent with the actual outcome.

pkg/db/db_session/test.go (1)

77-79: Fix initDatabase loop: it can sleep forever without re‑trying the query

In initDatabase, this loop only calls Exec once in the init statement. If that first call returns a non‑nil error, err never changes and the loop sleeps forever without re‑trying the query.

To actually poll until the DB is ready, re‑issue Exec on each iteration:

-	for _, err := dbx.Exec(`select 1`); err != nil; {
-		time.Sleep(100 * time.Millisecond)
-	}
+	for {
+		if _, err := dbx.Exec(`select 1`); err == nil {
+			break
+		}
+		time.Sleep(100 * time.Millisecond)
+	}
cmd/maestro/server/grpc_server.go (1)

315-315: Pass the stream context to WritePBMessage instead of context.TODO().

WritePBMessage uses the context parameter to control encoding behavior and handle cancellation. Passing context.TODO() prevents the function from accessing request-scoped options and respecting the stream's lifecycle. Use the available stream context (ctx) to ensure proper context propagation:

-if err = grpcprotocol.WritePBMessage(context.TODO(), binding.ToMessage(evt), pbEvt); err != nil {
+if err = grpcprotocol.WritePBMessage(ctx, binding.ToMessage(evt), pbEvt); err != nil {
🧹 Nitpick comments (22)
pkg/db/migrations.go (1)

5-5: klog swap looks correct; consider avoiding Fatalf in helper (optional).

The switch from the internal logger to klog.Fatalf("Could not migrate: %v", err) preserves the existing fatal-on-error behavior and is consistent with the PR’s move to klog; no functional issues from this change.

Longer term, you may want to refactor MigrateTo to return an error instead of terminating the process from a library-style helper, but that’s orthogonal to this PR and can be deferred.

Also applies to: 36-36

pkg/db/advisory_locks.go (1)

91-136: Prefer structured klog fields over formatted errMsg in lock acquisition logs

The new klog usage is fine, but you’re still building errMsg with fmt.Sprintf and passing it as the log message, then re-wrapping it into the returned error. You can simplify and make logs more query‑friendly by using structured fields and wrapping the original error directly, e.g.:

 func (f *AdvisoryLockFactory) NewAdvisoryLock(ctx context.Context, id string, lockType LockType) (string, error) {
-	logger := klog.FromContext(ctx)
+	logger := klog.FromContext(ctx)

 	lock, err := f.newLock(ctx, id, lockType)
@@
 	// obtain the advisory lock (blocking)
 	if err := lock.lock(); err != nil {
 		UpdateAdvisoryLockCountMetric(lockType, "ERROR")
-		errMsg := fmt.Sprintf("error obtaining the advisory lock for id %s type %s, %v", id, lockType, err)
-		logger.Error(err, errMsg)
-		// the lock transaction is already started, if error happens, we return the transaction id, so that the caller
-		// can end this transaction.
-		return *lock.uuid, fmt.Errorf("%s", errMsg)
+		logger.Error(err, "error obtaining the advisory lock", "id", id, "lockType", lockType)
+		// the lock transaction is already started, if error happens, we return the transaction id, so that the caller
+		// can end this transaction.
+		return *lock.uuid, fmt.Errorf("error obtaining the advisory lock for id %s type %s: %w", id, lockType, err)
 	}
@@
 func (f *AdvisoryLockFactory) NewNonBlockingLock(ctx context.Context, id string, lockType LockType) (string, bool, error) {
-	logger := klog.FromContext(ctx)
+	logger := klog.FromContext(ctx)
@@
 	// obtain the advisory lock (unblocking)
 	acquired, err := lock.nonBlockingLock()
 	if err != nil {
 		UpdateAdvisoryLockCountMetric(lockType, "ERROR")
-		errMsg := fmt.Sprintf("error obtaining the non blocking advisory lock for id %s type %s, %v", id, lockType, err)
-		logger.Error(err, errMsg)
-		// the lock transaction is already started, if error happens, we return the transaction id, so that the caller
-		// can end this transaction.
-		return *lock.uuid, false, fmt.Errorf("%s", errMsg)
+		logger.Error(err, "error obtaining the non blocking advisory lock", "id", id, "lockType", lockType)
+		// the lock transaction is already started, if error happens, we return the transaction id, so that the caller
+		// can end this transaction.
+		return *lock.uuid, false, fmt.Errorf("error obtaining the non blocking advisory lock for id %s type %s: %w", id, lockType, err)
 	}

This avoids redundant string construction and gives you better‑structured klog output keyed by id and lockType, while still returning a wrapped error with context.

pkg/auth/helpers.go (1)

14-22: Provide a non-empty message when logging server errors

logger.Error(err, "") in the non-4xx path logs with an empty message, which makes the entry harder to interpret in aggregated logs.

Consider including a short description and the HTTP code, for example:

-		logger.Error(err, "")
+		logger.Error(err, "server error", "code", err.HttpCode)

This keeps the structured context while making the log line self-explanatory.

pkg/db/context.go (1)

26-30: Avoid empty message string in MarkForRollback error log

In MarkForRollback, the missing-transaction branch logs with an empty message:

logger.Error(errors.New("failed to mark transaction for rollback: could not retrieve transaction from context"), "")

That makes the log line less readable than necessary. Suggest:

-	logger.Error(errors.New("failed to mark transaction for rollback: could not retrieve transaction from context"), "")
+	logger.Error(
+		errors.New("failed to mark transaction for rollback: could not retrieve transaction from context"),
+		"failed to mark transaction for rollback",
+	)

(or similar wording) so both the err and msg are meaningful.

Also applies to: 35-36, 50-54, 57-58

cmd/maestro/server/logging/writer.go (1)

8-10: Include logMsg in the error-path log for better diagnostics

When formatting fails, you currently log only a generic message:

writer.logger.Error(err, "Unable to format request/response for log")

To retain the intended log content for debugging, consider attaching logMsg as structured data:

-		writer.logger.Error(err, "Unable to format request/response for log")
+		writer.logger.Error(err, "Unable to format request/response for log", "log", logMsg)

This keeps error context while making problematic payloads easier to trace.

Also applies to: 18-19, 31-37

cmd/maestro/server/auth_interceptor.go (1)

101-107: Align stream interceptor logging with per-stream context

Unary interceptor correctly derives logger := klog.FromContext(ctx) inside the per-RPC closure, but the stream interceptor captures a logger from the constructor’s ctx:

func newAuthStreamInterceptor(ctx context.Context, authNType string, ...) grpc.StreamServerInterceptor {
	logger := klog.FromContext(ctx)
	return func(..., ss grpc.ServerStream, ...) error {
		// logs use logger here

If you attach request-scoped values (operation IDs, correlation IDs, etc.) to ss.Context(), those won’t show up in these logs.

Consider moving the FromContext call into the returned function and deriving it from the stream context, e.g.:

return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
	logger := klog.FromContext(ss.Context())
	// ...
}

so stream logs are consistent with unary logs and carry per-stream context.

Also applies to: 110-113, 150-152, 161-172

test/e2e/pkg/suite_test.go (1)

9-9: Import ordering: k8s.io import should be grouped with external imports.

The k8s.io/klog/v2 import is placed within the standard library imports block. It should be moved to the external imports section (after line 23) alongside other k8s.io imports for consistency.

 import (
 	"bytes"
 	"context"
 	"crypto/tls"
 	"flag"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net/http"
 	"os"
 	"testing"
 	"time"

 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/rand"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/tools/clientcmd"
+	"k8s.io/klog/v2"
cmd/maestro/main.go (1)

18-21: Remove unused constants.

The logConfigFile and varLogLevel constants appear to be remnants of the removed viper/fsnotify-based logging configuration and are no longer used after this migration.

-const (
-	logConfigFile = "/configs/logging/config.yaml"
-	varLogLevel   = "log_level"
-)
cmd/maestro/environments/framework.go (1)

5-6: Import ordering: k8s.io import should be grouped with external imports.

The k8s.io/klog/v2 import is placed within the standard library imports block. Move it to the external imports section for consistency with Go import conventions.

 import (
 	"fmt"
-	"k8s.io/klog/v2"
-	"log"
+	"log"
 	"os"
 	"strings"

 	"github.com/getsentry/sentry-go"
+	"k8s.io/klog/v2"
cmd/maestro/server/routes.go (1)

38-40: Redundant nil check on authMiddleware.

The authMiddleware is unconditionally assigned a mock on line 32 (authMiddleware = &auth.AuthMiddlewareMock{}), and if JWT is enabled, it's either successfully assigned or check terminates the process. This nil check can never trigger.

 	if env().Config.HTTPServer.EnableJWT {
 		var err error
 		authMiddleware, err = auth.NewAuthMiddleware()
 		check(ctx, err, "Unable to create auth middleware")
 	}
-	if authMiddleware == nil {
-		check(ctx, errors.New("authMiddleware is not set"), "Unable to create auth middleware: missing middleware")
-	}
cmd/maestro/common/otlp_sdk.go (1)

5-6: Import ordering: k8s.io import should be grouped with external imports.

The k8s.io/klog/v2 import is placed within the standard library imports block. Move it after the OpenTelemetry imports for consistency.

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"os"
 	"time"

 	"go.opentelemetry.io/contrib/exporters/autoexport"
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/propagation"
 	"go.opentelemetry.io/otel/sdk/resource"
 	tracesdk "go.opentelemetry.io/otel/sdk/trace"
 	semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
+	"k8s.io/klog/v2"

 	"github.com/openshift-online/maestro/pkg/constants"
cmd/maestro/server/server.go (1)

4-5: Import ordering: k8s.io import should be grouped with external imports.

The k8s.io/klog/v2 import is placed within the standard library imports block.

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"net"
 	"net/http"
 	"os"
 	"strings"

 	"github.com/getsentry/sentry-go"
+	"k8s.io/klog/v2"

 	"github.com/openshift-online/maestro/cmd/maestro/environments"
 )
cmd/maestro/server/metrics_server.go (1)

6-6: Import ordering: k8s.io import should be grouped with external imports.

The k8s.io/klog/v2 import is placed within the standard library imports block.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net"
 	"net/http"

 	"github.com/gorilla/mux"
+	"k8s.io/klog/v2"

 	"github.com/openshift-online/maestro/pkg/api"
cmd/maestro/server/controllers.go (2)

5-5: Import ordering: k8s.io import should be grouped with external imports.

The k8s.io/klog/v2 import is placed within the standard library imports block.

 import (
 	"context"
-	"k8s.io/klog/v2"

 	"github.com/openshift-online/maestro/pkg/api"
 	"github.com/openshift-online/maestro/pkg/controllers"
 	"github.com/openshift-online/maestro/pkg/dao"
 	"github.com/openshift-online/maestro/pkg/db"
+	"k8s.io/klog/v2"
 )

13-26: Logger variable unused when message broker is disabled.

The logger variable on line 14 is only used inside the if !env().Config.MessageBroker.Disable block (line 26). When the message broker is disabled, this variable is created but never used.

Consider moving the logger extraction inside the conditional block:

 func NewControllersServer(ctx context.Context, eventServer EventServer, eventFilter controllers.EventFilter) *ControllersServer {
-	logger := klog.FromContext(ctx)
-
 	s := &ControllersServer{
 		StatusController: controllers.NewStatusController(
 			env().Services.StatusEvents(),
 			dao.NewInstanceDao(&env().Database.SessionFactory),
 			dao.NewEventInstanceDao(&env().Database.SessionFactory),
 		),
 	}

 	// disable the spec controller if the message broker is disabled
 	if !env().Config.MessageBroker.Disable {
+		logger := klog.FromContext(ctx)
 		logger.V(4).Info("Message broker is enabled, setting up kind controller manager")
cmd/maestro/server/grpc_broker.go (1)

3-11: Non-standard import ordering.

The k8s.io/klog/v2 import on line 8 is placed between standard library imports (fmt and net). Go convention groups imports into: standard library, then external packages, then internal packages (separated by blank lines).

 import (
 	"context"
 	"crypto/tls"
 	"crypto/x509"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net"
 	"os"
 	"time"
 
+	"k8s.io/klog/v2"
 	ce "github.com/cloudevents/sdk-go/v2"
cmd/maestro/server/event_server.go (2)

3-19: Non-standard import ordering.

Similar to grpc_broker.go, the k8s.io/klog/v2 import is placed after standard library imports but before external packages, which is correct, but k8s.io/apimachinery/api/meta should also be grouped with the klog import.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 
 	"github.com/openshift-online/maestro/pkg/api"
 	"github.com/openshift-online/maestro/pkg/client/cloudevents"
 	"github.com/openshift-online/maestro/pkg/dao"
 	"github.com/openshift-online/maestro/pkg/db"
 	"github.com/openshift-online/maestro/pkg/dispatcher"
 	"github.com/openshift-online/maestro/pkg/event"
 	"github.com/openshift-online/maestro/pkg/services"
+	"k8s.io/klog/v2"
 	"k8s.io/apimachinery/pkg/api/meta"

169-171: Inconsistent log level annotation.

The message includes a WARN: prefix but uses logger.Info. Either remove the prefix or use a different logging approach. With klog, warnings are typically logged at a lower verbosity level or the prefix should be removed for clarity.

 	if svcErr != nil {
 		if svcErr.Is404() {
-			logger.Info("WARN: skipping resource as it is not found")
+			logger.V(1).Info("skipping resource status update as resource is not found")
 			return nil
 		}
pkg/controllers/framework.go (1)

3-14: Non-standard import ordering.

The k8s.io/klog/v2 import on line 6 is placed between fmt and time (standard library imports). It should be in a separate import group with other external packages.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"time"
 
+	"k8s.io/klog/v2"
 	"github.com/openshift-online/maestro/pkg/api"
cmd/maestro/servecmd/cmd.go (1)

3-23: Non-standard import ordering.

The imports errors, k8s.io/klog/v2, and log are mixed between standard library and external packages. Standard library imports should be grouped together, followed by external packages.

 import (
 	"context"
 	"errors"
-	"k8s.io/klog/v2"
 	"log"
 	"os"
 	"os/signal"
 	"syscall"
 	"time"
 
+	"k8s.io/klog/v2"
 	"github.com/spf13/cobra"
test/helper.go (1)

3-16: Non-standard import ordering.

The k8s.io/klog/v2 and log imports are placed between standard library imports. They should be properly grouped.

 import (
 	"context"
 	"crypto/rsa"
 	"encoding/json"
 	"fmt"
-	"k8s.io/klog/v2"
 	"log"
 	"os"
 	"path/filepath"
 	"strings"
 	"sync"
 	"testing"
 	"time"
 
+	"k8s.io/klog/v2"
 	"github.com/openshift-online/maestro/pkg/client/cloudevents"
cmd/maestro/server/api_server.go (1)

201-203: Consider accepting context parameter in Stop method.

The Stop() method uses context.Background() for shutdown, which is inconsistent with the context-aware design throughout the rest of the file. While context.Background() is acceptable for cleanup paths, consider whether the method should accept a context parameter for timeout control and cancellation.

If the Server interface permits, update the signature:

-func (s apiServer) Stop() error {
-	return s.httpServer.Shutdown(context.Background())
+func (s apiServer) Stop(ctx context.Context) error {
+	return s.httpServer.Shutdown(ctx)
 }

This would allow callers to control shutdown timeout and cancellation.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 4a3cf9b and 7461525.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (49)
  • cmd/maestro/agent/cmd.go (1 hunks)
  • cmd/maestro/common/otlp_sdk.go (4 hunks)
  • cmd/maestro/environments/framework.go (6 hunks)
  • cmd/maestro/main.go (1 hunks)
  • cmd/maestro/migrate/cmd.go (2 hunks)
  • cmd/maestro/servecmd/cmd.go (4 hunks)
  • cmd/maestro/server/api_server.go (6 hunks)
  • cmd/maestro/server/auth_interceptor.go (4 hunks)
  • cmd/maestro/server/controllers.go (3 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • cmd/maestro/server/healthcheck_server.go (6 hunks)
  • cmd/maestro/server/logging/formatter_json.go (3 hunks)
  • cmd/maestro/server/logging/logging.go (0 hunks)
  • cmd/maestro/server/logging/writer.go (3 hunks)
  • cmd/maestro/server/metrics_server.go (2 hunks)
  • cmd/maestro/server/routes.go (3 hunks)
  • cmd/maestro/server/server.go (3 hunks)
  • go.mod (3 hunks)
  • pkg/api/error.go (5 hunks)
  • pkg/api/metadata.go (4 hunks)
  • pkg/auth/helpers.go (1 hunks)
  • pkg/client/cloudevents/source_client.go (4 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
  • pkg/controllers/event_filter.go (3 hunks)
  • pkg/controllers/framework.go (9 hunks)
  • pkg/controllers/framework_test.go (2 hunks)
  • pkg/controllers/status_controller.go (7 hunks)
  • pkg/db/advisory_locks.go (8 hunks)
  • pkg/db/context.go (2 hunks)
  • pkg/db/db_session/default.go (4 hunks)
  • pkg/db/db_session/test.go (2 hunks)
  • pkg/db/migrations.go (2 hunks)
  • pkg/db/transaction_middleware.go (2 hunks)
  • pkg/dispatcher/hash_dispatcher.go (8 hunks)
  • pkg/dispatcher/noop_dispatcher.go (5 hunks)
  • pkg/errors/errors.go (0 hunks)
  • pkg/event/event.go (5 hunks)
  • pkg/handlers/framework.go (2 hunks)
  • pkg/logger/logger.go (0 hunks)
  • pkg/logger/zap.go (0 hunks)
  • pkg/services/generic.go (3 hunks)
  • pkg/services/resource.go (5 hunks)
  • test/e2e/pkg/suite_test.go (3 hunks)
  • test/helper.go (10 hunks)
  • test/integration/integration_test.go (1 hunks)
  • test/mocks/workserver/main.go (5 hunks)
  • test/upgrade/pkg/suite_test.go (2 hunks)
💤 Files with no reviewable changes (4)
  • pkg/logger/logger.go
  • pkg/logger/zap.go
  • pkg/errors/errors.go
  • cmd/maestro/server/logging/logging.go
🚧 Files skipped from review as they are similar to previous changes (15)
  • test/upgrade/pkg/suite_test.go
  • pkg/dispatcher/noop_dispatcher.go
  • cmd/maestro/migrate/cmd.go
  • pkg/db/transaction_middleware.go
  • pkg/api/error.go
  • pkg/services/generic.go
  • pkg/controllers/event_filter.go
  • pkg/controllers/status_controller.go
  • pkg/event/event.go
  • cmd/maestro/server/healthcheck_server.go
  • pkg/client/cloudevents/source_client.go
  • pkg/controllers/framework_test.go
  • pkg/services/resource.go
  • test/integration/integration_test.go
  • cmd/maestro/agent/cmd.go
🧰 Additional context used
🧬 Code graph analysis (7)
cmd/maestro/server/auth_interceptor.go (1)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
pkg/controllers/framework.go (3)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/event.go (1)
  • EventType (9-9)
pkg/api/openapi/model_error.go (1)
  • Error (21-28)
cmd/maestro/server/logging/writer.go (1)
cmd/maestro/server/logging/formatter.go (1)
  • LogFormatter (5-8)
cmd/maestro/server/api_server.go (2)
cmd/maestro/server/server.go (1)
  • Server (16-21)
cmd/maestro/server/grpc_server.go (2)
  • NewGRPCServer (48-146)
  • GRPCServer (36-45)
cmd/maestro/environments/framework.go (3)
cmd/maestro/environments/types.go (1)
  • Clients (50-54)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
cmd/maestro/server/grpc_server.go (1)
  • GRPCServer (36-45)
test/helper.go (2)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
cmd/maestro/server/healthcheck_server.go (1)
  • HealthCheckServer (19-26)
pkg/handlers/framework.go (1)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Red Hat Konflux / maestro-e2e-on-pull-request
  • GitHub Check: Red Hat Konflux / maestro-on-pull-request
  • GitHub Check: e2e-with-istio
  • GitHub Check: migration
  • GitHub Check: e2e-grpc-broker
  • GitHub Check: e2e-broadcast-subscription
  • GitHub Check: e2e
🔇 Additional comments (54)
pkg/client/grpcauthorizer/kube_authorizer.go (2)

10-10: LGTM: Import addition is correct.

The klog/v2 import is appropriate for the contextual logging migration.


46-54: LGTM: Contextual logging migration is correct.

The logger setup and usage follow klog best practices:

  • Logger is correctly extracted from context
  • All structured fields have unique keys (the past duplicate "resource" key issue has been addressed)
  • Verbosity level V(4) is appropriate for detailed authorization checks
pkg/db/db_session/default.go (4)

7-7: LGTM! klog/v2 import added for contextual logging migration.

The import is correctly added to support the migration from custom logging to klog contextual logging throughout this file.


141-168: LGTM! Contextual logging properly implemented in waitForNotification.

The function correctly:

  • Derives a logger from the context at line 142
  • Uses structured logging with appropriate field names throughout
  • Applies V(4) verbose level for frequent notification events at line 150
  • Maintains all the original logging information in the new structured format

170-197: LGTM! Error logging correctly structured in newListener.

The function properly:

  • Derives a logger from the context at line 171
  • Uses logger.Error with the correct signature at line 175 (error as first argument, followed by message and structured fields)
  • Includes the eventType field to provide useful debugging context for listener state changes

199-206: LGTM! Public API cleanly migrated to contextual logging.

The NewListener function correctly:

  • Derives a logger from the context at line 200
  • Logs the listener startup with structured channel information at line 203
  • Maintains the same public API signature while implementing contextual logging internally
pkg/dispatcher/hash_dispatcher.go (4)

6-6: LGTM!

The klog import is correctly added to support contextual logging throughout the file.


77-77: LGTM!

The contextual logger is correctly obtained from context and used for structured error logging with appropriate fields.

Also applies to: 86-86


152-152: LGTM!

The contextual logger is correctly created from context and used consistently throughout the method with appropriate log levels and structured fields.

Also applies to: 155-155, 195-196, 201-201


208-208: LGTM!

The contextual logger is correctly created and used throughout. The addition of Forget on the success path (lines 235-238) properly addresses the past review comment about rate limiter state management.

Also applies to: 230-232, 235-238

pkg/handlers/framework.go (2)

7-11: LGTM!

The imports are correct for the klog migration. The alias loggertracing appropriately avoids confusion with the local logger variable.


34-40: Verify logger middleware configuration before merging

The contextual logging implementation correctly uses klog's API, but its effectiveness depends on two critical prerequisites:

  1. klog.EnableContextualLogging(true) must be called during application startup before spawning goroutines; otherwise klog.FromContext(ctx) silently falls back to the global logger
  2. Request middleware must inject the logger into context using klog.NewContext(ctx, logger) and propagate context with r.WithContext(ctx)

Verify that:

  • Logger middleware exists and calls klog.NewContext to attach a per-request logger
  • klog.EnableContextualLogging(true) is called at application startup
  • Context is propagated through all request handlers via r.WithContext(ctx)

Without these, the contextual logging will not function as intended.

pkg/db/db_session/test.go (1)

7-7: klog migration in Test.Init looks correct; just confirm it matches repo-wide logging conventions

Importing k8s.io/klog/v2 and switching the two error paths in Init to:

klog.Error(err, "error initializing test database")
klog.Error(err, "error resetting test database")

is functionally fine and keeps roughly the same behavior as the previous logger (no formatting is needed here, and both error + message are logged).

If the rest of the codebase is standardizing on klog.ErrorS/structured logging and/or context-derived loggers, you may want to consider aligning these calls (e.g., adding DB name as a field), but that’s purely optional for this test helper.

Also applies to: 58-64

test/mocks/workserver/main.go (1)

10-10: Klog migration in mock server looks consistent

The switch to klog here (Infof/Fatalf/Errorf) for init/start/shutdown paths is straightforward and appropriate for this standalone test binary; no issues from a correctness or behavior perspective.

Also applies to: 155-159, 172-172, 269-270, 279-281, 286-287

pkg/api/metadata.go (1)

34-35: Context-derived logging for metadata responses looks good

Deriving the logger from r.Context() and logging write failures with a clear message and "path" field (while still capturing to Sentry) is a solid, context-aware pattern; no further changes needed here.

Also applies to: 55-61, 69-70, 93-98

go.mod (1)

93-93: Dependency graph updates look reasonable; ensure go mod tidy stays clean

Marking github.com/fsnotify/fsnotify, go.uber.org/zap, and google.golang.org/genproto as indirect is consistent with removing direct logger/config usages elsewhere. Just ensure CI runs go mod tidy (and that go.sum is updated) so the module graph stays consistent with the new logging stack.

Also applies to: 173-173, 186-186

cmd/maestro/server/logging/formatter_json.go (1)

24-27: V(4)-gated JSON logging is consistent with the new klog usage

Using klog.V(4).Enabled() to decide when to include headers/bodies in request/response JSON logs aligns with the writer’s .V(4) logging and replaces the old logger-level check cleanly; no issues spotted here.

Also applies to: 38-40

test/e2e/pkg/suite_test.go (1)

246-252: LGTM!

The migration from the custom logger to klog is correctly implemented. The klog.Infof and klog.Errorf calls appropriately replace the previous logging calls.

cmd/maestro/main.go (1)

23-51: LGTM!

The klog initialization and integration with cobra flags is correctly implemented. Using log.Fatalf for the fatal error case during command execution is appropriate since it's a startup-time failure before the application context is established.

cmd/maestro/environments/framework.go (1)

73-73: LGTM!

The migration to klog-based logging is correctly implemented. Using klog.Infof for environment initialization and klog.V(4).Info/Infof for debug-level messages (mock clients, fallback paths, Sentry config) follows good practice for verbosity-controlled logging.

Also applies to: 159-159, 170-170, 198-198, 203-203, 227-227, 232-232

cmd/maestro/server/routes.go (1)

19-19: LGTM!

The context-aware signature and error handling propagation are correctly implemented. The check(ctx, err, ...) pattern aligns with the broader PR changes for context-based error handling.

Also applies to: 24-24, 36-36

cmd/maestro/common/otlp_sdk.go (1)

26-27: LGTM!

The migration to accept a klog.Logger parameter enables proper context-aware logging. The error handler correctly captures the logger in the closure for OpenTelemetry error callbacks.

Also applies to: 59-61

cmd/maestro/server/server.go (1)

16-21: LGTM!

The context-aware Server interface and check function are correctly implemented. Using klog.FromContext(ctx) to extract the logger enables consistent, context-bound logging throughout the request lifecycle.

Also applies to: 31-38

cmd/maestro/server/metrics_server.go (1)

47-66: LGTM!

The context-aware Start method correctly extracts the logger and propagates context through error checks. The TLS vs non-TLS logging paths are properly handled with the context-bound logger.

cmd/maestro/server/controllers.go (1)

58-75: LGTM!

The Start method correctly creates a named logger ("maestro-controllers"), injects it into the context via klog.NewContext, and uses it consistently for all controller lifecycle logging. The context propagation to Run and listener callbacks is properly implemented.

cmd/maestro/server/grpc_broker.go (4)

128-130: LGTM!

The constructor now properly accepts a context and derives a context-bound logger for TLS setup messages. This aligns with the project-wide migration to klog-based contextual logging.


154-179: LGTM!

TLS error handling now consistently uses check(ctx, ...) for all error paths, ensuring Sentry reporting and proper error context propagation.


215-231: LGTM!

The Start method now properly derives a context-bound logger and uses check(ctx, ...) for error handling in both the listener setup and server goroutine. This addresses the previous review feedback about os.Exit(1) bypassing Sentry reporting.


269-285: LGTM!

The PredicateEvent method uses a context-derived logger with appropriate verbosity level (V(4)) for debug-level reconciliation messages.

cmd/maestro/server/event_server.go (3)

77-89: LGTM!

The Start method properly derives a context-bound logger for lifecycle messages.


93-117: LGTM!

The subscription handler properly enriches the context with structured logging fields (resourceID, action) and propagates the enriched context to downstream calls.


255-295: LGTM!

The broadcastStatusEvent function properly enriches the logger with relevant context fields (resourceID, instanceID, eventID) for effective log correlation.

pkg/controllers/framework.go (4)

88-104: LGTM!

The Run method properly uses context-aware wait utilities (JitterUntilWithContext, UntilWithContext) and derives a context-bound logger for lifecycle messages.


118-121: LGTM!

The handleEvent method properly enriches the context with both the logger (containing the EventID) and the EventID value for downstream handler access.


203-230: LGTM!

The processNextEvent method properly derives a logger with the queue key for effective error tracing.


232-258: LGTM!

The syncEvents method properly uses a context-derived logger for operation and error logging.

cmd/maestro/servecmd/cmd.go (4)

52-56: LGTM!

The context and logger initialization properly creates a named logger and embeds it in the context for propagation throughout the server components.


76-79: LGTM!

The error handling for unsupported subscription types now uses proper klog.Error format with a descriptive message, addressing previous review feedback.


113-117: LGTM!

The tracing shutdown error handling now correctly captures the shutdown error in a separate variable (shutdownErr) and logs it appropriately, addressing the previous review feedback about using the wrong error variable.


120-131: LGTM!

All server components now receive the context for proper lifecycle management and cancellation propagation.

test/helper.go (4)

157-160: LGTM!

The NewGRPCBroker call correctly passes the context parameter to match the updated constructor signature.


198-265: LGTM!

All test server startup methods consistently derive loggers from helper.Ctx and use appropriate verbosity levels (V(4)) for test infrastructure messages.


376-378: LGTM!

The typo has been corrected from "Reseting" to "Resetting", addressing previous review feedback.


516-538: LGTM!

The CleanDB method properly uses a context-derived logger with structured error logging that includes the table name for debugging.

cmd/maestro/server/api_server.go (3)

40-43: LGTM: Constructor updated for context propagation.

The constructor signature correctly accepts context.Context and propagates it to routes(). This aligns with the PR's goal of enabling contextual logging throughout the server lifecycle.


148-171: LGTM: Context-aware logging properly implemented.

The Serve method correctly:

  • Accepts context.Context as a parameter
  • Derives a logger from the context via klog.FromContext(ctx)
  • Passes context to all check() calls
  • Uses the context-derived logger for TLS/non-TLS startup messages

68-68: Verify the check function implementation.

The check function is now called with ctx as the first argument. Ensure that its implementation properly uses the context for logging via klog.FromContext(ctx).

cmd/maestro/server/grpc_server.go (7)

48-54: LGTM: Constructor signature updated correctly.

The constructor now accepts context.Context as the first parameter and derives a logger from it. This is consistent with the broader migration to contextual logging.


74-135: LGTM: TLS setup with context-aware error handling.

The TLS/mTLS configuration paths correctly use check(ctx, ...) for error handling and the context-derived logger for startup messages. The logging includes useful port information for debugging.


149-159: LGTM: Start method properly propagates context.

The Start method correctly:

  • Accepts context.Context as a parameter
  • Derives a logger from the context
  • Uses context-aware logging for errors

167-240: LGTM: Publish method uses per-request context.

The Publish method correctly derives the logger from the incoming request context (line 168), ensuring each request has its own contextual logging scope. Authorization and resource operations properly use this context.


243-361: LGTM: Subscribe method with proper context management.

The subscribe flow correctly:

  • Derives logger from the stream context (line 266)
  • Passes context to eventBroadcaster.Register() and Unregister() (lines 304, 355, 358)
  • Uses context-aware logging for errors and events
  • Properly manages context cancellation

445-488: LGTM: Resync handler uses context-aware logging.

The respondResyncStatusRequest function correctly derives the logger from the context and uses it for logging throughout the resync flow.


98-98: Stream interceptor receives constructor context instead of request context.

Line 98 passes the constructor's ctx to newAuthStreamInterceptor(). Verify whether:

  1. The interceptor uses this context at construction time (problematic) or stores it only as configuration
  2. The interceptor extracts the actual request context from the stream itself via stream.Context()
  3. If the constructor context is indeed used for authentication decisions, this could cause all stream authentications to fail if the setup context is cancelled

Compare the pattern used here against newAuthUnaryInterceptor() on the same line to ensure consistency. If the stream interceptor should derive its context per-request from the stream rather than using the construction-time context, remove the ctx parameter.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmd/maestro/server/grpc_server.go (1)

466-472: Clarify log message: the condition is inverted.

The log message at line 470 says "The resource is not found from the maestro" but the condition !ok means the resource exists in maestro (obj is from objs) but is NOT found in the source's statusHashes. The message should reflect this:

 	if !ok {
 		// ignore the resource that is not on the source, but exists on the maestro, wait for the source deleting it
-		logger.Info("The resource is not found from the maestro, ignore", "objectID", obj.GetUID())
+		logger.Info("The resource is not found in the source status hashes, ignore", "objectID", obj.GetUID())
 		continue
 	}
♻️ Duplicate comments (2)
pkg/services/resource.go (1)

226-226: Fix inconsistent key naming for camelCase convention.

The log key "wantsequenceID" is inconsistent with camelCase convention used elsewhere (e.g., "foundSequenceID" on the same line and "wantVersion" on line 185). This affects log parsing and searchability.

Apply this diff to fix the naming:

-		logger.Info("Updating status for stale resource; disregard it",
-			"foundSequenceID", foundSequenceID, "wantsequenceID", sequenceID)
+		logger.Info("Updating status for stale resource; disregard it",
+			"foundSequenceID", foundSequenceID, "wantSequenceID", sequenceID)
cmd/maestro/server/api_server.go (1)

180-193: os.Exit(1) bypasses deferred gRPC server cleanup.

Line 191 calls os.Exit(1) which immediately terminates the process, bypassing the deferred s.grpcServer.Stop() at line 184. This could leave gRPC connections open or resources unreleased if the listener fails to start.

Apply this diff to return instead of exiting, allowing deferred cleanup to run:

 	listener, err := s.Listen()
 	if err != nil {
 		logger.Error(err, "Unable to start API server")
-		os.Exit(1)
+		return
 	}
 	s.Serve(ctx, listener)

Alternatively, if an exit is required, explicitly stop the gRPC server before exiting:

 	listener, err := s.Listen()
 	if err != nil {
 		logger.Error(err, "Unable to start API server")
+		if env().Config.GRPCServer.EnableGRPCServer {
+			s.grpcServer.Stop()
+		}
 		os.Exit(1)
 	}
🧹 Nitpick comments (13)
pkg/auth/helpers.go (1)

13-25: Enrich error logs with message and correlation fields

The switch to a context-derived logger and 4xx→Info / non‑4xx→Error split looks good. Two small improvements:

  • logger.Error(err, "") logs with an empty message; prefer a descriptive message.
  • Include operationID (and possibly HTTP code) as structured fields on both Info and Error logs to simplify log correlation.

For example:

-	if err.HttpCode >= 400 && err.HttpCode <= 499 {
-		logger.Info("client error", "error", err.Error(), "code", err.HttpCode)
-	} else {
-		logger.Error(err, "")
-	}
+	if err.HttpCode >= 400 && err.HttpCode <= 499 {
+		logger.Info("client error",
+			"error", err.Error(),
+			"code", err.HttpCode,
+			"operation_id", operationID,
+		)
+	} else {
+		logger.Error(err, "server error",
+			"code", err.HttpCode,
+			"operation_id", operationID,
+		)
+	}

Also please double‑check that all call sites always pass a non‑nil ctx with a logger injected (so klog.FromContext behaves as expected).

pkg/dispatcher/noop_dispatcher.go (1)

77-90: Consider using a closure to enable contextual logging.

The onInstanceUpdate callback uses global klog.Infof/klog.Errorf while Start and resyncOnReconnect use contextual logging via klog.FromContext(ctx). For consistency, consider capturing the logger in a closure.

 func (d *NoopDispatcher) Start(ctx context.Context) {
 	logger := klog.FromContext(ctx)
 	// handle client reconnected signal and resync status from consumers for this source
 	go d.resyncOnReconnect(ctx)

 	// listen for server_instance update
 	logger.Info("NoopDispatcher listening for server_instances updates")
-	go d.sessionFactory.NewListener(ctx, "server_instances", d.onInstanceUpdate)
+	go d.sessionFactory.NewListener(ctx, "server_instances", func(ids string) {
+		d.onInstanceUpdate(logger, ids)
+	})

 	// wait until context is canceled
 	<-ctx.Done()

 }

Then update the method signature:

-func (d *NoopDispatcher) onInstanceUpdate(ids string) {
+func (d *NoopDispatcher) onInstanceUpdate(logger klog.Logger, ids string) {
 	states := strings.Split(ids, ":")
 	if len(states) != 2 {
-		klog.Infof("watched server instances updated with invalid ids: %s", ids)
+		logger.Info("watched server instances updated with invalid ids", "ids", ids)
 		return
 	}
 	idList := strings.Split(states[1], ",")
 	if states[0] == "unready" && len(idList) > 0 {
 		// only call onInstanceDown once with empty instance id to reduce the number of status resync requests
 		if err := d.onInstanceDown(); err != nil {
-			klog.Errorf("failed to call OnInstancesDown: %v", err)
+			logger.Error(err, "failed to call OnInstancesDown")
 		}
 	}
 }
pkg/api/error.go (1)

41-45: Contextual error logging in API helpers looks good

Using klog.FromContext(r.Context()) in the write‑error paths keeps logs tied to the request while preserving Sentry reporting and control flow. The init‑time klog.Error(err) is also appropriate where no request context exists. Optionally, consider adding method/remote‑addr fields for more diagnosability.

Also applies to: 63-67, 73-79, 101-109

cmd/maestro/server/auth_interceptor.go (1)

90-120: Derive stream logger from ss.Context() instead of constructor ctx

newAuthUnaryInterceptor correctly uses the per‑RPC ctx, but newAuthStreamInterceptor binds logger := klog.FromContext(ctx) at construction time. That ctx is typically process/server‑scoped, so stream logs won’t pick up per‑request values injected into ss.Context() (operation IDs, tracing, etc.).

Consider deriving the logger inside the interceptor from the stream context:

-func newAuthStreamInterceptor(ctx context.Context, authNType string, authorizer grpcauthorizer.GRPCAuthorizer) grpc.StreamServerInterceptor {
-	logger := klog.FromContext(ctx)
-	return func(
+func newAuthStreamInterceptor(ctx context.Context, authNType string, authorizer grpcauthorizer.GRPCAuthorizer) grpc.StreamServerInterceptor {
+	return func(
 		srv interface{},
 		ss grpc.ServerStream,
 		info *grpc.StreamServerInfo,
 		handler grpc.StreamHandler,
 	) error {
+		logger := klog.FromContext(ss.Context())

This keeps the existing API while ensuring stream logs carry the same request context as the unary interceptor. Also, consider normalizing the default error message ("unsupported authentication type %s") to match the unary path.

Also applies to: 150-179

cmd/maestro/server/metrics_server.go (1)

44-67: Metrics server Start integration with context and klog looks consistent

Start(ctx) now uses klog.FromContext(ctx) for TLS/non‑TLS startup logs, validates TLS config via check(ctx, ...), and relies on check to handle non‑http.ErrServerClosed termination errors. This aligns with the new Server interface and central error handling. If Stop() is ever extended to accept a context, consider threading that ctx into Shutdown instead of context.Background() for graceful, deadline‑aware shutdowns.

cmd/maestro/server/grpc_broker.go (1)

128-188: gRPC broker TLS and lifecycle now use ctx‑aware logging and check consistently

NewGRPCBroker and Start now route TLS validation, listener errors, and Serve failures through check(ctx, ...) and use klog.FromContext(ctx) for startup/shutdown messages. PredicateEvent’s V(4) log on deleted resources is also moved to klog with context. This brings the broker in line with the rest of the ctx‑aware logging and centralized fatal handling. If log ordering matters, consider moving the “Serving gRPC broker with/without TLS” messages to just after the successful net.Listen in Start, but behavior is otherwise sound.

Also applies to: 214-231, 269-286

pkg/event/event.go (1)

41-57: EventBroadcaster’s ctx‑aware logging and signatures look correct

Register, Unregister, and Start now use klog.FromContext(ctx) to log client lifecycle, empty‑client situations, and handler failures while preserving the existing metrics behavior. This fits well with the broader contextual logging shift. If the “no clients registered on this instance” message fires frequently in production, consider logging it at a higher verbosity (e.g., V(3/4)) or gating it to avoid log noise.

Also applies to: 60-74, 82-106

cmd/maestro/server/healthcheck_server.go (1)

176-177: Request context logger may lack enrichment.

The logger is derived from r.Context(), but HTTP request contexts typically don't have a klog logger attached unless middleware injects one. This will fall back to the global logger.

Consider whether middleware should inject a logger into the request context, or use a fallback pattern:

 func (s *HealthCheckServer) healthCheckHandler(w http.ResponseWriter, r *http.Request) {
-	logger := klog.FromContext(r.Context()).WithValues("instanceID", s.instanceID)
+	logger := klog.TODO().WithValues("instanceID", s.instanceID, "path", r.URL.Path)

Alternatively, if you expect middleware to inject the logger, this is fine as-is since klog.FromContext gracefully falls back to the global logger.

pkg/controllers/framework.go (1)

6-7: Import grouping: stdlib imports should be grouped together.

The k8s.io/klog/v2 import is placed between stdlib imports (fmt and time). Consider moving it to the external imports section for consistency with Go import conventions.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"time"
 
 	"github.com/openshift-online/maestro/pkg/api"
 	"github.com/openshift-online/maestro/pkg/services"
 
+	"k8s.io/klog/v2"
 	"k8s.io/apimachinery/pkg/util/wait"
 	"k8s.io/client-go/util/workqueue"
 )
cmd/maestro/server/grpc_server.go (1)

8-11: Import grouping: stdlib imports should be grouped together.

Same issue as in framework.go - the k8s.io/klog/v2 import is placed between stdlib imports.

 import (
 	"context"
 	"crypto/tls"
 	"crypto/x509"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net"
 	"os"
 	"time"

Move k8s.io/klog/v2 to the external imports section.

pkg/controllers/status_controller.go (3)

6-7: Import grouping: stdlib imports should be grouped together.

Same issue as in other files - the k8s.io/klog/v2 import is placed between stdlib imports.


76-99: Minor inconsistency with framework.go pattern.

In framework.go, processNextEvent enriches the logger with the key before logging errors:

logger := klog.FromContext(ctx).WithValues("key", key)

This method logs the key separately in the error message. Consider aligning for consistency:

 func (sc *StatusController) processNextEvent(ctx context.Context) bool {
-	logger := klog.FromContext(ctx)
+	logger := klog.FromContext(ctx).WithValues("key", key)
 	// pull the next status event item from queue.
 	// events queue blocks until it can return an item to be processed
 	key, quit := sc.eventsQueue.Get()

Note: You'd need to move the key declaration before the logger creation, which changes the flow slightly.


161-190: Consider verbosity level for instance IDs logging.

Line 169 logs all readyInstanceIDs which could be verbose in large deployments. Consider using V(2) or V(4) for detailed instance information:

-	logger.Info("purge status events on the ready instances", "readyInstanceIDs", readyInstanceIDs)
+	logger.V(2).Info("purge status events on the ready instances", "readyInstanceIDs", readyInstanceIDs)

Or log just the count at info level and details at verbose level:

logger.Info("purge status events on the ready instances", "count", len(readyInstanceIDs))
logger.V(4).Info("ready instance details", "readyInstanceIDs", readyInstanceIDs)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 7461525 and 42f5f17.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (49)
  • cmd/maestro/agent/cmd.go (1 hunks)
  • cmd/maestro/common/otlp_sdk.go (4 hunks)
  • cmd/maestro/environments/framework.go (6 hunks)
  • cmd/maestro/main.go (1 hunks)
  • cmd/maestro/migrate/cmd.go (2 hunks)
  • cmd/maestro/servecmd/cmd.go (4 hunks)
  • cmd/maestro/server/api_server.go (6 hunks)
  • cmd/maestro/server/auth_interceptor.go (4 hunks)
  • cmd/maestro/server/controllers.go (3 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • cmd/maestro/server/healthcheck_server.go (6 hunks)
  • cmd/maestro/server/logging/formatter_json.go (3 hunks)
  • cmd/maestro/server/logging/logging.go (0 hunks)
  • cmd/maestro/server/logging/writer.go (3 hunks)
  • cmd/maestro/server/metrics_server.go (2 hunks)
  • cmd/maestro/server/routes.go (2 hunks)
  • cmd/maestro/server/server.go (3 hunks)
  • go.mod (3 hunks)
  • pkg/api/error.go (5 hunks)
  • pkg/api/metadata.go (4 hunks)
  • pkg/auth/helpers.go (1 hunks)
  • pkg/client/cloudevents/source_client.go (4 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
  • pkg/controllers/event_filter.go (3 hunks)
  • pkg/controllers/framework.go (9 hunks)
  • pkg/controllers/framework_test.go (2 hunks)
  • pkg/controllers/status_controller.go (7 hunks)
  • pkg/db/advisory_locks.go (8 hunks)
  • pkg/db/context.go (2 hunks)
  • pkg/db/db_session/default.go (4 hunks)
  • pkg/db/db_session/test.go (2 hunks)
  • pkg/db/migrations.go (2 hunks)
  • pkg/db/transaction_middleware.go (2 hunks)
  • pkg/dispatcher/hash_dispatcher.go (8 hunks)
  • pkg/dispatcher/noop_dispatcher.go (5 hunks)
  • pkg/errors/errors.go (0 hunks)
  • pkg/event/event.go (5 hunks)
  • pkg/handlers/framework.go (2 hunks)
  • pkg/logger/logger.go (0 hunks)
  • pkg/logger/zap.go (0 hunks)
  • pkg/services/generic.go (3 hunks)
  • pkg/services/resource.go (5 hunks)
  • test/e2e/pkg/suite_test.go (3 hunks)
  • test/helper.go (10 hunks)
  • test/integration/integration_test.go (1 hunks)
  • test/mocks/workserver/main.go (5 hunks)
  • test/upgrade/pkg/suite_test.go (2 hunks)
💤 Files with no reviewable changes (4)
  • cmd/maestro/server/logging/logging.go
  • pkg/logger/zap.go
  • pkg/errors/errors.go
  • pkg/logger/logger.go
🚧 Files skipped from review as they are similar to previous changes (23)
  • cmd/maestro/migrate/cmd.go
  • pkg/client/grpcauthorizer/kube_authorizer.go
  • pkg/db/advisory_locks.go
  • pkg/db/transaction_middleware.go
  • pkg/db/db_session/test.go
  • pkg/client/cloudevents/source_client.go
  • pkg/api/metadata.go
  • pkg/services/generic.go
  • test/e2e/pkg/suite_test.go
  • pkg/controllers/event_filter.go
  • pkg/handlers/framework.go
  • pkg/db/db_session/default.go
  • test/mocks/workserver/main.go
  • cmd/maestro/common/otlp_sdk.go
  • pkg/db/migrations.go
  • pkg/controllers/framework_test.go
  • cmd/maestro/server/logging/writer.go
  • cmd/maestro/server/logging/formatter_json.go
  • pkg/dispatcher/hash_dispatcher.go
  • test/upgrade/pkg/suite_test.go
  • cmd/maestro/environments/framework.go
  • cmd/maestro/main.go
  • cmd/maestro/agent/cmd.go
🧰 Additional context used
🧬 Code graph analysis (12)
cmd/maestro/server/controllers.go (5)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/controllers/framework.go (1)
  • KindControllerManager (52-57)
cmd/maestro/environments/types.go (1)
  • Database (31-33)
pkg/db/session.go (1)
  • SessionFactory (13-21)
cmd/maestro/server/routes.go (5)
cmd/maestro/environments/types.go (1)
  • Services (42-48)
pkg/handlers/resource_bundle.go (1)
  • NewResourceBundleHandler (22-27)
pkg/handlers/consumer.go (1)
  • NewConsumerHandler (24-30)
pkg/handlers/errors.go (1)
  • NewErrorsHandler (14-16)
pkg/auth/auth_middleware_mock.go (1)
  • AuthMiddlewareMock (7-7)
cmd/maestro/server/auth_interceptor.go (1)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
cmd/maestro/server/api_server.go (2)
cmd/maestro/server/server.go (1)
  • Server (16-21)
cmd/maestro/server/grpc_server.go (2)
  • NewGRPCServer (48-146)
  • GRPCServer (36-45)
cmd/maestro/server/grpc_broker.go (2)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
test/helper.go (2)
cmd/maestro/server/grpc_broker.go (1)
  • NewGRPCBroker (128-212)
cmd/maestro/server/api_server.go (1)
  • NewAPIServer (40-144)
cmd/maestro/server/grpc_server.go (5)
pkg/services/resource.go (1)
  • ResourceService (26-39)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
pkg/config/grpc_server.go (1)
  • GRPCServerConfig (10-35)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
pkg/api/resource_types.go (1)
  • Resource (14-27)
pkg/auth/helpers.go (2)
pkg/errors/errors.go (2)
  • ServiceErrorCode (61-61)
  • New (102-116)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
pkg/controllers/status_controller.go (2)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
pkg/controllers/framework.go (2)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/event.go (1)
  • EventType (9-9)
cmd/maestro/server/healthcheck_server.go (1)
pkg/db/advisory_locks.go (1)
  • Instances (25-25)
cmd/maestro/server/event_server.go (3)
pkg/api/resource_types.go (1)
  • Resource (14-27)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Red Hat Konflux / maestro-on-pull-request
  • GitHub Check: Red Hat Konflux / maestro-e2e-on-pull-request
  • GitHub Check: e2e-grpc-broker
  • GitHub Check: migration
  • GitHub Check: e2e-with-istio
  • GitHub Check: e2e-broadcast-subscription
  • GitHub Check: e2e
🔇 Additional comments (49)
go.mod (1)

93-93: Dependency reorganization aligns with klog migration.

The changes correctly reflect the transition from Zap-based logging to klog:

  • fsnotify and viper moved to indirect dependencies, consistent with removing log config management
  • zap moved to indirect, expected since klog replaces the custom Zap logger
  • klog/v2 v2.130.1 (line 56) is a stable release with full contextual logging support via logr-compatible APIs (EnableContextualLogging, NewContext, FromContext, LoggerWithValues, LoggerWithName)

The genproto reorganization (line 186) is part of the dependency graph rebalancing and aligns with the modernization effort.

pkg/auth/helpers.go (1)

3-11: Imports and logger/operation ID wiring look good

Using k8s.io/klog/v2 plus logtracing for GetOperationID aligns this helper with the new contextual logging stack. No issues here.

cmd/maestro/server/event_server.go (6)

6-6: LGTM: klog import added for contextual logging.

The import is correctly added to support the migration to klog's contextual logging pattern.


78-79: LGTM: Start method correctly uses contextual logging.

The startup and shutdown logging properly derives the logger from context and uses appropriate log levels.

Also applies to: 88-88


95-97: LGTM: Logger enrichment and context propagation are correct.

The code properly enriches the logger with resourceID and action, then updates the context so downstream functions like handleStatusUpdate receive the enriched logger.


103-103: LGTM: Previous format specifier issue addressed.

The log message correctly removed the %s format specifier that was flagged in the previous review.


164-165: LGTM: Contextual logging correctly applied.

The logger is properly derived from context and used for informational messages about resource status handling.

Also applies to: 230-230, 248-248


266-267: LGTM: Excellent use of contextual and structured logging.

The logger is properly enriched with resourceID, instanceID, and eventID context. Line 294 demonstrates good practice by using structured key-value logging for statusEventType.

Also applies to: 285-285, 294-294

pkg/dispatcher/noop_dispatcher.go (3)

3-12: Skip: Import grouping is not flagged by linters.


35-47: LGTM!

The contextual logging setup correctly derives the logger from context and propagates context to child goroutines.


50-75: LGTM!

Contextual logging is correctly implemented with proper error handling pattern (logger.Error(err, message, keyvals...)).

pkg/services/resource.go (5)

5-5: LGTM! klog import added.

The import of k8s.io/klog/v2 aligns with the PR objective to migrate to contextual logging with klog.


162-163: LGTM! Contextual logger properly initialized.

The logger is correctly derived from context and enriched with resourceID for structured logging. klog.FromContext safely falls back to the global logger if the context lacks one.


184-185: Verify the log level downgrade from Warn to Info.

The previous implementation used log.Warnf, but this now uses logger.Info. Stale resource events are expected under eventual consistency, so Info-level may be appropriate. However, confirm this severity change is intentional.


199-200: LGTM! Logging migration to klog is correct.

The migration correctly maps log.Infof to logger.Info and log.Debugf to logger.V(4).Info. Using V(4) for verbose event payload logging is appropriate and follows klog conventions.


225-226: Verify the log level downgrade from Warn to Info.

Similar to lines 184-185, the previous implementation used log.Warnf, but this now uses logger.Info. Stale sequence ID events are expected under eventual consistency. Confirm this severity change is intentional.

pkg/db/context.go (3)

5-6: LGTM!

The new imports are appropriate for klog contextual logging.


25-46: LGTM!

The contextual logger integration in the Resolve function is correctly implemented, with proper error handling and informative log messages.


57-57: Verify error sanitization in MarkForRollback calls.

The error parameter is logged directly as a structured field without sanitization. Industry best practices recommend wrapping raw errors with contextual, non-sensitive messages rather than logging them directly, as lower-layer errors may contain sensitive information (PII, internal system details, or user input). Confirm that errors passed to this function are properly sanitized or wrapped before logging, or implement error wrapping/redaction at this logging point.

test/integration/integration_test.go (1)

13-21: TestMain klog usage and DB cleanup look good

Startup logging via klog.Infof and calling CleanDB() before os.Exit integrate cleanly with the new logging approach and improve integration test teardown.

cmd/maestro/server/server.go (1)

16-21: Server interface and check now properly carry context for logging

Updating Server to Start(ctx) / Serve(ctx, listener) and threading ctx into check(ctx, err, msg) centralizes fatal error handling with a context‑derived klog logger while still skipping http.ErrServerClosed. This keeps Sentry reporting and exit semantics intact and enables richer, per‑request/per‑server startup logs where a real context is available.

Also applies to: 30-38

cmd/maestro/server/controllers.go (3)

13-15: Context-aware constructor pattern looks good.

The constructor now properly accepts a context and extracts a logger from it using klog.FromContext(ctx). This aligns well with the broader migration to contextual logging.


26-26: Correct use of klog structured logging.

Using logger.V(4).Info("Message") is the proper pattern for verbose/debug-level logging with klog.


59-72: Per-context logger with named scope is well-implemented.

The pattern of creating a named logger (WithName("maestro-controllers")) and injecting it back into the context ensures consistent log prefixing for all downstream operations. The lifecycle logging and goroutine spawning are appropriate.

cmd/maestro/server/healthcheck_server.go (4)

50-53: Context-aware logging with instance identifier is well-implemented.

The logger is enriched with instanceID for traceability and properly injected into the context for downstream use.


71-78: Correct structured logging format for TLS/non-TLS startup.

The logging now properly uses key-value pairs ("port", env().Config.HealthCheck.BindPort) instead of printf-style formatting.


87-96: Proper context-based logging in pulse method.

The logger is correctly derived from context and used for error logging with structured format.


160-172: Structured logging for batch operations is correct.

The error logging now properly uses key-value pairs for instance IDs without printf-style format specifiers.

cmd/maestro/servecmd/cmd.go (4)

52-56: Root logger and context setup is well-structured.

Creating a named root logger ("maestro-server") and injecting it into the context provides good traceability for all downstream operations.


77-78: Correct structured error logging for unsupported subscription type.

The error logging now properly uses a message string with key-value pairs, addressing the previous review feedback.


113-117: Tracing shutdown error handling is now correct.

The shutdown error is properly captured in shutdownErr and logged, fixing the previous bug where the wrong error variable was being logged.


84-88: Context properly propagated to server constructors.

The updated constructor calls correctly pass the context to NewAPIServer, NewControllersServer, and other components.

cmd/maestro/server/api_server.go (2)

40-43: Context-aware API server constructor is well-implemented.

The constructor properly accepts and propagates context to route construction.


148-170: Correct structured logging in Serve method.

The logging properly uses key-value pairs for the port and the context-derived logger pattern is correct.

test/helper.go (5)

158-160: Test helper correctly updated for context-aware GRPCBroker constructor.

The NewGRPCBroker call now properly passes the context as required by the updated signature.


198-208: Context-derived logging in test API server startup.

The test helper correctly uses klog.FromContext(helper.Ctx) and passes context to the updated NewAPIServer constructor.


235-242: Health check server test helper updated correctly.

The startup logging now uses the context-derived logger pattern consistent with other server startups.


376-378: Typo fix confirmed: "Resetting" is now spelled correctly.

The log message now reads "Resetting testing environment" as expected.


517-532: Structured error logging in CleanDB.

The error logging correctly uses key-value pairs ("table", table) for structured logging.

pkg/controllers/framework.go (4)

88-104: LGTM!

The context propagation through Run is well-structured. The logger is correctly derived from context, and the context is properly passed to wait.JitterUntilWithContext and wait.UntilWithContext for cancellation support.


118-134: LGTM!

The context enrichment pattern is well-implemented. The logger is enriched with EventID for structured logging, and the same ID is stored in the context for handlers to access via context.Value(). This dual approach enables both contextual logging and programmatic access to the event ID.


204-230: LGTM!

The local logger enrichment with key for error logging is appropriate. The handleEvent method correctly creates its own enriched context with EventID, so there's no need to propagate the key-enriched logger.


232-258: LGTM!

The syncEvents method correctly propagates context to database operations and uses the context-derived logger consistently.

cmd/maestro/server/grpc_server.go (4)

48-54: Context usage in constructor: verify intent.

The ctx parameter is used during construction for logging configuration messages. Ensure this is the intended design, as typically constructors don't require context (context is for request/operation lifecycle). The Start() method correctly accepts its own context for runtime operations.

If the intent is to capture startup configuration logs with the application's root context, this is acceptable. Just ensure the constructor's context isn't expected to carry request-scoped values.


149-159: LGTM!

The Start method correctly uses the runtime context for logging. The context-derived logger provides proper structured logging during server startup.


167-194: LGTM!

Good use of verbosity levels with V(4) for detailed event logging while keeping standard logs concise. The logger is correctly derived from the gRPC request context.


266-311: LGTM!

The subscription flow correctly derives the logger from the subscription context and uses it consistently throughout the event sending goroutine and registration callback. The verbose logging with V(4) for full event details is appropriate.

pkg/controllers/status_controller.go (2)

51-66: LGTM!

The Run method follows the same correct pattern as KindControllerManager.Run(), with proper context propagation to background workers.


104-106: LGTM!

The context enrichment pattern with StatusEventID is consistent with the handleEvent pattern in framework.go.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
pkg/dispatcher/noop_dispatcher.go (1)

52-74: Fix wording in resync error log message

The log message "failed to resync resources status for consumers" is slightly off grammatically; consider "failed to resync resource status for consumers" (or "resource statuses").

-            if err := d.sourceClient.Resync(ctx, consumerIDs); err != nil {
-                logger.Error(err, "failed to resync resources status for consumers", "consumers", consumerIDs)
-            }
+            if err := d.sourceClient.Resync(ctx, consumerIDs); err != nil {
+                logger.Error(err, "failed to resync resource status for consumers", "consumers", consumerIDs)
+            }
cmd/maestro/server/routes.go (1)

31-32: Mock auth middleware still unconditionally applied.

This was flagged in a past review. The current code still unconditionally uses auth.AuthMiddlewareMock{} and auth.NewAuthzMiddlewareMock() without config-gated creation based on EnableJWT/EnableAuthz flags. If this is intentional for this PR (deferring to a separate change), please confirm.

🧹 Nitpick comments (20)
pkg/auth/helpers.go (1)

38-40: Consider logging if JSON marshaling fails.

If json.Marshal fails, the response body will be empty while the status code indicates an error, potentially confusing clients. While this is unlikely for well-defined error types, defensive logging would aid debugging.

 	if payload != nil {
-		response, _ := json.Marshal(payload)
+		response, err := json.Marshal(payload)
+		if err != nil {
+			klog.ErrorS(err, "failed to marshal response payload")
+			return
+		}
 		_, _ = w.Write(response)
 	}
pkg/dispatcher/noop_dispatcher.go (1)

79-118: Consider threading context/logger into onInstanceDown instead of using context.TODO()

onInstanceUpdate now has a klog.Logger, but onInstanceDown still uses context.TODO() and only returns fmt.Errorf without contextual logging. If you want full consistency with the PR’s contextual-logging goal, consider passing ctx and/or logger from the call site into onInstanceDown so it can both respect cancellation and emit structured logs instead of only formatted errors. Not blocking, but would make this path align with the rest of the file.

pkg/services/resource.go (2)

184-185: Consider debug-level logging for expected stale-update paths

Both stale paths (version mismatch and sequence ID comparison) are part of normal eventual-consistency behavior and might be hit frequently under load. Logging them at default Info level could be noisy in production.

You might want to drop them to a verbose level, e.g.:

-logger.Info("Updating status for stale resource; disregard it",
-    "foundVersion", found.Version, "wantVersion", resource.Version)
+logger.V(2).Info("Updating status for stale resource; disregard it",
+    "foundVersion", found.Version, "wantVersion", resource.Version)

-logger.Info("Updating status for stale resource; disregard it",
-    "foundSequenceID", foundSequenceID, "wantSequenceID", sequenceID)
+logger.V(2).Info("Updating status for stale resource; disregard it",
+    "foundSequenceID", foundSequenceID, "wantSequenceID", sequenceID)

(or whatever verbosity level matches your logging policy).

Please confirm that your current klog verbosity configuration won’t result in excessive log volume from these paths in high-churn clusters.

Also applies to: 225-226


199-200: Tighten up the status-update logs to avoid duplicate messages

You currently log:

  • An Info message: "Updating resource status".
  • A V(4) message with the same text plus the event payload.

To reduce noise and make logs more expressive, you could slightly differentiate or consolidate them, for example:

-logger.Info("Updating resource status")
-logger.V(4).Info("Updating resource status", "event", resourceStatusEvent)
+logger.Info("Updating resource status")
+logger.V(4).Info("Updating resource status event detail", "event", resourceStatusEvent)

or, if the detailed log is sufficient for your needs, just keep the V(4) call and drop the plain Info.

Verify that your chosen combination (Info + V(4) or V(4) only) matches how SREs actually query these logs in production.

pkg/db/context.go (1)

29-29: Previous review concern addressed; optional consistency improvement.

The past review comment about the empty message string at line 53 has been resolved. Both lines now correctly follow klog's Error(err, msg) pattern.

However, there's a minor inconsistency: line 29 creates errors.New("missing transaction") while line 53 creates errors.New("could not retrieve transaction from context") for the same condition. Consider using the same error message for consistency.

Optional diff for consistency:

-		logger.Error(errors.New("missing transaction"), "Could not retrieve transaction from context")
+		logger.Error(errors.New("could not retrieve transaction from context"), "Could not retrieve transaction from context")

Also applies to: 53-53

cmd/maestro/environments/framework.go (1)

3-7: Logging updates improve observability without changing control flow

Initialization and client/Sentry setup now emit clearer info and debug-level logs (including when mock implementations are used) while retaining the existing log.Fatalf behavior on unrecoverable errors; this is a safe, incremental improvement. If you later thread a context.Context through Env.Initialize and LoadClients, you could switch these to per-context loggers for even better correlation, but that’s optional.

Also applies to: 73-79, 157-167, 169-193, 195-215, 220-234

cmd/maestro/server/metrics_server.go (1)

44-67: Context-aware startup and corrected metrics port logging

Start now takes a context.Context, derives a logger from it, logs using the Metrics bind port, and passes ctx into check, which is exactly what you want for contextual logging and termination handling. The no-op Serve is acceptable to satisfy the Server interface; if that interface is ever relaxed, you could drop it to avoid confusion.

pkg/services/generic.go (1)

7-8: Additional list edge-case logging is context-aware and safe

loadList now derives a logger from the operation context and emits info-level messages for oversized, negative, and zero-size queries, without changing any of the paging or DB behavior; this is a safe observability improvement. If you want richer diagnostics later, you could add key/value fields (for example, requested size and resource type) to those log entries.

Also applies to: 220-241

test/mocks/workserver/main.go (1)

10-10: Import ordering: external package mixed with stdlib imports.

The k8s.io/klog/v2 import is placed within the standard library import block. Go convention groups imports into: stdlib, external packages, and internal packages.

 import (
 	"context"
 	"crypto/tls"
 	"encoding/json"
 	"flag"
 	"fmt"
 	"io"
-	"k8s.io/klog/v2"
 	"net/http"
 	"os"
 	"os/signal"
 	"sync"
 	"syscall"
 	"time"
 
 	"github.com/gorilla/mux"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials/insecure"
+	"k8s.io/klog/v2"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
cmd/maestro/server/logging/formatter_json.go (1)

6-6: Import ordering: external package mixed with stdlib imports.

Same as the other file - k8s.io/klog/v2 should be grouped with external packages, not within stdlib imports.

 import (
 	"encoding/json"
 	"io"
-	"k8s.io/klog/v2"
 	"net/http"
+
+	"k8s.io/klog/v2"
 )
cmd/maestro/server/auth_interceptor.go (1)

6-6: Import ordering: external package mixed with stdlib imports.

k8s.io/klog/v2 should be grouped with external packages.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"strings"
 
 	"github.com/openshift-online/maestro/pkg/client/grpcauthorizer"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/metadata"
 	"google.golang.org/grpc/peer"
 	"google.golang.org/grpc/status"
+	"k8s.io/klog/v2"
 )
cmd/maestro/server/routes.go (1)

102-103: TODO: Operation ID not yet set on logger.

The TODO indicates the operation ID should be attached to the logger for request correlation. Consider tracking this as a follow-up task.

Would you like me to open an issue to track implementing the operation ID attachment to the per-request logger?

pkg/event/event.go (1)

5-5: Import ordering: external package mixed with stdlib imports.

k8s.io/klog/v2 should be grouped with external packages after the stdlib imports.

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"sync"
 
 	"github.com/google/uuid"
+	"k8s.io/klog/v2"
+
 	"github.com/openshift-online/maestro/pkg/api"
 )
cmd/maestro/server/controllers.go (1)

5-5: Import ordering: external package mixed with stdlib imports.

k8s.io/klog/v2 should be in the external package group.

 import (
 	"context"
-	"k8s.io/klog/v2"
 
 	"github.com/openshift-online/maestro/pkg/api"
 	"github.com/openshift-online/maestro/pkg/controllers"
 	"github.com/openshift-online/maestro/pkg/dao"
 	"github.com/openshift-online/maestro/pkg/db"
+	"k8s.io/klog/v2"
 )
cmd/maestro/server/grpc_broker.go (1)

3-11: Import ordering: stdlib imports should be grouped together.

The k8s.io/klog/v2 import is placed between standard library imports, which breaks the conventional Go import grouping (stdlib, then external packages). Consider moving it to the external imports section.

 import (
 	"context"
 	"crypto/tls"
 	"crypto/x509"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net"
 	"os"
 	"time"

 	ce "github.com/cloudevents/sdk-go/v2"
 	cetypes "github.com/cloudevents/sdk-go/v2/types"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/keepalive"
+	"k8s.io/klog/v2"
 	kubeerrors "k8s.io/apimachinery/pkg/api/errors"
cmd/maestro/server/api_server.go (1)

3-10: Import ordering: stdlib imports should be grouped together.

Same as in grpc_broker.go, the k8s.io/klog/v2 import is misplaced among standard library imports.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net"
 	"net/http"
 	"time"

 	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
+	"k8s.io/klog/v2"
test/helper.go (1)

3-16: Import ordering: stdlib imports should be grouped together.

The k8s.io/klog/v2 import at line 8 is placed between standard library imports. Consider grouping all stdlib imports together.

 import (
 	"context"
 	"crypto/rsa"
 	"encoding/json"
 	"fmt"
-	"k8s.io/klog/v2"
 	"log"
 	"os"
 	"path/filepath"
 	"strings"
 	"sync"
 	"testing"
 	"time"

 	"github.com/openshift-online/maestro/pkg/client/cloudevents"
+	"k8s.io/klog/v2"
cmd/maestro/servecmd/cmd.go (1)

3-12: Import ordering: stdlib imports should be grouped together.

The k8s.io/klog/v2 import is placed between stdlib imports (errors and log).

 import (
 	"context"
 	"errors"
-	"k8s.io/klog/v2"
 	"log"
 	"os"
 	"os/signal"
 	"syscall"
 	"time"

 	"github.com/spf13/cobra"
+	"k8s.io/klog/v2"
cmd/maestro/server/healthcheck_server.go (2)

57-60: Heartbeat/check interval math is a bit opaque and can misbehave for small intervals

Using expressions like time.Duration(s.heartbeatInterval/3*int(time.Second)) and time.Duration(int(-3*time.Second)*s.heartbeatInterval) works numerically but is hard to read and has edge cases (e.g., heartbeatInterval < 3 makes heartbeatInterval/3 zero, so checkInstances would run in a tight loop). It also disagrees with the comment about “three check intervals” (current threshold is 3 * heartbeatInterval seconds, not 3 * checkInterval).

Consider refactoring to derive durations directly from time.Duration(s.heartbeatInterval) * time.Second and a named checkInterval, and use those consistently for both the scheduler period and the active/inactive thresholds.

Also applies to: 154-157


176-203: healthCheckHandler now logs per-request context; consider adding Content-Type

Using klog.FromContext(r.Context()).WithValues("instanceID", s.instanceID) and logging all DAO/response-write errors via logger.Error is a solid improvement in observability. As a small follow-up, you might set Content-Type: application/json on responses to match the JSON bodies.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 42f5f17 and 180dfbe.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (49)
  • cmd/maestro/agent/cmd.go (1 hunks)
  • cmd/maestro/common/otlp_sdk.go (4 hunks)
  • cmd/maestro/environments/framework.go (6 hunks)
  • cmd/maestro/main.go (1 hunks)
  • cmd/maestro/migrate/cmd.go (2 hunks)
  • cmd/maestro/servecmd/cmd.go (4 hunks)
  • cmd/maestro/server/api_server.go (6 hunks)
  • cmd/maestro/server/auth_interceptor.go (3 hunks)
  • cmd/maestro/server/controllers.go (3 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • cmd/maestro/server/healthcheck_server.go (7 hunks)
  • cmd/maestro/server/logging/formatter_json.go (3 hunks)
  • cmd/maestro/server/logging/logging.go (0 hunks)
  • cmd/maestro/server/logging/writer.go (3 hunks)
  • cmd/maestro/server/metrics_server.go (2 hunks)
  • cmd/maestro/server/routes.go (4 hunks)
  • cmd/maestro/server/server.go (3 hunks)
  • go.mod (3 hunks)
  • pkg/api/error.go (5 hunks)
  • pkg/api/metadata.go (4 hunks)
  • pkg/auth/helpers.go (1 hunks)
  • pkg/client/cloudevents/source_client.go (4 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
  • pkg/controllers/event_filter.go (3 hunks)
  • pkg/controllers/framework.go (9 hunks)
  • pkg/controllers/framework_test.go (2 hunks)
  • pkg/controllers/status_controller.go (7 hunks)
  • pkg/db/advisory_locks.go (8 hunks)
  • pkg/db/context.go (2 hunks)
  • pkg/db/db_session/default.go (4 hunks)
  • pkg/db/db_session/test.go (2 hunks)
  • pkg/db/migrations.go (2 hunks)
  • pkg/db/transaction_middleware.go (2 hunks)
  • pkg/dispatcher/hash_dispatcher.go (8 hunks)
  • pkg/dispatcher/noop_dispatcher.go (4 hunks)
  • pkg/errors/errors.go (0 hunks)
  • pkg/event/event.go (5 hunks)
  • pkg/handlers/framework.go (2 hunks)
  • pkg/logger/logger.go (0 hunks)
  • pkg/logger/zap.go (0 hunks)
  • pkg/services/generic.go (3 hunks)
  • pkg/services/resource.go (5 hunks)
  • test/e2e/pkg/suite_test.go (3 hunks)
  • test/helper.go (10 hunks)
  • test/integration/integration_test.go (1 hunks)
  • test/mocks/workserver/main.go (5 hunks)
  • test/upgrade/pkg/suite_test.go (2 hunks)
💤 Files with no reviewable changes (4)
  • pkg/errors/errors.go
  • pkg/logger/zap.go
  • pkg/logger/logger.go
  • cmd/maestro/server/logging/logging.go
🚧 Files skipped from review as they are similar to previous changes (16)
  • test/e2e/pkg/suite_test.go
  • pkg/db/db_session/default.go
  • pkg/db/db_session/test.go
  • pkg/db/migrations.go
  • pkg/client/cloudevents/source_client.go
  • cmd/maestro/server/server.go
  • pkg/db/transaction_middleware.go
  • cmd/maestro/server/event_server.go
  • pkg/controllers/event_filter.go
  • test/upgrade/pkg/suite_test.go
  • pkg/api/error.go
  • pkg/controllers/framework_test.go
  • cmd/maestro/migrate/cmd.go
  • pkg/handlers/framework.go
  • pkg/dispatcher/hash_dispatcher.go
  • test/integration/integration_test.go
🧰 Additional context used
🧬 Code graph analysis (10)
pkg/db/advisory_locks.go (1)
pkg/db/metrics_collector.go (2)
  • UpdateAdvisoryUnlockCountMetric (92-98)
  • UpdateAdvisoryLockDurationMetric (100-107)
cmd/maestro/server/controllers.go (5)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/controllers/event_filter.go (1)
  • EventFilter (18-25)
pkg/controllers/framework.go (1)
  • KindControllerManager (52-57)
cmd/maestro/environments/types.go (1)
  • Database (31-33)
pkg/db/session.go (1)
  • SessionFactory (13-21)
cmd/maestro/environments/framework.go (3)
cmd/maestro/environments/types.go (1)
  • Clients (50-54)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
pkg/client/grpcauthorizer/mock_authorizer.go (1)
  • NewMockGRPCAuthorizer (9-11)
cmd/maestro/server/healthcheck_server.go (4)
cmd/maestro/server/server.go (1)
  • Server (16-21)
pkg/client/ocm/client.go (1)
  • Config (17-24)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/db/advisory_locks.go (1)
  • Instances (25-25)
pkg/controllers/status_controller.go (2)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
pkg/auth/helpers.go (2)
pkg/errors/errors.go (2)
  • ServiceErrorCode (61-61)
  • New (102-116)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
cmd/maestro/server/grpc_broker.go (3)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/config/config.go (1)
  • ReadFile (110-135)
cmd/maestro/server/api_server.go (2)
cmd/maestro/server/server.go (1)
  • Server (16-21)
cmd/maestro/server/grpc_server.go (2)
  • NewGRPCServer (48-146)
  • GRPCServer (36-45)
test/helper.go (3)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
cmd/maestro/server/grpc_broker.go (1)
  • NewGRPCBroker (128-212)
cmd/maestro/server/api_server.go (1)
  • NewAPIServer (39-143)
cmd/maestro/server/logging/writer.go (1)
cmd/maestro/server/logging/formatter.go (1)
  • LogFormatter (5-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: e2e-broadcast-subscription
  • GitHub Check: e2e
  • GitHub Check: e2e-with-istio
  • GitHub Check: migration
  • GitHub Check: e2e-grpc-broker
🔇 Additional comments (55)
pkg/client/grpcauthorizer/kube_authorizer.go (2)

3-11: New logging import is correctly wired

The added k8s.io/klog/v2 import is used by AccessReview and there are no unused or conflicting imports; this part looks good as-is.


46-54: Context-derived structured logging looks correct; ensure callers attach a logger to ctx

Using klog.FromContext(ctx).WithValues(...) with distinct keys (action, resourceType, resource, user, groups) and logging at V(4) cleanly replaces the old debug log and avoids the previous duplicate-key issue. To get the full benefit, double-check that all call sites pass a context that already has a klog logger attached (e.g., via klog.NewContext in your gRPC handlers), otherwise these entries will fall back to the background logger and lose per-request correlation fields.

pkg/auth/helpers.go (2)

6-10: LGTM!

The import changes correctly introduce klog/v2 for contextual logging and rename the logger package to logtracing to avoid naming conflicts while retaining access to GetOperationID.


13-32: LGTM!

The function correctly uses klog's contextual logging pattern:

  • klog.FromContext(ctx) obtains the context-bound logger
  • Client errors (4xx) are logged at Info level
  • Server errors are logged at Error level with the error object as first parameter

The structured logging with "error", "code", and "op-id" keys provides good observability.

pkg/dispatcher/noop_dispatcher.go (2)

3-12: klog import matches the new contextual logging pattern

Importing k8s.io/klog/v2 here aligns with the new logger usage below; nothing else needed in this section.


35-44: Context-derived logger usage in Start looks good

Deriving the logger once from ctx and capturing it in the NewListener callback keeps logging contextual and avoids repeated lookups; this wiring looks correct.

cmd/maestro/server/logging/writer.go (3)

4-9: LGTM: Context-bound logging properly implemented.

The migration to klog.FromContext(r.Context()) is a solid improvement. Deriving the logger from the request context enables proper correlation and structured logging throughout the request lifecycle. klog.FromContext safely returns the global logger if the context doesn't contain one, so this is robust.


18-18: LGTM: Logger field properly encapsulated.

The logger field is correctly initialized in the constructor and remains immutable thereafter, ensuring thread-safe access during request handling.


31-38: LGTM: Log routing correctly implemented.

The verbosity level V(4) is appropriate for detailed request/response logging, and the error case properly uses Error() with contextual messaging. Both paths now route through the context-bound logger as intended.

pkg/services/resource.go (2)

5-5: klog/v2 import fits the contextual logging migration

The new k8s.io/klog/v2 import here is appropriate for the PR’s move to klog-based contextual logging; nothing else to change in this block.

Please double-check that module wiring and entrypoints initialize klog properly (flags/config) so these logs respect the desired verbosity in all environments.


162-162: Context-scoped logger with resourceID is a solid pattern

Using klog.FromContext(ctx).WithValues("resourceID", resource.ID) gives you per-call, per-resource scoping without changing the method signature; this is an idiomatic way to bind context data into logs.

Ensure all callers of UpdateStatus propagate a context that already carries the base klog logger; otherwise these calls will fall back to the global logger, which may or may not be what you want.

pkg/db/context.go (2)

5-6: LGTM! Contextual logging properly adopted.

The migration to klog's contextual logging is well-implemented. Using klog.FromContext(ctx) ensures that all log entries within these functions inherit context-specific metadata, which aligns with the broader PR objectives.

Also applies to: 26-26, 50-50


57-57: LGTM! Excellent use of structured logging.

The structured logging with key-value pairs ("error", err) is a best practice that enhances observability and makes logs easier to query and analyze.

pkg/db/advisory_locks.go (2)

155-187: Unlock logging and success-only OK/duration metrics look correct; consider confirming desired failure metrics behavior

The Unlock changes are well-implemented:

  • Contextual logger with WithValues("owner", uuid) and the V(4).Info("Caller not lock owner") debug line maintains previous behavior while improving queryability.
  • Error path logs via logger.Error() and increments UpdateAdvisoryUnlockCountMetric(lockType, "ERROR") appropriately.
  • Success path increments UpdateAdvisoryUnlockCountMetric(lockType, "OK") and UpdateAdvisoryLockDurationMetric(lockType, "OK", lock.startTime), making metrics more accurate for successful unlocks.

If failure duration tracking is used elsewhere in the codebase or needed for observability, consider whether a UpdateAdvisoryLockDurationMetric(lockType, "ERROR", lock.startTime) call should also be added to the error branch.


8-8: Contextual klog migration in lock constructors looks good; minor logging pattern concern

Using klog.FromContext(ctx) and switching error paths in NewAdvisoryLock / NewNonBlockingLock to logger.Error(...) is consistent with klog's contextual logging and the PR's intent. Behavior and metrics updates in these paths remain unchanged.

One small optional nit: in both constructors you format err into errMsg and also pass err as the first argument to logger.Error. Per the logr API, msg should be a short, simple description without formatting, and the error is already surfaced as structured data via the err parameter. This pattern leads to duplicated error information in logs. In a follow-up, consider either:

  • Pass a short message and omit the formatted error text from errMsg, or
  • Use structured keysAndValues pairs for additional context instead of embedding them in the message.

This is purely a log clarity concern and safe to defer.

Also applies to: 91-112, 114-136

pkg/api/metadata.go (1)

34-62: Per-request context-derived logging on write errors looks good

Both SendAPI and SendAPIV1 now derive a logger from the request context and log failures from w.Write with the request path while still capturing to Sentry; this is consistent with the new contextual logging approach and preserves existing behavior.

Also applies to: 69-99

cmd/maestro/main.go (1)

5-13: Main entrypoint error handling remains clear and simple

Switching to the standard library’s log.Fatalf for command execution errors keeps behavior straightforward and decouples main from the removed custom logger, with no functional regressions.

Also applies to: 49-51

cmd/maestro/common/otlp_sdk.go (1)

3-6: Tracer installation now uses an injected logger cleanly

InstallOpenTelemetryTracer now takes an abstract logger and uses it only for a startup info log and error-handler logging; the exporter, resource, tracer provider, and shutdown behavior remain the same, so behavior is preserved apart from the logging backend.

Also applies to: 26-32, 59-61

go.mod (1)

93-95: Dependency metadata changes align with logger/config refactor

Marking fsnotify, zap, and genproto as indirect dependencies is consistent with dropping direct usage in this repo while still satisfying transitive requirements; this looks correct. Please just ensure your usual go mod tidy / CI dependency checks pass so the module graph stays clean.

Also applies to: 173-173, 186-186

cmd/maestro/agent/cmd.go (1)

66-76: Comment clarification is correct

The updated comment for addFlags accurately describes that it overrides cluster name and leader election flags, with no code changes required.

test/mocks/workserver/main.go (1)

155-159: LGTM - klog migration for mock server.

The logging migration from the custom logger to klog is correctly implemented. Using non-contextual klog.Infof/klog.Fatalf/klog.Errorf is appropriate for this standalone mock server used in testing.

Also applies to: 172-172, 269-269, 278-280, 286-286

cmd/maestro/server/logging/formatter_json.go (1)

24-24: LGTM - debug gate migrated to klog verbosity.

The switch from logger.GetLoggerLevel() == "debug" to klog.V(4).Enabled() correctly gates debug information (headers, body) behind klog's verbosity level 4, which aligns with the k8s ecosystem convention.

Also applies to: 38-38

cmd/maestro/server/auth_interceptor.go (1)

100-114: LGTM - contextual logging in auth interceptors.

The per-context logger pattern using klog.FromContext(ctx) is correctly implemented in both unary and stream interceptors. The error logging follows klog conventions with logger.Error(err, message).

Also applies to: 160-174

cmd/maestro/server/routes.go (1)

96-107: Logger middleware correctly propagates context-bound logger.

The middleware properly extracts the logger from the outer context and injects it into each request's context using klog.NewContext.

pkg/event/event.go (1)

41-57: LGTM - contextual logging in EventBroadcaster.

The migration to per-context logging is well implemented:

  • Register and Unregister now accept context and use klog.FromContext(ctx).
  • Structured logging with key-value pairs ("id", "source", "resourceID") follows klog conventions.
  • logger.WithValues("id", id) correctly attaches persistent context to the logger for the Unregister operation.

Also applies to: 60-74, 82-106

cmd/maestro/server/controllers.go (2)

13-26: LGTM - context propagation in NewControllersServer.

The constructor correctly accepts context and retrieves a logger for conditional debug logging when the message broker is enabled.


58-72: LGTM - named logger and context propagation in Start.

The implementation correctly:

  • Creates a named logger with WithName("maestro-controllers") for component identification.
  • Injects the logger into the context with klog.NewContext(ctx, logger).
  • Uses the updated Run(ctx) signature for both KindControllerManager and StatusController.
cmd/maestro/server/grpc_broker.go (3)

128-212: Context-aware initialization looks good.

The NewGRPCBroker function now properly accepts a context, derives a logger from it, and uses check(ctx, ...) for fatal error paths. The TLS configuration and logging are correctly migrated to context-aware patterns.


215-232: Start method correctly migrated to context-aware logging.

The error handling now uses check(ctx, err, msg) as suggested in the past review, ensuring consistent error reporting through Sentry. The shutdown logging also uses the context-derived logger.


269-298: PredicateEvent logging migration is correct.

The debug logging for resource deletion reconciliation is appropriately set to verbosity level 4.

cmd/maestro/server/api_server.go (2)

39-143: Context propagation in NewAPIServer is well implemented.

The context is correctly passed through to route construction, authentication handler creation, and GRPC server initialization. Error handling consistently uses check(ctx, ...).


179-198: Critical issue from past review has been addressed.

The os.Exit(1) that was bypassing the deferred s.grpcServer.Stop() has been replaced with return, allowing proper cleanup of the gRPC server when the listener fails to start.

test/helper.go (3)

147-180: Event server and helper initialization correctly migrated.

The NewGRPCBroker now receives the context, and the helper's start methods internally use helper.Ctx for consistency.


198-265: Test helper start methods consistently migrated to context-aware logging.

All start/stop methods use klog.FromContext(helper.Ctx) and log at verbosity level 4, which is appropriate for test infrastructure messages.


376-396: Reset method correctly updated.

The typo "Reseting" mentioned in past reviews has been fixed to "Resetting".

cmd/maestro/servecmd/cmd.go (4)

52-56: Logger and context initialization is well structured.

The named logger "maestro-server" and proper context setup establish the foundation for context-aware logging throughout the application.


62-82: Event server setup with proper error logging.

The error logging for unsupported subscription types has been corrected to follow the proper logger.Error(err, msg, keysAndValues...) pattern as suggested in past reviews.


84-97: Server construction and tracing setup correctly updated.

All server constructors now receive the context. The OpenTelemetry error handling properly logs the actual installation error.


113-117: Tracing shutdown error handling corrected.

The past review issue about logging the wrong error variable has been addressed. The code now correctly captures and logs shutdownErr from the tracing shutdown call.

cmd/maestro/server/grpc_server.go (6)

48-54: Context-aware constructor is well implemented.

The NewGRPCServer function properly accepts a context and derives the logger for use in TLS configuration logging.


74-146: TLS configuration logging and error handling is consistent.

The error paths use check(ctx, ...) and the informational logging correctly indicates whether the server is using mTLS, TLS, or no TLS.


149-159: Start method correctly migrated to context-aware logging.

The logger is properly derived from context and used for both informational and error messages.


167-204: Publish method logging is well structured.

Context-based logging with appropriate verbosity levels: standard log for event context, V(4) for full event details.


243-361: Subscribe method comprehensively migrated to context-aware logging.

The subscription lifecycle (registration, event sending, heartbeats, errors, unregistration) is well instrumented with context-derived logging.


443-488: Resync status request handling correctly uses context-aware logging.

The logger is properly derived from context for logging edge cases during resync operations.

pkg/controllers/framework.go (4)

88-104: Run(ctx) wiring and shutdown behavior look sound

Run now cleanly uses wait.JitterUntilWithContext/wait.UntilWithContext and blocks on ctx.Done() while deferring eventsQueue.ShutDown(), so worker and sync goroutines respect cancellation without changing controller semantics.


118-194: Event-scoped logger/context usage is consistent

Deriving an event-scoped logger via WithValues(EventID, id) and threading reqContext through eventFilter, DAO calls, and handler funcs keeps logs correlated with the event while preserving existing metrics and reconciliation behavior. No functional issues spotted here.


196-230: Worker loop and requeue behavior preserved under ctx

runWorker and processNextEvent correctly take ctx, use eventsQueue.Get()/Done()/Forget()/AddRateLimited, and log failures via a key-scoped logger, so queue semantics and backoff behavior remain intact while gaining contextual logging.


232-258: syncEvents(ctx) correctly adopts contextual logging

syncEvents now uses ctx for DB calls and a context-derived logger for purge/sync operations; periodic behavior, error paths, and metrics remain unchanged.

cmd/maestro/server/healthcheck_server.go (3)

28-49: Constructor and Start(ctx) integration with contextual logging are reasonable

Accepting ctx in NewHealthCheckServer and registering logger middleware there, then deriving an instance-scoped logger in Start via WithValues("instanceID", s.instanceID) and klog.NewContext, keeps startup and background goroutines tied to the provided context without changing server behavior.

Also applies to: 51-55


88-124: pulse(ctx) logging and lock/DAO handling look correct

The advisory lock is acquired with ctx and always unlocked via defer; klog is used for structured errors and the new-instance path uses V(4).Info rather than ad‑hoc debug logging, while the create/get/update flows are otherwise unchanged.


126-174: checkInstances(ctx) adopts contextual logging cleanly

Switching to a context-derived logger, keeping the non-blocking advisory lock semantics, and using structured fields for batch mark-ready/mark-unready operations all look good. Aside from the timing arithmetic noted separately, instance liveness classification and DAO calls are unchanged.

pkg/controllers/status_controller.go (3)

51-66: Status controller run loop and error requeue logic remain intact with ctx

Run(ctx) now uses context-aware wait helpers and blocks on ctx.Done(), while runWorker/processNextEvent drive the queue with the same backoff and AddRateLimited behavior, only adding a context-derived logger for failures. Semantics look preserved.

Also applies to: 68-73, 76-99


104-145: Per-status-event logger/context is wired correctly

handleStatusEvent now derives a logger with StatusEventID, wraps it into reqContext via klog.NewContext, and threads that through the service and handler calls. Logging “no handler functions” as an Info with statusEventType plus existing metrics gives good visibility without altering behavior.


161-190: syncStatusEvents(ctx) context/logging changes look good

Using ctx for DAO calls and klog.FromContext(ctx) for structured errors and the readyInstanceIDs debug log preserves the existing batching/deletion and metrics logic while making operations observable per-context.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/services/resource.go (1)

86-93: Bug: wrong error variable used when event creation fails

On event creation failure, you’re returning an error derived from err (which is nil here) instead of eErr, so the real failure is lost and you may end up wrapping a nil error:

_, eErr := s.events.Create(...)
if eErr != nil {
    return nil, handleCreateError("Resource", err) // uses wrong variable
}

This should use eErr:

-	if eErr != nil {
-		return nil, handleCreateError("Resource", err)
-	}
+	if eErr != nil {
+		return nil, handleCreateError("Resource", eErr)
+	}
♻️ Duplicate comments (2)
cmd/maestro/server/logging/formatter_json.go (1)

36-46: Same context-less klog usage as in FormatRequestLog.

The same consideration about using context-bound loggers applies here. See the review comment on lines 18-34.

cmd/maestro/server/logging/writer.go (1)

31-37: Tighten error message wording

The string "Unable to format request/response for log" is a bit awkward; the trailing “for log” doesn’t add information. Consider simplifying to something like:

-        writer.logger.Error(err, "Unable to format request/response for log")
+        writer.logger.Error(err, "Unable to format request/response log")

This reads more naturally while conveying the same meaning.

🧹 Nitpick comments (25)
cmd/maestro/agent/cmd.go (1)

66-76: Clarify addFlags comment to match the actual flags and options struct

The current comment says this overrides cluster name and leader election flags from agentOption, but the implementation uses commonOptions and also exposes QPS/burst flags. Consider tightening the wording so future readers don't get misled about where these flags come from or what they cover.

For example:

-// addFlags overrides cluster name and leader election flags from the agentOption
+// addFlags exposes consumer name, leader election, and API client QPS/burst flags derived from commonOptions
pkg/dispatcher/noop_dispatcher.go (1)

100-119: Consider threading context through onInstanceDown.

This function uses context.TODO() while callers like onInstanceUpdate have access to a context-derived logger. For consistency with the PR's contextual logging pattern, consider accepting ctx context.Context to enable proper context propagation and contextual logging.

-func (d *NoopDispatcher) onInstanceDown() error {
+func (d *NoopDispatcher) onInstanceDown(ctx context.Context) error {
 	// send resync request to each consumer
 	// TODO: optimize this to only resync resource status for necessary consumers
 	consumerIDs := []string{}
-	ctx := context.TODO()
 	consumers, err := d.consumerDao.All(ctx)

This would require updating the call site in onInstanceUpdate to pass through a context (which could be derived from the logger or added as a parameter).

cmd/maestro/migrate/cmd.go (1)

31-37: Consider adding context to fatal logs and verify exit‑code semantics

Using klog.Fatal(err) works, but it only prints the raw error and exits (with klog’s fatal exit code, typically 255). Two optional improvements:

  • Add context to the message so failures are clearer, e.g.:
    if err := dbConfig.ReadFiles(); err != nil {
        klog.Fatalf("failed to read DB config: %v", err)
    }
    and similarly for the migration failure.
  • If callers or scripts rely on a specific exit code (often 1), verify that switching to klog’s fatal behavior doesn’t break them. If you need a specific code, you could log with klog.Error/Errorf and then call os.Exit(code) explicitly.
pkg/auth/helpers.go (2)

13-32: Consider logging the internal service error code in addition to HTTP status

The structured logs currently include error, code (HTTP status), and op-id. For troubleshooting, it would be useful to also log the internal errors.ServiceErrorCode passed into handleError, so operators can correlate logs with specific error types more precisely.

For example:

 func handleError(ctx context.Context, w http.ResponseWriter, code errors.ServiceErrorCode, reason string) {
@@
-    logger.Info("client error",
-        "error", err.Error(),
-        "code", err.HttpCode,
-        "op-id", operationID,
-    )
+    logger.Info("client error",
+        "error", err.Error(),
+        "http_code", err.HttpCode,
+        "service_code", code,
+        "op-id", operationID,
+    )
 } else {
-    logger.Error(err, "server error",
-        "code", err.HttpCode,
-        "op-id", operationID,
-    )
+    logger.Error(err, "server error",
+        "http_code", err.HttpCode,
+        "service_code", code,
+        "op-id", operationID,
+    )
 }

This is optional but improves debuggability without changing behavior.


34-41: Handle JSON marshalling/write errors and consider adding charset to Content-Type

writeJSONResponse currently ignores both json.Marshal and w.Write errors, and sets Content-Type without a charset. For better observability and standards compliance:

  • At least log marshalling failures (and avoid writing a partial/empty body).
  • Optionally log write failures at a lower level (e.g., debug).
  • Consider application/json; charset=utf-8 as the content type.

Example:

 func writeJSONResponse(w http.ResponseWriter, code int, payload interface{}) {
-    w.Header().Set("Content-Type", "application/json")
+    w.Header().Set("Content-Type", "application/json; charset=utf-8")
     w.WriteHeader(code)

     if payload != nil {
-        response, _ := json.Marshal(payload)
-        _, _ = w.Write(response)
+        response, err := json.Marshal(payload)
+        if err != nil {
+            // best-effort: log and return; headers are already sent
+            // logger is not available here, so consider wiring one in if needed
+            return
+        }
+        _, _ = w.Write(response)
     }
 }

If you decide not to log here to avoid threading a logger, at least checking the marshal error and returning early would still be a robustness win.

pkg/db/context.go (1)

38-45: Consider logging successful commits for observability consistency.

Successful rollbacks are logged at line 38, but successful commits are silent. Logging both outcomes improves transaction lifecycle traceability.

Add logging after successful commit:

     if err := tx.Commit(); err != nil {
         // TODO:  what does the user see when this occurs? seems like they will get a false positive
         logger.Error(err, "Could not commit transaction")
         return
     }
+    logger.Info("Committed transaction")
 }
pkg/services/resource.go (1)

184-185: Consider lowering verbosity for expected stale-event noise

If stale status events are common in steady state, logging them at base Info could be noisy. Consider moving this to a verbose level, e.g.:

-	logger.Info("Updating status for stale resource; disregard it",
-		"foundVersion", found.Version, "wantVersion", resource.Version)
+	logger.V(2).Info("Updating status for stale resource; disregard it",
+		"foundVersion", found.Version, "wantVersion", resource.Version)

This preserves observability while keeping default logs cleaner.

pkg/db/migrations.go (1)

31-37: Consider moving from klog.Fatalf to context‑bound error logging

The direct klog.Fatalf call preserves the previous “log and exit” behavior, so this change is functionally fine. Given the PR’s push toward contextual logging, you might consider a follow‑up refactor:

  • Thread a context.Context into MigrateTo instead of using context.Background().
  • Use a context‑derived klog logger (e.g., klog.FromContext(ctx) with .Error(...)) and return/propagate the error instead of exiting the process, especially since this helper is “mainly for testing purposes”.

Not blocking for this PR, but it would align this path with the rest of the context‑aware logging work and make tests easier to control.

cmd/maestro/main.go (1)

18-21: Consider flushing klog on exit and cleaning up legacy logging constants

Two small follow‑ups:

  1. To ensure klog output is flushed on normal process exit, it’s typical to add a flush in main after klog.InitFlags:
-    // add klog flags
-    klog.InitFlags(nil)
+    // add klog flags
+    klog.InitFlags(nil)
+    defer klog.Flush()
  1. logConfigFile and varLogLevel no longer appear to be used in this file since the viper/fsnotify-based config was removed. Please double‑check if they’re referenced anywhere else in cmd/maestro; if not, it’s cleaner to drop them along with any remaining logging-config plumbing.

Also applies to: 29-31, 49-51

cmd/maestro/server/auth_interceptor.go (1)

3-16: Import ordering: klog should be grouped with external imports.

The k8s.io/klog/v2 import on line 6 is placed between fmt and strings (standard library). Per Go conventions, imports should be grouped: stdlib first, then external packages, then internal packages.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"strings"
 
+	"k8s.io/klog/v2"
+
 	"github.com/openshift-online/maestro/pkg/client/grpcauthorizer"
 	"google.golang.org/grpc"
cmd/maestro/server/routes.go (2)

3-16: Import ordering: klog should be grouped with external imports.

Same as in auth_interceptor.go, the k8s.io/klog/v2 import is placed between stdlib imports.

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"net/http"
 
 	gorillahandlers "github.com/gorilla/handlers"
 	"github.com/gorilla/mux"
+	"k8s.io/klog/v2"
 
 	"github.com/openshift-online/maestro/cmd/maestro/server/logging"

96-107: Logger middleware implementation looks good; consider addressing the TODO.

The middleware correctly propagates the context-derived logger to each request. However, the TODO on line 102 indicates that the operation ID should be set on the logger for request tracing correlation.

Since OperationIDMiddleware (line 39) already sets the operation ID in the context, you could enhance this middleware to include it in the logger:

opID := loggertracing.GetOperationID(reqCtx)
newLogger := logger.WithValues("operationID", opID)
newReqCtx := klog.NewContext(reqCtx, newLogger)

Would you like me to generate the complete implementation that includes the operation ID in the logger?

cmd/maestro/common/otlp_sdk.go (1)

3-18: Import ordering: klog should be grouped with external imports.

The k8s.io/klog/v2 import is placed between stdlib imports (context and os).

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"os"
 	"time"
 
 	"go.opentelemetry.io/contrib/exporters/autoexport"
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/propagation"
 	"go.opentelemetry.io/otel/sdk/resource"
 	tracesdk "go.opentelemetry.io/otel/sdk/trace"
 	semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
+	"k8s.io/klog/v2"
 
 	"github.com/openshift-online/maestro/pkg/constants"
-	errors "github.com/zgalor/weberr"
+	"github.com/zgalor/weberr"
 )
pkg/handlers/framework.go (1)

3-12: Import ordering: klog should be grouped with external imports.

The k8s.io/klog/v2 import is placed between stdlib imports.

 import (
 	"context"
 	"encoding/json"
 	"io"
-	"k8s.io/klog/v2"
 	"net/http"
 
+	"k8s.io/klog/v2"
+
 	"github.com/openshift-online/maestro/pkg/errors"
 	loggertracing "github.com/openshift-online/maestro/pkg/logger"
 )
cmd/maestro/server/metrics_server.go (1)

3-14: Import ordering: klog should be grouped with external imports.

The k8s.io/klog/v2 import is placed between stdlib imports.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net"
 	"net/http"
 
 	"github.com/gorilla/mux"
+	"k8s.io/klog/v2"
 
 	"github.com/openshift-online/maestro/pkg/api"
cmd/maestro/server/server.go (1)

3-14: Import grouping does not follow Go conventions.

Standard library imports (context, net, net/http, os, strings) should be grouped separately from third-party imports (k8s.io/klog/v2, github.com/getsentry/sentry-go).

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"net"
 	"net/http"
 	"os"
 	"strings"
 
+	"k8s.io/klog/v2"
 	"github.com/getsentry/sentry-go"
 
 	"github.com/openshift-online/maestro/cmd/maestro/environments"
 )
cmd/maestro/server/event_server.go (1)

3-19: Import grouping does not follow Go conventions.

Same issue as in server.go - standard library imports should be grouped separately from third-party imports.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 
+	"k8s.io/klog/v2"
+	"k8s.io/apimachinery/pkg/api/meta"
+	"open-cluster-management.io/sdk-go/pkg/cloudevents/clients/common"
+	workpayload "open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/payload"
+	"open-cluster-management.io/sdk-go/pkg/cloudevents/generic/types"
+
 	"github.com/openshift-online/maestro/pkg/api"
 	"github.com/openshift-online/maestro/pkg/client/cloudevents"
 	"github.com/openshift-online/maestro/pkg/dao"
 	"github.com/openshift-online/maestro/pkg/db"
 	"github.com/openshift-online/maestro/pkg/dispatcher"
 	"github.com/openshift-online/maestro/pkg/event"
 	"github.com/openshift-online/maestro/pkg/services"
-	"k8s.io/apimachinery/pkg/api/meta"
-	"open-cluster-management.io/sdk-go/pkg/cloudevents/clients/common"
-	workpayload "open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/payload"
-	"open-cluster-management.io/sdk-go/pkg/cloudevents/generic/types"
 )
cmd/maestro/server/grpc_broker.go (1)

3-30: Import grouping does not follow Go conventions.

Standard library imports should be grouped separately. This is consistent with the feedback on other files.

cmd/maestro/server/api_server.go (1)

3-26: Import grouping does not follow Go conventions.

Standard library imports should be grouped separately from third-party imports. This is consistent with feedback on other files in this PR.

cmd/maestro/servecmd/cmd.go (1)

3-23: Import grouping does not follow Go conventions.

Standard library imports should be grouped separately. Additionally, consider whether both log and klog are necessary - log appears to only be used for log.Fatalf in NewServerCommand (line 34).

 import (
 	"context"
 	"errors"
-	"k8s.io/klog/v2"
-	"log"
 	"os"
 	"os/signal"
 	"syscall"
 	"time"
 
 	"github.com/spf13/cobra"
+	"k8s.io/klog/v2"
 
 	"github.com/openshift-online/maestro/cmd/maestro/common"
cmd/maestro/server/healthcheck_server.go (2)

7-9: Non-standard import ordering.

The klog import is placed between standard library imports (fmt and net/http). Go convention groups imports into: standard library, then external packages, then local packages.

Consider reorganizing imports:

 import (
 	"context"
 	e "errors"
 	"fmt"
-	"k8s.io/klog/v2"
 	"net/http"
 	"time"

 	"github.com/gorilla/mux"
+	"k8s.io/klog/v2"
+
 	"github.com/openshift-online/maestro/pkg/api"

78-82: Unreachable code after server error.

When ListenAndServe or ListenAndServeTLS returns an error, check() is called which likely logs/handles the error, then logger.Info("HealthCheck server terminated") runs, followed by waiting on ctx.Done(). If the server fails immediately, this blocks indefinitely waiting for context cancellation.

Consider returning early or restructuring to avoid blocking after server failure:

 	check(ctx, err, "HealthCheck server terminated with errors")
+	if err != nil && err != http.ErrServerClosed {
+		return
+	}
 	logger.Info("HealthCheck server terminated")

 	// wait until context is done
 	<-ctx.Done()
pkg/controllers/framework.go (1)

214-218: Context enrichment at wrong level.

The logger is created with "key" at line 214, but this enriched context isn't passed to handleEvent. The handleEvent method receives the original ctx and creates its own enriched logger. The "key" information is only available for the error log at line 218, not within handleEvent.

Consider passing the enriched context to handleEvent for consistent logging:

 	logger := klog.FromContext(ctx).WithValues("key", key)
+	enrichedCtx := klog.NewContext(ctx, logger)

-	if reconciled, err := km.handleEvent(ctx, key); !reconciled {
+	if reconciled, err := km.handleEvent(enrichedCtx, key); !reconciled {

This is optional since handleEvent also adds the event ID, but having the key available throughout would improve traceability.

test/helper.go (1)

8-9: Non-standard import ordering.

Similar to the healthcheck_server.go file, klog is placed between standard library imports. Go convention groups standard library imports separately from external packages.

Consider reorganizing imports:

 import (
 	"context"
 	"crypto/rsa"
 	"encoding/json"
 	"fmt"
-	"k8s.io/klog/v2"
 	"log"
 	"os"

And add klog in the external packages section.

cmd/maestro/server/grpc_server.go (1)

304-326: Callback function doesn't propagate context-derived logger.

The callback registered with eventBroadcaster.Register receives a context but creates logs using the outer logger variable. While this works due to closure, the callback should ideally derive its logger from the provided context for consistency, especially if the broadcaster might enrich the context.

Consider deriving logger from the callback's context:

-	clientID := svr.eventBroadcaster.Register(ctx, subReq.Source, func(res *api.Resource) error {
+	clientID := svr.eventBroadcaster.Register(ctx, subReq.Source, func(res *api.Resource) error {
+		// Note: if eventBroadcaster enriches context, consider using klog.FromContext(ctx)
 		evt, err := encodeResourceStatus(res)

This is optional since the current implementation works correctly with the closure-captured logger.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 180dfbe and 928f017.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (49)
  • cmd/maestro/agent/cmd.go (1 hunks)
  • cmd/maestro/common/otlp_sdk.go (4 hunks)
  • cmd/maestro/environments/framework.go (6 hunks)
  • cmd/maestro/main.go (1 hunks)
  • cmd/maestro/migrate/cmd.go (2 hunks)
  • cmd/maestro/servecmd/cmd.go (4 hunks)
  • cmd/maestro/server/api_server.go (6 hunks)
  • cmd/maestro/server/auth_interceptor.go (3 hunks)
  • cmd/maestro/server/controllers.go (3 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • cmd/maestro/server/healthcheck_server.go (7 hunks)
  • cmd/maestro/server/logging/formatter_json.go (3 hunks)
  • cmd/maestro/server/logging/logging.go (0 hunks)
  • cmd/maestro/server/logging/writer.go (3 hunks)
  • cmd/maestro/server/metrics_server.go (2 hunks)
  • cmd/maestro/server/routes.go (4 hunks)
  • cmd/maestro/server/server.go (3 hunks)
  • go.mod (3 hunks)
  • pkg/api/error.go (5 hunks)
  • pkg/api/metadata.go (4 hunks)
  • pkg/auth/helpers.go (1 hunks)
  • pkg/client/cloudevents/source_client.go (4 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
  • pkg/controllers/event_filter.go (3 hunks)
  • pkg/controllers/framework.go (9 hunks)
  • pkg/controllers/framework_test.go (2 hunks)
  • pkg/controllers/status_controller.go (7 hunks)
  • pkg/db/advisory_locks.go (8 hunks)
  • pkg/db/context.go (2 hunks)
  • pkg/db/db_session/default.go (4 hunks)
  • pkg/db/db_session/test.go (2 hunks)
  • pkg/db/migrations.go (2 hunks)
  • pkg/db/transaction_middleware.go (2 hunks)
  • pkg/dispatcher/hash_dispatcher.go (8 hunks)
  • pkg/dispatcher/noop_dispatcher.go (4 hunks)
  • pkg/errors/errors.go (0 hunks)
  • pkg/event/event.go (5 hunks)
  • pkg/handlers/framework.go (2 hunks)
  • pkg/logger/logger.go (0 hunks)
  • pkg/logger/zap.go (0 hunks)
  • pkg/services/generic.go (3 hunks)
  • pkg/services/resource.go (5 hunks)
  • test/e2e/pkg/suite_test.go (3 hunks)
  • test/helper.go (11 hunks)
  • test/integration/integration_test.go (1 hunks)
  • test/mocks/workserver/main.go (5 hunks)
  • test/upgrade/pkg/suite_test.go (2 hunks)
💤 Files with no reviewable changes (4)
  • pkg/errors/errors.go
  • pkg/logger/zap.go
  • cmd/maestro/server/logging/logging.go
  • pkg/logger/logger.go
🚧 Files skipped from review as they are similar to previous changes (11)
  • pkg/client/grpcauthorizer/kube_authorizer.go
  • pkg/db/transaction_middleware.go
  • test/integration/integration_test.go
  • pkg/services/generic.go
  • pkg/db/advisory_locks.go
  • pkg/controllers/event_filter.go
  • cmd/maestro/environments/framework.go
  • test/e2e/pkg/suite_test.go
  • cmd/maestro/server/controllers.go
  • pkg/client/cloudevents/source_client.go
  • pkg/event/event.go
🧰 Additional context used
🧬 Code graph analysis (10)
cmd/maestro/server/event_server.go (3)
pkg/api/resource_types.go (1)
  • Resource (14-27)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
cmd/maestro/server/routes.go (5)
cmd/maestro/environments/types.go (1)
  • Services (42-48)
pkg/handlers/resource_bundle.go (1)
  • NewResourceBundleHandler (22-27)
pkg/handlers/consumer.go (1)
  • NewConsumerHandler (24-30)
pkg/auth/auth_middleware_mock.go (1)
  • AuthMiddlewareMock (7-7)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/auth/helpers.go (2)
pkg/errors/errors.go (2)
  • ServiceErrorCode (61-61)
  • New (102-116)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
pkg/handlers/framework.go (1)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
pkg/controllers/status_controller.go (2)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
cmd/maestro/server/healthcheck_server.go (3)
cmd/maestro/server/server.go (1)
  • Server (16-21)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/db/advisory_locks.go (1)
  • Instances (25-25)
cmd/maestro/migrate/cmd.go (3)
pkg/db/db_session/default.go (1)
  • NewProdFactory (38-42)
pkg/db/migrations.go (1)
  • Migrate (15-26)
pkg/errors/errors.go (1)
  • New (102-116)
cmd/maestro/server/logging/writer.go (1)
cmd/maestro/server/logging/formatter.go (1)
  • LogFormatter (5-8)
cmd/maestro/server/grpc_server.go (4)
pkg/services/resource.go (1)
  • ResourceService (26-39)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
pkg/config/grpc_server.go (1)
  • GRPCServerConfig (10-35)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
cmd/maestro/server/api_server.go (2)
cmd/maestro/server/server.go (1)
  • Server (16-21)
cmd/maestro/server/grpc_server.go (2)
  • NewGRPCServer (48-146)
  • GRPCServer (36-45)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: migration
  • GitHub Check: e2e
  • GitHub Check: e2e-with-istio
  • GitHub Check: e2e-broadcast-subscription
  • GitHub Check: e2e-grpc-broker
🔇 Additional comments (65)
go.mod (2)

5-62: Dependency migration to klog is well-structured.

The addition of k8s.io/klog/v2 v2.130.1 as a direct dependency and the removal of spf13/viper from the require section align with the PR objective to migrate from Zap-based logging to klog-based contextual logging. The version is consistent with the other k8s.io packages at v0.33.4.


93-93: Verify transitive dependency resolution after migration.

Lines 93 (fsnotify), 173 (zap), and 186 (genproto) have been moved or added to the indirect section. Ensure that:

  1. The move of go.uber.org/zap to indirect is intentional and does not break any transitive dependencies that previously relied on it being direct.
  2. The removal of spf13/viper (and its dependency on fsnotify for dynamic config watching) does not cause issues elsewhere in the codebase.
  3. The k8s.io/klog/v2 v2.130.1 is fully compatible with the k8s.io packages at v0.33.4.
test/upgrade/pkg/suite_test.go (2)

6-6: LGTM!

The klog import is correctly added to support the contextual logging migration.


65-65: Verify consistency with contextual logging approach.

The migration to klog.Errorf is correct, but this uses the global logger rather than a context-aware logger. Since the PR emphasizes "contextual logging" and "threads context.Context and context-bound klog loggers," please confirm that using the global logger in Ginkgo test callbacks (where context isn't available in the signature) is the intended pattern.

pkg/dispatcher/noop_dispatcher.go (3)

35-49: LGTM!

The contextual logging integration is well-implemented. The logger is correctly obtained from context and passed to the listener callback, ensuring consistent logging context across the dispatcher lifecycle.


52-77: LGTM!

The contextual logger is correctly extracted from the context. The structured error logging with key-value pairs ("consumers", consumerIDs) follows klog best practices.


79-92: LGTM!

The updated signature accepting klog.Logger enables consistent contextual logging throughout the callback chain.

cmd/maestro/server/logging/formatter_json.go (2)

6-6: LGTM!

The klog import is correctly added to support the migration to klog-based logging.


18-34: Verify context-less klog usage for consistency with PR objectives.

The PR migrates to contextual logging with context-bound loggers, but this code uses the global klog.V(4).Enabled() check. While this is only checking verbosity enablement (not actually logging), consider whether a context-bound logger should be used for consistency.

Additionally, the magic number 4 (debug verbosity level) could benefit from a comment explaining the klog verbosity convention.

cmd/maestro/migrate/cmd.go (1)

7-7: klog import usage looks good

The klog v2 import is correct and is used consistently below; nothing blocking here.

pkg/db/db_session/default.go (4)

7-7: LGTM: klog import added correctly.

The import aligns with the PR's objective to adopt klog's contextual logging.


141-168: LGTM: Contextual logging correctly implemented.

The function correctly derives a per-context logger and uses structured logging with appropriate verbosity levels. The V(4) level for detailed event notifications is a good choice.


170-197: LGTM: Logger correctly captured in callback closure.

The contextual logger is properly derived and captured in the plog callback closure. The logger.Error call follows klog's convention correctly (error first, then message, then structured fields). The captured logger will safely handle asynchronous callback invocations.


199-206: LGTM: Context and logger properly propagated.

The function correctly derives the logger and propagates the context to both newListener and waitForNotification, ensuring consistent contextual logging throughout the listener lifecycle.

pkg/auth/helpers.go (1)

3-11: Contextual klog usage is consistent; confirm logger injection into context

Using klog.FromContext(ctx) and logtracing.GetOperationID(ctx) aligns with the move to contextual logging and op-id tracing. This looks good as long as all HTTP handlers/middleware in the call path reliably attach a klog logger to the context; otherwise logs may silently fall back to a background/no-op logger, making debugging harder. Please double-check that your klog setup guarantees a logger is always present on request contexts.

Also applies to: 14-17

pkg/db/context.go (4)

5-6: LGTM! Necessary imports for klog migration.

The addition of errors and k8s.io/klog/v2 packages supports the contextual logging refactor.


26-26: LGTM! Proper contextual logger initialization.

Retrieving the logger from context follows klog best practices.


50-50: LGTM! Proper contextual logger initialization.

Retrieving the logger from context follows klog best practices.


57-57: LGTM! Good use of structured logging.

Logging the rollback trigger with the error as a key-value pair enables better log filtering and analysis.

pkg/services/resource.go (4)

5-5: klog import matches the move to contextual logging

Importing k8s.io/klog/v2 here is appropriate and aligns this service with the rest of the klog-based logging changes.


162-163: Good use of context-derived logger with resource scoping

Deriving the logger from ctx and scoping it with "resourceID" keeps logs per-request and structured; this is exactly the right pattern for this service.


199-201: Status update logging looks well-structured and appropriately verbose

Using a lightweight Info without payload plus a V(4) log with the event payload is a good split between signal and detail, and matches common klog usage.


225-226: Stale sequenceID log is consistent and resolves prior key-name issue

The structured log for stale sequence IDs now uses "foundSequenceID" / "wantSequenceID", consistent with other keys and the earlier review feedback.

pkg/db/migrations.go (1)

3-10: klog/v2 import is consistent with the logging migration

Importing k8s.io/klog/v2 here is consistent with the rest of the PR’s shift away from the custom logger; nothing blocking from this file’s perspective. Please just confirm k8s.io/klog/v2 is properly listed in go.mod and aligned with the repo’s chosen klog version.

pkg/db/db_session/test.go (1)

55-64: klog migration in test Init preserves behavior

Switching the Init error paths to klog.Error keeps the control flow and error handling identical while aligning the test factory with the new logging backend. Nothing else to change here.

test/mocks/workserver/main.go (1)

10-11: Mock workserver klog migration looks good

The swap to klog for init/start/shutdown messages keeps the same behavior and severities, and fits the rest of the repo’s logging direction. No issues spotted.

Also applies to: 155-160, 172-173, 269-287

pkg/dispatcher/hash_dispatcher.go (1)

76-88: Context propagation and workqueue handling are improved

Nice changes here:

  • updateConsumerSet now takes ctx and uses it for consumerDao.All, eliminating the context.TODO() and aligning with the rest of the context‑aware code.
  • Deriving logger := klog.FromContext(ctx) in resyncOnReconnect, check, and processNextResync keeps logging contextual and structured.
  • Adding d.workQueue.Forget(key) on successful resync correctly resets the rate limiter for that key.

This all looks solid.

Also applies to: 99-133, 151-203, 205-241

pkg/api/metadata.go (1)

34-36: Per-request klog logging in metadata handlers looks correct

Deriving a logger from r.Context() and logging write failures with logger.Error(..., "path", r.URL.Path) keeps the previous behavior while adding contextual, structured logging. Sentry capture remains in place. This migration looks good.

Also applies to: 55-61, 69-71, 93-99

pkg/api/error.go (1)

42-47: Error helpers now consistently use contextual klog logging

All three helpers now log write failures (and the panic-body initialization failure) via klog, using klog.FromContext(r.Context()) where an HTTP request is available and still capturing with Sentry. This gives you structured, per-request logging without changing HTTP behavior. Looks good.

Also applies to: 64-69, 71-79, 101-111

pkg/controllers/framework_test.go (1)

87-90: Tests correctly updated for context-aware handleEvent

Passing ctx into mgr.handleEvent in both tests aligns them with the new (ctx context.Context, id string) signature and the overall context‑aware controller design. Assertions still cover the same behavior, so this looks good.

Also applies to: 198-200

cmd/maestro/server/auth_interceptor.go (2)

100-124: LGTM!

The unary interceptor correctly derives the logger from context and uses structured logging for authentication errors while preserving the original error handling flow.


160-183: LGTM!

The stream interceptor follows the same pattern as the unary interceptor, correctly extracting the logger from ss.Context() and using it for structured error logging.

cmd/maestro/common/otlp_sdk.go (1)

26-64: LGTM!

The migration from Zap to klog is clean. The logger is correctly passed as a parameter and used for both initialization logging and error handling within the OpenTelemetry error handler closure.

pkg/handlers/framework.go (1)

33-43: LGTM!

The error handling correctly differentiates between client errors (4xx logged at Info level) and server errors (5xx logged at Error level). The operation ID is properly retrieved and passed to the OpenAPI error response.

cmd/maestro/server/metrics_server.go (2)

47-67: LGTM!

The Start method correctly derives the logger from context and uses it for all logging paths (TLS/non-TLS startup messages and termination). The error handling with check(ctx, ...) is consistent with the broader PR pattern.


44-45: Add a comment clarifying that Serve implements the Server interface, which requires these parameters despite them being unused.

The underscore-prefixed parameters indicate these are deliberately unused. A brief inline comment explaining the interface requirement would improve code clarity for future maintainers.

cmd/maestro/server/server.go (1)

30-38: LGTM!

The check function correctly derives the logger from context and uses klog's structured logging pattern. The error handling flow (log → Sentry → exit) is preserved.

cmd/maestro/server/event_server.go (4)

77-89: LGTM!

The Start method correctly derives the logger from context and uses it consistently for startup/shutdown messages.


93-117: LGTM!

Good use of structured logging with WithValues to enrich the logger with resourceID and action. The context is properly updated using klog.NewContext so downstream functions receive the enriched logger.


163-253: LGTM!

The handleStatusUpdate function correctly derives the logger from context and uses consistent structured logging throughout. The log messages clearly indicate the status update flow.


255-304: LGTM!

The broadcastStatusEvent function properly enriches the logger with relevant identifiers (resourceID, instanceID, eventID) and uses structured logging for the broadcast message.

cmd/maestro/server/grpc_broker.go (3)

127-212: LGTM!

The NewGRPCBroker constructor correctly accepts context, derives the logger, and uses the context-aware check() function consistently for error handling. The TLS configuration logging is clear and includes relevant port information.


214-232: LGTM!

The Start method correctly uses check(ctx, ...) for error handling (addressing the previous review comment about Sentry reporting). The graceful shutdown flow with GracefulStop() is appropriate.


269-298: LGTM!

The PredicateEvent method correctly uses logger.V(4).Info for debug-level logging, which is appropriate for operational details that shouldn't clutter standard logs.

cmd/maestro/server/api_server.go (3)

39-143: LGTM!

The NewAPIServer constructor correctly accepts context and propagates it to route setup, authentication handler creation, and gRPC server initialization. The check(ctx, ...) calls ensure consistent error handling.


147-170: LGTM!

The Serve method correctly derives the logger from context and uses structured logging with port information for TLS status messages.


179-198: LGTM!

The Start method correctly addresses the previous review concern - it now returns on listener error instead of calling os.Exit(1), ensuring the deferred s.grpcServer.Stop() executes properly.

cmd/maestro/servecmd/cmd.go (4)

52-56: LGTM!

Good pattern for contextual logging - creating a named logger with WithName("maestro-server") and attaching it to the context. This ensures all downstream components receive a properly identified logger.


62-82: LGTM!

The event server setup correctly uses context-aware logging and propagates context to constructors. The error handling for unsupported subscription types now includes a proper error message (addressing the previous review comment).


113-117: LGTM!

The shutdown error handling is now correct - it captures the shutdownErr from tracingShutdown(ctx) and logs that specific error (addressing the previous review comment about logging the wrong error variable).


120-131: LGTM!

Context is correctly propagated to all server Start methods, ensuring consistent contextual logging throughout the application lifecycle.

cmd/maestro/server/healthcheck_server.go (1)

28-48: LGTM!

The constructor properly accepts context, registers the logger middleware, and initializes all server components correctly. The context propagation pattern is consistent with the PR's goals.

pkg/controllers/framework.go (3)

88-104: LGTM!

The Run method correctly derives the logger from context, starts background goroutines with context propagation using wait.JitterUntilWithContext and wait.UntilWithContext, and properly waits for context cancellation before shutdown.


118-121: LGTM!

The context enrichment pattern correctly creates a logger with the event ID, embeds it into a new context via klog.NewContext, and also stores the event ID as a context value for non-logging purposes. This enables both structured logging and context-based event identification.


232-258: LGTM!

The syncEvents method properly derives the logger from context and uses it consistently for all informational and error logging with appropriate structured fields.

pkg/controllers/status_controller.go (4)

51-66: LGTM!

The Run method correctly follows the same context-aware pattern as KindControllerManager.Run, with proper logger derivation, goroutine startup with context, and graceful shutdown on context cancellation.


76-99: LGTM!

The processNextEvent method correctly derives a logger from context and handles the event processing flow with proper error logging and queue management (rate-limited requeue on failure, forget on success).


104-106: LGTM!

The context enrichment pattern is consistent with handleEvent in framework.go, correctly creating an enriched logger with the status event ID and embedding it into the request context.


161-190: LGTM!

The syncStatusEvents method properly uses context-derived logging throughout, with appropriate log levels (V(2) for verbose operational info, Error for failures) and structured fields for instance IDs.

test/helper.go (3)

129-160: LGTM!

The helper initialization correctly creates a cancellable context and propagates it to all context-aware constructors (NewHealthCheckServer, NewGRPCBroker). The context is stored in the helper for use across test lifecycle methods.


198-265: LGTM!

All server start methods consistently derive loggers from helper.Ctx and use appropriate log levels (V(4) for debug-level test infrastructure messages). The pattern is uniform across all startup methods.


376-396: LGTM!

The Reset method correctly uses context-derived logging. The typo fix ("Resetting" instead of "Reseting") from the previous review has been applied.

cmd/maestro/server/grpc_server.go (3)

48-146: LGTM!

The NewGRPCServer constructor properly accepts context, derives a logger for initialization logging, and passes context to the check() helper for fatal error handling. All TLS configuration paths log with structured fields.


149-159: LGTM!

The Start method correctly derives a logger from context, logs the startup, and properly handles and logs listen errors before returning.


445-488: LGTM!

The respondResyncStatusRequest method correctly derives a logger from context and uses it for informational logging about resources not found during status resync. The structured logging with "objectID" field provides good traceability.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
cmd/maestro/main.go (1)

18-21: Remove unused constants.

These constants appear to be leftover from the removed viper/fsnotify-based logging configuration and are no longer referenced.

Apply this diff to remove the dead code:

-// nolint
-//
-//go:generate go-bindata -o ../../data/generated/openapi/openapi.go -pkg openapi -prefix ../../openapi/ ../../openapi
-const (
-	logConfigFile = "/configs/logging/config.yaml"
-	varLogLevel   = "log_level"
-)
-
cmd/maestro/server/event_server.go (1)

94-110: Avoid mutating shared ctx inside Subscribe callback (data race and context leakage)

The callback captures and then reassigns the outer ctx variable with ctx = klog.NewContext(ctx, logger). If Subscribe invokes the handler concurrently (standard practice for message queue clients), multiple goroutines will race on this shared variable, causing undefined behavior and potentially leaking logger context from one event to another.

Create a local context variable instead of reassigning the outer one:

 s.sourceClient.Subscribe(ctx, func(action types.ResourceAction, resource *api.Resource) error {
 	logger := klog.FromContext(ctx).WithValues("resourceID", resource.ID, "action", action)
 	logger.Info("received action for resource")
-	ctx = klog.NewContext(ctx, logger)
+	eventCtx := klog.NewContext(ctx, logger)
 
 	switch action {
 	case types.StatusModified:
 		if !s.statusDispatcher.Dispatch(resource.ConsumerName) {
 			logger.Info("skipping resource status update as it is not owned by the current instance")
 			return nil
 		}
 
-		if err := handleStatusUpdate(ctx, resource, s.resourceService, s.statusEventService); err != nil {
+		if err := handleStatusUpdate(eventCtx, resource, s.resourceService, s.statusEventService); err != nil {
 			return fmt.Errorf("failed to handle resource status update %s: %s", resource.ID, err.Error())
 		}

This eliminates the race and keeps each event's context isolated.

🧹 Nitpick comments (12)
cmd/maestro/migrate/cmd.go (1)

29-37: Add context to fatal log messages for easier troubleshooting

klog.Fatal(err) will only emit the raw error string, which makes it harder to see what failed when scanning logs. Consider adding short, operation-specific messages so failures from this command are self-describing.

For example:

-	if err != nil {
-		klog.Fatal(err)
-	}
+	if err != nil {
+		klog.Fatal("failed to read database config:", err)
+	}
@@
-	if err := db.Migrate(connection.New(context.Background())); err != nil {
-		klog.Fatal(err)
-	}
+	if err := db.Migrate(connection.New(context.Background())); err != nil {
+		klog.Fatal("failed to run database migrations:", err)
+	}
test/mocks/workserver/main.go (1)

155-159: Consider using contextual logging where context is available.

The PR aims to adopt klog's contextual logging. Since s.ctx is available in both Initialize() (lines 155-159) and Start() (line 172), consider using klog.FromContext(s.ctx) instead of the package-level klog functions for consistency with the PR's objectives.

Example for Initialize():

-	klog.Infof("Mock server initialized successfully")
-	klog.Infof("API Server: %s", s.apiServerAddress)
-	klog.Infof("gRPC Server: %s", s.grpcServerAddress)
-	klog.Infof("Consumer: %s", s.consumerName)
-	klog.Infof("Bind Address: %s", s.bindAddress)
+	logger := klog.FromContext(s.ctx)
+	logger.Info("Mock server initialized successfully")
+	logger.Info("API Server", "address", s.apiServerAddress)
+	logger.Info("gRPC Server", "address", s.grpcServerAddress)
+	logger.Info("Consumer", "name", s.consumerName)
+	logger.Info("Bind Address", "address", s.bindAddress)

Similar pattern for Start():

-	klog.Infof("Starting mock server on %s", s.bindAddress)
+	logger := klog.FromContext(s.ctx)
+	logger.Info("Starting mock server", "address", s.bindAddress)

Note: klog's contextual logger uses structured key-value pairs instead of format strings.

Also applies to: 172-172

pkg/handlers/framework.go (1)

33-43: Context-scoped error logging looks correct; consider enriching logs with operation ID

Using loggertracing.GetOperationID(ctx) and klog.FromContext(ctx) makes handleError fully context-aware and preserves the 4xx-as-Info vs other-as-Error behavior. Implementation looks sound.

Optionally, if the per-request logger created upstream does not already include the operation ID, you could attach it here to improve correlation, e.g.:

opID := loggertracing.GetOperationID(ctx)
logger := klog.FromContext(ctx).WithValues("operation_id", opID)

before logging, while still passing opID into AsOpenapiError.

cmd/maestro/server/auth_interceptor.go (1)

119-119: Nitpick: Inconsistent capitalization in error messages.

Line 119 uses lowercase "type" while line 179 uses uppercase "Type" in the same error message. Consider standardizing to lowercase for consistency.

Apply this diff to standardize:

 	default:
-		return fmt.Errorf("unsupported authentication Type %s", authNType)
+		return fmt.Errorf("unsupported authentication type %s", authNType)

Also applies to: 179-179

pkg/db/db_session/test.go (1)

58-64: Prefer klog.ErrorS over klog.Error and avoid odd formatting

klog.Error is deprecated in favor of klog.ErrorS, which gives structured logging with the error attached under the standard err field. (pkg.go.dev) Using klog.Error(err, "…") also produces a slightly awkward log line because the error and message are just concatenated via fmt.Sprint with no separator.

You can switch both call sites to ErrorS:

-        if err := initDatabase(config, db.Migrate); err != nil {
-            klog.Error(err, "error initializing test database")
+        if err := initDatabase(config, db.Migrate); err != nil {
+            klog.ErrorS(err, "error initializing test database")
         }

-        if err := resetDB(config); err != nil {
-            klog.Error(err, "error resetting test database")
+        if err := resetDB(config); err != nil {
+            klog.ErrorS(err, "error resetting test database")
         }
pkg/services/resource.go (1)

3-19: Import grouping could be improved.

The "k8s.io/klog/v2" import on line 5 is placed between stdlib imports ("context" and "reflect"). Consider grouping it with other third-party imports for consistency.

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"reflect"
 	"time"

 	cloudeventstypes "github.com/cloudevents/sdk-go/v2/types"
 	"github.com/openshift-online/maestro/pkg/dao"
 	"github.com/openshift-online/maestro/pkg/db"
 	"github.com/prometheus/client_golang/prometheus"
+	"k8s.io/klog/v2"

 	cegeneric "open-cluster-management.io/sdk-go/pkg/cloudevents/generic"
pkg/event/event.go (1)

82-106: Consider adding rate-limiting or level adjustment for "no clients" log.

The log message on line 94 (logger.Info("no clients registered on this instance")) will be emitted for every broadcast when no clients are registered. Depending on broadcast frequency, this could generate significant log volume.

Consider using a debug/verbose level for this message:

 			if len(h.clients) == 0 {
-				logger.Info("no clients registered on this instance")
+				logger.V(4).Info("no clients registered on this instance")
 			}
cmd/maestro/server/controllers.go (1)

3-12: Minor: Remove stray blank line in imports.

Line 5 has an unnecessary blank line within the import block.

 import (
 	"context"
-	
 	"k8s.io/klog/v2"

 	"github.com/openshift-online/maestro/pkg/api"
cmd/maestro/server/logging/request_logging_middleware.go (1)

27-31: Stale TODO comment and potential empty opID in logs.

The TODO on line 27 appears to be stale—the operation ID is already being extracted and added to the logger on lines 29-30.

Additionally, when the X-Operation-ID header is absent, opID will be an empty string, resulting in log entries with "opid": "". Consider omitting the key when empty:

 				opID := r.Header.Get(string(maestrologger.OpIDHeader))
-				logger := klog.FromContext(ctx).WithValues("opid", opID)
+				logger := klog.FromContext(ctx)
+				if opID != "" {
+					logger = logger.WithValues("opid", opID)
+				}
 				loggingWriter := NewLoggingWriter(logger, w, r, NewJSONLogFormatter())
test/helper.go (1)

8-9: Import ordering violates Go conventions.

The k8s.io/klog/v2 import (third-party) is placed before the standard library log import. Go convention and most linters expect imports ordered as: standard library, then third-party packages.

 import (
 	"context"
 	"crypto/rsa"
 	"encoding/json"
 	"fmt"
+	"log"
+	"os"
+	"path/filepath"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+
-	"k8s.io/klog/v2"
-	"log"
-	"os"
-	"path/filepath"
-	"strings"
-	"sync"
-	"testing"
-	"time"
-
 	"github.com/openshift-online/maestro/pkg/client/cloudevents"
 	...
+	"k8s.io/klog/v2"
pkg/db/advisory_locks.go (2)

91-103: Leverage structured key/values for advisory lock error logging (optional).

The new contextual logger usage is functionally fine. To get more value from klog’s structured logging, consider logging id and lockType as key/value pairs instead of only inside errMsg, e.g.:

-       errMsg := fmt.Sprintf("error obtaining the advisory lock for id %s type %s, %v", id, lockType, err)
-       logger.Error(err, errMsg)
+       logger.Error(err, "error obtaining advisory lock", "id", id, "lockType", lockType)
+       errMsg := fmt.Sprintf("error obtaining the advisory lock for id %s type %s, %v", id, lockType, err)

This keeps the returned error text unchanged while making log queries on id/lockType much easier.


114-127: Apply the same structured logging pattern for non-blocking lock errors (optional).

Similarly to NewAdvisoryLock, you can expose id and lockType as structured fields instead of only in the formatted string:

-       errMsg := fmt.Sprintf("error obtaining the non blocking advisory lock for id %s type %s, %v", id, lockType, err)
-       logger.Error(err, errMsg)
+       logger.Error(err, "error obtaining non-blocking advisory lock", "id", id, "lockType", lockType)
+       errMsg := fmt.Sprintf("error obtaining the non blocking advisory lock for id %s type %s, %v", id, lockType, err)

This keeps behavior and returned error text as-is while improving log queryability.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 928f017 and b4c0ca4.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (51)
  • cmd/maestro/agent/cmd.go (1 hunks)
  • cmd/maestro/common/otlp_sdk.go (3 hunks)
  • cmd/maestro/environments/framework.go (7 hunks)
  • cmd/maestro/main.go (1 hunks)
  • cmd/maestro/migrate/cmd.go (2 hunks)
  • cmd/maestro/servecmd/cmd.go (4 hunks)
  • cmd/maestro/server/api_server.go (6 hunks)
  • cmd/maestro/server/auth_interceptor.go (3 hunks)
  • cmd/maestro/server/controllers.go (3 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • cmd/maestro/server/healthcheck_server.go (7 hunks)
  • cmd/maestro/server/logging/formatter.go (1 hunks)
  • cmd/maestro/server/logging/formatter_json.go (3 hunks)
  • cmd/maestro/server/logging/logging.go (0 hunks)
  • cmd/maestro/server/logging/request_logging_middleware.go (1 hunks)
  • cmd/maestro/server/logging/writer.go (4 hunks)
  • cmd/maestro/server/metrics_server.go (2 hunks)
  • cmd/maestro/server/routes.go (3 hunks)
  • cmd/maestro/server/server.go (2 hunks)
  • go.mod (3 hunks)
  • pkg/api/error.go (5 hunks)
  • pkg/api/metadata.go (4 hunks)
  • pkg/auth/helpers.go (1 hunks)
  • pkg/client/cloudevents/source_client.go (4 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
  • pkg/controllers/event_filter.go (3 hunks)
  • pkg/controllers/framework.go (9 hunks)
  • pkg/controllers/framework_test.go (2 hunks)
  • pkg/controllers/status_controller.go (7 hunks)
  • pkg/db/advisory_locks.go (8 hunks)
  • pkg/db/context.go (2 hunks)
  • pkg/db/db_session/default.go (4 hunks)
  • pkg/db/db_session/test.go (2 hunks)
  • pkg/db/migrations.go (2 hunks)
  • pkg/db/transaction_middleware.go (2 hunks)
  • pkg/dispatcher/hash_dispatcher.go (8 hunks)
  • pkg/dispatcher/noop_dispatcher.go (4 hunks)
  • pkg/errors/errors.go (0 hunks)
  • pkg/event/event.go (5 hunks)
  • pkg/handlers/framework.go (2 hunks)
  • pkg/logger/logger.go (0 hunks)
  • pkg/logger/zap.go (0 hunks)
  • pkg/services/generic.go (3 hunks)
  • pkg/services/resource.go (6 hunks)
  • test/e2e/pkg/suite_test.go (3 hunks)
  • test/helper.go (11 hunks)
  • test/integration/integration_test.go (1 hunks)
  • test/mocks/workserver/main.go (5 hunks)
  • test/upgrade/pkg/suite_test.go (2 hunks)
💤 Files with no reviewable changes (4)
  • pkg/errors/errors.go
  • pkg/logger/logger.go
  • pkg/logger/zap.go
  • cmd/maestro/server/logging/logging.go
✅ Files skipped from review due to trivial changes (1)
  • cmd/maestro/agent/cmd.go
🚧 Files skipped from review as they are similar to previous changes (16)
  • pkg/db/migrations.go
  • pkg/services/generic.go
  • pkg/db/transaction_middleware.go
  • pkg/client/cloudevents/source_client.go
  • pkg/db/context.go
  • cmd/maestro/environments/framework.go
  • pkg/api/error.go
  • pkg/dispatcher/noop_dispatcher.go
  • cmd/maestro/server/metrics_server.go
  • pkg/auth/helpers.go
  • pkg/db/db_session/default.go
  • pkg/controllers/event_filter.go
  • pkg/client/grpcauthorizer/kube_authorizer.go
  • test/e2e/pkg/suite_test.go
  • test/integration/integration_test.go
  • pkg/controllers/framework_test.go
🧰 Additional context used
🧬 Code graph analysis (16)
cmd/maestro/server/controllers.go (7)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/controllers/event_filter.go (1)
  • EventFilter (18-25)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/controllers/framework.go (1)
  • KindControllerManager (52-57)
cmd/maestro/environments/types.go (1)
  • Database (31-33)
pkg/db/session.go (1)
  • SessionFactory (13-21)
pkg/controllers/status_controller.go (1)
  • StatusController (20-26)
pkg/handlers/framework.go (1)
pkg/logger/operationid_middleware.go (1)
  • GetOperationID (60-65)
cmd/maestro/server/healthcheck_server.go (3)
cmd/maestro/server/server.go (1)
  • Server (16-21)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/db/advisory_locks.go (1)
  • Instances (25-25)
cmd/maestro/server/event_server.go (3)
pkg/api/resource_types.go (1)
  • Resource (14-27)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
cmd/maestro/server/logging/formatter.go (1)
cmd/maestro/server/logging/responseinfo.go (1)
  • ResponseInfo (5-10)
pkg/db/advisory_locks.go (1)
pkg/db/metrics_collector.go (2)
  • UpdateAdvisoryUnlockCountMetric (92-98)
  • UpdateAdvisoryLockDurationMetric (100-107)
pkg/controllers/framework.go (3)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/event.go (1)
  • EventType (9-9)
pkg/api/openapi/model_error.go (1)
  • Error (21-28)
cmd/maestro/server/api_server.go (2)
cmd/maestro/server/server.go (1)
  • Server (16-21)
cmd/maestro/server/grpc_server.go (2)
  • NewGRPCServer (48-146)
  • GRPCServer (36-45)
cmd/maestro/server/grpc_broker.go (3)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/config/config.go (1)
  • ReadFile (110-135)
cmd/maestro/server/routes.go (2)
pkg/auth/auth_middleware_mock.go (1)
  • AuthMiddlewareMock (7-7)
cmd/maestro/server/logging/request_logging_middleware.go (1)
  • RegisterLoggerMiddleware (14-49)
pkg/controllers/status_controller.go (2)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/status_event.go (1)
  • StatusEventType (10-10)
cmd/maestro/server/logging/request_logging_middleware.go (3)
pkg/logger/operationid_middleware.go (1)
  • OpIDHeader (18-18)
cmd/maestro/server/logging/writer.go (1)
  • NewLoggingWriter (8-10)
cmd/maestro/server/logging/formatter_json.go (1)
  • NewJSONLogFormatter (10-12)
cmd/maestro/server/logging/writer.go (1)
cmd/maestro/server/logging/formatter.go (1)
  • LogFormatter (8-11)
cmd/maestro/server/logging/formatter_json.go (1)
cmd/maestro/server/logging/responseinfo.go (1)
  • ResponseInfo (5-10)
cmd/maestro/servecmd/cmd.go (5)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
cmd/maestro/server/grpc_broker.go (1)
  • NewGRPCBroker (128-212)
cmd/maestro/server/api_server.go (1)
  • NewAPIServer (39-143)
cmd/maestro/server/healthcheck_server.go (1)
  • NewHealthCheckServer (28-49)
cmd/maestro/common/otlp_sdk.go (2)
  • TracingEnabled (68-71)
  • InstallOpenTelemetryTracer (26-64)
test/helper.go (4)
cmd/maestro/server/healthcheck_server.go (2)
  • HealthCheckServer (19-26)
  • NewHealthCheckServer (28-49)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
cmd/maestro/server/grpc_broker.go (1)
  • NewGRPCBroker (128-212)
cmd/maestro/server/api_server.go (1)
  • NewAPIServer (39-143)
🪛 GitHub Check: e2e
cmd/maestro/server/healthcheck_server.go

[failure] 35-35:
undefined: registerLoggerMiddleware

🪛 GitHub Check: e2e-broadcast-subscription
cmd/maestro/server/healthcheck_server.go

[failure] 35-35:
undefined: registerLoggerMiddleware

🪛 GitHub Check: e2e-grpc-broker
cmd/maestro/server/healthcheck_server.go

[failure] 35-35:
undefined: registerLoggerMiddleware

🪛 GitHub Check: e2e-with-istio
cmd/maestro/server/healthcheck_server.go

[failure] 35-35:
undefined: registerLoggerMiddleware

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Red Hat Konflux / maestro-e2e-on-pull-request
  • GitHub Check: Red Hat Konflux / maestro-on-pull-request
  • GitHub Check: migration
🔇 Additional comments (71)
cmd/maestro/common/otlp_sdk.go (3)

14-17: LGTM! Clean import updates.

The klog import addition and error package aliasing align with the logger migration.


26-27: LGTM! Function signature and logging call properly migrated.

The function signature correctly accepts klog.Logger, and the Info logging call follows klog's API properly.


60-60: LGTM! Error logging correctly migrated to klog.

The error handler properly uses klog's Error(err, msg) signature.

go.mod (2)

93-93: Confirm fsnotify is no longer directly used.

github.com/fsnotify/fsnotify v1.7.0 is now an indirect dependency. The PR objective states that dynamic log config via viper/fsnotify is removed, so fsnotify should not be directly imported anywhere.


173-173: Confirm zap is no longer directly used.

go.uber.org/zap v1.27.1 is now an indirect dependency (moved from direct). Ensure that all direct imports of zap have been replaced with klog throughout the codebase and that the transitive dependency through other libraries won't cause conflicts.

To verify:

  • Search for direct imports: rg --type go 'go\.uber\.org/zap' — should return no results
  • Verify klog usage: rg --type go 'klog\.' — confirm replacement is in place
  • Check dependency chain: go mod graph | grep zap — confirm zap only appears as transitive
pkg/dispatcher/hash_dispatcher.go (4)

77-86: LGTM! Contextual logging properly implemented.

The logger is correctly derived from the context and used with structured key-value pairs. The previous typo "resourcs" has been fixed to "resources".


100-106: LGTM! Context properly propagated.

The function signature now correctly accepts context and logger parameters. The previous issue of using context.TODO() has been resolved by passing the context through to the DAO call.


152-201: LGTM! Consistent contextual logging throughout.

The logger is correctly derived from context and consistently used across all logging statements. Context and logger are properly passed to updateConsumerSet, ensuring the contextual logging chain is maintained.


230-238: LGTM! Previous issue resolved.

The contextual logging is properly implemented with structured key-value pairs. The addition of the else block that calls d.workQueue.Forget(key) on successful resync addresses the previous review comment about rate limiter state persisting unnecessarily.

cmd/maestro/servecmd/cmd.go (6)

52-55: Context and logger setup looks good.

The klog contextual logging pattern is correctly implemented: creating a named logger, establishing a cancellable context, and embedding the logger into the context for downstream components.


62-82: Event server initialization is well-structured.

The branching logic for gRPC vs message queue event servers correctly propagates the context and uses the logger appropriately. The previous issue with logger.Error usage has been addressed.


84-88: Server constructors correctly receive context.

All server constructors (NewAPIServer, NewHealthCheckServer, NewControllersServer) receive the context, enabling consistent logging and lifecycle management across components.


90-97: Tracing setup and shutdown correctly implemented.

The previous issue with logging the wrong error variable during tracing shutdown has been fixed. The shutdown now correctly captures and logs shutdownErr.

Minor note: the nil check on line 113 is always true since tracingShutdown is initialized to a no-op function on line 90. This is defensive coding and acceptable, though the no-op function approach already ensures safe behavior.

Also applies to: 113-117


101-118: Shutdown sequence ordering.

The shutdown goroutine properly stops the API and metrics servers explicitly before cancelling the context. Other servers (healthcheck, event, controllers) rely on context cancellation, which is consistent with their Start(ctx) pattern.

Note that defer cancel() ensures the context is cancelled after the explicit stops complete, allowing <-ctx.Done() to unblock gracefully.


120-131: Server startup with context propagation looks correct.

All servers receive the context and will properly respond to cancellation. The conditional start of the event server based on message broker configuration is appropriately handled.

test/mocks/workserver/main.go (1)

10-10: LGTM: klog import added correctly.

The addition of k8s.io/klog/v2 is appropriate for Kubernetes ecosystem projects.

pkg/handlers/framework.go (1)

3-12: Contextual logging imports are consistent with usage

The addition of k8s.io/klog/v2 and the loggertracing alias lines up cleanly with how klog.FromContext and loggertracing.GetOperationID are used below; nothing to change here.

cmd/maestro/server/auth_interceptor.go (3)

15-15: LGTM: klog import added.

The klog/v2 import is correct for contextual logging.


106-106: LGTM: Error logging migrated to klog correctly.

The logger.Error(err, "message") pattern follows klog conventions. Error handling flow is preserved—errors are logged and then returned to the caller.

Also applies to: 112-112, 166-166, 172-172


101-101: Verify that incoming request contexts have loggers attached.

Both interceptors use klog.FromContext to derive a logger. If the incoming context lacks a logger, FromContext returns a discard logger that silently drops all log output. Ensure that the gRPC server setup (e.g., via an earlier interceptor) attaches a logger to all incoming request contexts before these auth interceptors execute.

Applies to: lines 101 and 161

cmd/maestro/main.go (2)

23-52: LGTM! Clean migration to klog.

The integration of klog with Cobra is correctly implemented, and using the standard library log package for fatal errors in main() is appropriate since no context is available at this point. The subcommands will handle contextual logging appropriately.


24-27: Review the klog v2 flag initialization pattern.

The glog compatibility check and klog.InitFlags(nil) create a separate FlagSet, which is not the recommended pattern for klog v2. According to klog v2 documentation, the correct approach for glog coexistence is klog.InitFlags(flag.CommandLine) (not nil), which allows glog and klog to share the same flag registry. The current pattern suggests either: (1) glog is no longer used and this code is legacy, or (2) there's an unintended separation of glog and klog flags. Clarify the intent and update to the correct klog v2 pattern if glog coexistence is needed, or remove this check entirely if glog dependencies have been eliminated.

pkg/db/db_session/test.go (1)

7-7: klog/v2 import is consistent with the logging migration

Importing k8s.io/klog/v2 here is aligned with the rest of the PR’s move away from the custom logger; nothing else to change in this file around imports.

test/upgrade/pkg/suite_test.go (1)

3-20: LGTM! Logging migration looks correct.

The switch from the custom logger to klog.Errorf is appropriate for this test suite context. The error reporting path maintains the same behavior.

pkg/api/metadata.go (2)

30-62: LGTM! Context-aware logging correctly implemented.

The per-request logger extraction via klog.FromContext(r.Context()) properly enables request correlation. The structured logging with logger.Error(err, message, "path", r.URL.Path) follows klog conventions.


65-99: Consistent implementation in SendAPIV1.

Same correct pattern applied here as in SendAPI.

pkg/services/resource.go (2)

161-200: LGTM! Well-structured contextual logging in UpdateStatus.

The logger enrichment with resourceID via WithValues enables effective tracing of status updates. The use of logger.V(4).Info for verbose event payload logging is appropriate for debug scenarios without cluttering production logs.


86-93: Correct error variable used.

Using eErr (the event creation error) instead of err (which was shadowed by the resource creation result) is correct here.

cmd/maestro/server/grpc_broker.go (3)

128-212: LGTM! Context-aware logging properly integrated in NewGRPCBroker.

The constructor now correctly:

  • Accepts context for logger derivation
  • Uses check(ctx, ...) for consistent error handling with Sentry reporting
  • Logs TLS configuration state with structured fields

214-232: Error handling correctly updated to use check().

The Start method now properly uses check(ctx, err, ...) for both listener creation and server startup errors, ensuring consistent Sentry reporting as noted in the previous review.


269-298: LGTM! PredicateEvent logging is appropriate.

Using logger.V(4).Info for the "resource deleted" path is correct for debug-level visibility without production log noise.

pkg/event/event.go (1)

41-57: LGTM! Registration logging is well-structured.

The use of structured logging with "id" and "source" fields enables effective client tracking.

cmd/maestro/server/logging/formatter.go (1)

8-11: LGTM! Interface updated for context-aware logging.

The LogFormatter interface now accepts klog.Logger as the first parameter, enabling implementations to use per-request loggers for any internal logging needs. This aligns with the PR's logging migration strategy.

cmd/maestro/server/routes.go (1)

18-42: LGTM! Routes function correctly propagates context.

The function now:

  • Accepts context for error handling via check(ctx, err, ...)
  • Wires the logger middleware with context via RegisterLoggerMiddleware(ctx, mainRouter)

The mock middleware usage is intentional as confirmed in past reviews (EnableJWT/EnableAuthz flags are deprecated).

cmd/maestro/server/controllers.go (2)

14-49: LGTM! Constructor correctly propagates context for logging.

The logger is extracted from context early and used for conditional setup logging at the appropriate verbosity level (V(4) for message broker configuration details).


58-77: LGTM! Start method properly establishes named logger scope.

Good patterns applied here:

  • Named logger with .WithName("maestro-controllers") for component identification in logs
  • Context enriched with logger via klog.NewContext(ctx, logger) for downstream propagation
  • Consistent structured logging for controller lifecycle events
cmd/maestro/server/server.go (2)

16-21: LGTM! Clean interface update for contextual logging.

The Server interface properly threads context.Context through Start and Serve methods, enabling per-request/per-operation logging throughout the server lifecycle.


31-38: LGTM! Proper context-based logging in error handler.

The check function correctly extracts the logger from context before logging the error. The existing Sentry integration and os.Exit(1) behavior is preserved, which is appropriate for fatal startup errors.

cmd/maestro/server/logging/writer.go (3)

8-10: LGTM! Constructor properly accepts and stores the logger.

The NewLoggingWriter constructor correctly accepts a klog.Logger parameter and initializes the struct with it, enabling per-request logging.


31-38: LGTM! Logging implementation is correct.

The log method properly uses verbosity level V(4) for info logs and structured error logging with the error object. The error message has been corrected per prior review feedback.


40-52: LGTM! Logger propagation to formatters is correct.

Both prepareRequestLog and prepareResponseLog correctly pass the logger to the formatter methods, aligning with the updated LogFormatter interface.

cmd/maestro/server/logging/formatter_json.go (2)

18-34: LGTM! Efficient conditional serialization based on log verbosity.

The logger.V(4).Enabled() check inside the formatter is a smart optimization—it avoids serializing request headers and body when verbose logging is disabled, even though the format method is always called. This prevents unnecessary work in production.


36-46: LGTM! Consistent verbosity check for response body.

Same pattern as request logging—body serialization is skipped when V(4) is not enabled.

cmd/maestro/server/logging/request_logging_middleware.go (1)

14-48: LGTM! Well-structured per-request logging middleware.

The middleware correctly:

  • Creates a per-request logger enriched with operation ID
  • Injects the logger into the request context for downstream handlers
  • Wraps the response writer to capture response details
  • Measures and logs elapsed time
  • Excludes noisy endpoints (/api/maestro) from logging
cmd/maestro/server/api_server.go (4)

39-43: LGTM! Constructor properly propagates context.

The NewAPIServer constructor correctly accepts context and passes it to routes(ctx) for middleware and handler setup.


63-82: LGTM! Authentication handler setup with context-aware error handling.

The check(ctx, err, msg) calls properly include context for logging. Note that the glog import is required here for OCM SDK's NewGlogLoggerBuilder compatibility—this is separate from the klog migration.


147-170: LGTM! Serve method with proper context-based logging.

The Serve method correctly:

  • Extracts the logger from context
  • Uses structured logging with key-value pairs ("port", ...)
  • Propagates context to the check function for error logging

179-198: LGTM! Start method correctly handles errors without bypassing defer.

The previous review concern about os.Exit(1) bypassing the deferred s.grpcServer.Stop() has been properly addressed—the code now uses return (line 190) to allow the defer to execute.

cmd/maestro/server/healthcheck_server.go (4)

78-85: Potential blocking issue after server termination.

If ListenAndServe returns due to an error (other than http.ErrServerClosed), line 79 logs "HealthCheck server terminated" but the code then blocks on <-ctx.Done() (line 82). If the context is not cancelled externally, this goroutine will block indefinitely.

Please verify that the caller always cancels the context when the server terminates unexpectedly, or consider restructuring to avoid blocking after the server has already stopped.


88-124: LGTM!

The pulse method correctly derives the logger from context and uses structured logging with appropriate key-value pairs for error logging.


126-173: LGTM!

The checkInstances method properly uses context-derived logging with structured key-value pairs for both info and error messages.


177-202: LGTM!

The healthCheckHandler correctly derives the logger from the request context and enriches it with instanceID. All response write errors are logged appropriately.

test/helper.go (3)

143-160: LGTM!

The constructor calls for NewHealthCheckServer, NewGRPCBroker, and related servers have been correctly updated to pass the context, aligning with the new context-aware signatures.


198-265: LGTM!

All server start/stop helper methods consistently use klog.FromContext(helper.Ctx) for logging lifecycle events at the appropriate verbosity level (V(4) for debug).


516-538: LGTM!

The CleanDB method correctly uses context-derived logging with structured key-value pairs for error messages, replacing the previous global logger pattern.

cmd/maestro/server/grpc_server.go (4)

48-53: LGTM!

The NewGRPCServer constructor correctly accepts a context as the first parameter and derives a logger for use in the initialization path.


266-361: LGTM!

The Subscribe method correctly derives the logger from context once and captures it in closures for use in goroutines. The context cancellation propagates properly, and the error handling pattern with sendErrCh is well-designed for unregistering subscribers on connection failures.


149-159: LGTM!

The Start method correctly derives a logger from context and uses structured logging for lifecycle and error messages.


167-194: LGTM!

The Publish method correctly derives a logger from context and uses appropriate verbosity levels - Info for context-level logging and V(4) for detailed event logging.

pkg/controllers/status_controller.go (3)

51-66: LGTM!

The Run method correctly derives a logger from context and uses context-aware wait functions for the periodic sync and worker goroutines.


104-106: LGTM!

The per-event logger enrichment with StatusEventID provides excellent traceability. The pattern of creating a new context with both the enriched logger and the event ID value is correct and consistent with the framework.


161-190: LGTM!

The syncStatusEvents method correctly uses context-derived logging and properly logs at different verbosity levels (V(2) for purge info, Error for failures).

pkg/controllers/framework.go (4)

88-104: LGTM!

The Run method correctly derives a logger from context, uses deferred shutdown, and properly employs context-aware wait functions for periodic sync and worker goroutines.


118-120: LGTM!

The per-event logger enrichment pattern is well-designed. Creating reqContext with both the enriched logger (klog.NewContext) and the event ID value (context.WithValue) ensures that all downstream operations have access to both structured logging and the event ID for tracing.


204-230: LGTM!

The processNextEvent method correctly derives a logger with the queue key and handles the reconciliation result appropriately - requeuing with rate limiting on failure and forgetting on success.


232-258: LGTM!

The syncEvents method correctly uses context-derived logging for the periodic sync operations. The pattern of purging reconciled events before syncing unreconciled ones, with appropriate error handling and metrics, is well-structured.

pkg/db/advisory_locks.go (2)

3-14: klog import looks appropriate; ensure module metadata is updated.

Importing k8s.io/klog/v2 here is consistent with the new contextual logging approach. Just make sure go.mod/go.sum are updated and tidied so this dependency is correctly pinned.


155-184: Contextual unlock logging and success-only metrics look correct.

Using klog.FromContext(ctx).WithValues("owner", uuid) plus structured fields on the error log ("lockID", "lockType") gives good observability, and the V(4) debug message for non-owner callers mirrors the prior low-verbosity behavior.

Moving UpdateAdvisoryUnlockCountMetric(lockType, "OK") and UpdateAdvisoryLockDurationMetric into the success branch ensures failed unlocks are no longer counted as OK or included in success-duration stats, which matches how the metrics helpers are intended to be used.

cmd/maestro/server/event_server.go (3)

75-89: Contextual startup/shutdown logging looks good

Using klog.FromContext(ctx) for Start/Stop messages keeps these logs tied to the caller’s context; behavior and control flow are unchanged and correct.


156-253: Status-update logging is now contextual and preserves behavior

handleStatusUpdate correctly pulls a logger from ctx and relies on the upstream context (enriched in the subscription) so that 404 skips and delete/update events are logged with the right structured fields; the functional behavior (404 short‑circuit, delete vs update branches) remains intact.


255-304: Per-event logging in broadcastStatusEvent is appropriately keyed

The logger derived via klog.FromContext(ctx).WithValues("resourceID", resourceID, "instanceID", instanceID, "eventID", eventID) and the Info calls for “skipping resource as it is not found” and “Broadcast the resource status” give clear, structured diagnostics without changing control flow or error handling.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (12)
pkg/db/db_session/test.go (1)

54-70: Logging backend switch in Init looks correct; consider structured logging optionally

Switching the two error paths in Init to klog.Error(err, "...") preserves the previous behavior of logging the error and returning early, without changing control flow. This is fine for a test factory. If you later want more consistent structured output with the rest of the codebase, you could move to klog.ErrorS(err, "..."), but it’s not required here.

cmd/maestro/server/metrics_server.go (2)

62-62: Polish the log message for consistency.

The message "Serving Metrics without TLS at" reads awkwardly. For consistency with line 59, consider "Serving Metrics without TLS on port" or simply "Serving Metrics without TLS".

Apply this diff:

-		logger.Info("Serving Metrics without TLS at", "port", env().Config.Metrics.BindPort)
+		logger.Info("Serving Metrics without TLS", "port", env().Config.Metrics.BindPort)

69-71: Consider accepting context in Stop() for consistent context propagation.

The Stop() method uses context.Background() while the rest of the file has been updated to accept and propagate context. For consistency with the PR's context-aware design, consider updating Stop() to accept a context parameter.

Example signature:

-func (s metricsServer) Stop() error {
-	return s.httpServer.Shutdown(context.Background())
+func (s metricsServer) Stop(ctx context.Context) error {
+	return s.httpServer.Shutdown(ctx)

Note: This would require updating the Server interface and all implementations.

pkg/services/resource.go (1)

3-7: Non-standard import ordering.

The klog/v2 import is placed between standard library imports (context and reflect), which violates Go's conventional import grouping. Standard library imports should be grouped together, followed by external packages.

 import (
 	"context"
-	"k8s.io/klog/v2"
 	"reflect"
 	"time"
 
 	cloudeventstypes "github.com/cloudevents/sdk-go/v2/types"
+	"k8s.io/klog/v2"
+
 	"github.com/openshift-online/maestro/pkg/dao"
pkg/dispatcher/noop_dispatcher.go (2)

3-7: Non-standard import ordering.

Same as in resource.go, the klog/v2 import should be grouped with external packages, not interspersed with standard library imports.

 import (
 	"context"
 	"fmt"
-	"k8s.io/klog/v2"
 	"strings"
 
 	"github.com/openshift-online/maestro/pkg/client/cloudevents"
+	"k8s.io/klog/v2"
+
 	"github.com/openshift-online/maestro/pkg/dao"

100-119: Consider propagating context to onInstanceDown.

This function uses context.TODO() while the rest of the file has migrated to context-based patterns. Since onInstanceUpdate has access to the logger but not a context, and this function is only called from there, consider either:

  1. Passing the logger as a parameter for potential future logging needs
  2. Storing context in the struct during Start for use in callbacks

This is a minor inconsistency that can be addressed in a follow-up.

pkg/db/db_session/default.go (1)

3-8: Non-standard import ordering.

Consistent with other files in this PR, the klog/v2 import should be grouped with external packages.

 import (
 	"context"
 	"database/sql"
 	"fmt"
-	"k8s.io/klog/v2"
 	"time"
 
 	"github.com/Azure/azure-sdk-for-go/sdk/azcore"
+	"k8s.io/klog/v2"
cmd/maestro/server/logging/formatter.go (1)

3-6: Consider grouping imports by convention.

Go convention typically places standard library imports before third-party imports. Consider reordering:

 import (
+	"net/http"
+
 	"k8s.io/klog/v2"
-	"net/http"
 )
cmd/maestro/server/controllers.go (1)

3-6: Remove stray blank line in import block.

There's an extra blank line after "context" that should be removed for cleaner formatting.

 import (
 	"context"
-	
 	"k8s.io/klog/v2"
cmd/maestro/server/logging/request_logging_middleware.go (1)

3-12: Consider organizing imports per Go conventions.

Standard library imports should be grouped separately from third-party imports with a blank line between groups.

 import (
+	"context"
 	"net/http"
 	"strings"
 	"time"
-	"context"
-	"github.com/gorilla/mux"
+
+	"github.com/gorilla/mux"
 	maestrologger "github.com/openshift-online/maestro/pkg/logger"
 	"k8s.io/klog/v2"
 )
cmd/maestro/server/logging/formatter_json.go (1)

36-46: Consider including response headers when V(4) is enabled.

The response header is explicitly set to nil in jsonResponseLog initialization (line 37), but ResponseInfo contains header data. If verbose logging should include response headers, consider adding them conditionally:

 func (f *jsonLogFormatter) FormatResponseLog(logger klog.Logger, info *ResponseInfo) (string, error) {
-	jsonlog := jsonResponseLog{Header: nil, Status: info.Status, Elapsed: info.Elapsed}
+	jsonlog := jsonResponseLog{Status: info.Status, Elapsed: info.Elapsed}
 	if logger.V(4).Enabled() {
+		jsonlog.Header = info.Header
 		jsonlog.Body = string(info.Body[:])
 	}

This is optional if response headers are intentionally excluded for privacy/security reasons.

cmd/maestro/servecmd/cmd.go (1)

40-48: Consider using klog.Fatal instead of log.Fatalf for consistency.

The initialization phase uses klog.Infof (line 42) and klog.Fatalf (line 46), but the import still includes the standard log package. If log is only used elsewhere (line 34), this is fine, but ensure consistency.

-	klog.Fatalf("Unable to initialize environment: %s", err.Error())
+	klog.Fatal("Unable to initialize environment: ", err)

Or keep as-is if the formatting is intentional.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between b4c0ca4 and 7f44cbd.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (51)
  • cmd/maestro/agent/cmd.go (1 hunks)
  • cmd/maestro/common/otlp_sdk.go (3 hunks)
  • cmd/maestro/environments/framework.go (7 hunks)
  • cmd/maestro/main.go (1 hunks)
  • cmd/maestro/migrate/cmd.go (2 hunks)
  • cmd/maestro/servecmd/cmd.go (4 hunks)
  • cmd/maestro/server/api_server.go (6 hunks)
  • cmd/maestro/server/auth_interceptor.go (3 hunks)
  • cmd/maestro/server/controllers.go (3 hunks)
  • cmd/maestro/server/event_server.go (9 hunks)
  • cmd/maestro/server/grpc_broker.go (7 hunks)
  • cmd/maestro/server/grpc_server.go (16 hunks)
  • cmd/maestro/server/healthcheck_server.go (8 hunks)
  • cmd/maestro/server/logging/formatter.go (1 hunks)
  • cmd/maestro/server/logging/formatter_json.go (3 hunks)
  • cmd/maestro/server/logging/logging.go (0 hunks)
  • cmd/maestro/server/logging/request_logging_middleware.go (1 hunks)
  • cmd/maestro/server/logging/writer.go (4 hunks)
  • cmd/maestro/server/metrics_server.go (2 hunks)
  • cmd/maestro/server/routes.go (3 hunks)
  • cmd/maestro/server/server.go (2 hunks)
  • go.mod (3 hunks)
  • pkg/api/error.go (5 hunks)
  • pkg/api/metadata.go (4 hunks)
  • pkg/auth/helpers.go (1 hunks)
  • pkg/client/cloudevents/source_client.go (4 hunks)
  • pkg/client/grpcauthorizer/kube_authorizer.go (2 hunks)
  • pkg/controllers/event_filter.go (3 hunks)
  • pkg/controllers/framework.go (9 hunks)
  • pkg/controllers/framework_test.go (2 hunks)
  • pkg/controllers/status_controller.go (7 hunks)
  • pkg/db/advisory_locks.go (8 hunks)
  • pkg/db/context.go (2 hunks)
  • pkg/db/db_session/default.go (4 hunks)
  • pkg/db/db_session/test.go (2 hunks)
  • pkg/db/migrations.go (2 hunks)
  • pkg/db/transaction_middleware.go (2 hunks)
  • pkg/dispatcher/hash_dispatcher.go (8 hunks)
  • pkg/dispatcher/noop_dispatcher.go (4 hunks)
  • pkg/errors/errors.go (0 hunks)
  • pkg/event/event.go (5 hunks)
  • pkg/handlers/framework.go (2 hunks)
  • pkg/logger/logger.go (0 hunks)
  • pkg/logger/zap.go (0 hunks)
  • pkg/services/generic.go (3 hunks)
  • pkg/services/resource.go (6 hunks)
  • test/e2e/pkg/suite_test.go (3 hunks)
  • test/helper.go (11 hunks)
  • test/integration/integration_test.go (1 hunks)
  • test/mocks/workserver/main.go (5 hunks)
  • test/upgrade/pkg/suite_test.go (2 hunks)
💤 Files with no reviewable changes (4)
  • pkg/errors/errors.go
  • cmd/maestro/server/logging/logging.go
  • pkg/logger/zap.go
  • pkg/logger/logger.go
🚧 Files skipped from review as they are similar to previous changes (16)
  • pkg/db/transaction_middleware.go
  • test/e2e/pkg/suite_test.go
  • pkg/handlers/framework.go
  • cmd/maestro/environments/framework.go
  • cmd/maestro/server/server.go
  • cmd/maestro/main.go
  • pkg/auth/helpers.go
  • pkg/db/migrations.go
  • pkg/db/advisory_locks.go
  • cmd/maestro/migrate/cmd.go
  • test/mocks/workserver/main.go
  • pkg/event/event.go
  • pkg/db/context.go
  • test/upgrade/pkg/suite_test.go
  • test/integration/integration_test.go
  • pkg/services/generic.go
🧰 Additional context used
🧬 Code graph analysis (11)
pkg/client/cloudevents/source_client.go (4)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/services/resource.go (1)
  • ResourceService (26-39)
pkg/api/metadata_types.go (1)
  • Meta (51-56)
pkg/client/cloudevents/codec.go (1)
  • Codec (17-19)
cmd/maestro/server/routes.go (2)
pkg/auth/auth_middleware_mock.go (1)
  • AuthMiddlewareMock (7-7)
cmd/maestro/server/logging/request_logging_middleware.go (1)
  • RegisterLoggerMiddleware (14-49)
cmd/maestro/server/logging/writer.go (1)
cmd/maestro/server/logging/formatter.go (1)
  • LogFormatter (8-11)
pkg/controllers/event_filter.go (1)
pkg/controllers/framework.go (1)
  • EventID (38-38)
cmd/maestro/server/grpc_broker.go (2)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
cmd/maestro/server/controllers.go (4)
cmd/maestro/server/event_server.go (1)
  • EventServer (24-42)
pkg/db/context.go (1)
  • NewContext (13-22)
cmd/maestro/environments/types.go (1)
  • Database (31-33)
pkg/db/session.go (1)
  • SessionFactory (13-21)
cmd/maestro/server/logging/formatter.go (1)
cmd/maestro/server/logging/responseinfo.go (1)
  • ResponseInfo (5-10)
cmd/maestro/server/logging/formatter_json.go (1)
cmd/maestro/server/logging/responseinfo.go (1)
  • ResponseInfo (5-10)
cmd/maestro/server/api_server.go (2)
cmd/maestro/server/server.go (1)
  • Server (16-21)
cmd/maestro/server/grpc_server.go (2)
  • NewGRPCServer (48-146)
  • GRPCServer (36-45)
cmd/maestro/server/grpc_server.go (4)
pkg/services/resource.go (1)
  • ResourceService (26-39)
pkg/event/event.go (1)
  • EventBroadcaster (22-30)
pkg/config/grpc_server.go (1)
  • GRPCServerConfig (10-35)
pkg/client/grpcauthorizer/interface.go (1)
  • GRPCAuthorizer (6-32)
pkg/controllers/framework.go (3)
pkg/db/context.go (1)
  • NewContext (13-22)
pkg/api/event.go (1)
  • EventType (9-9)
pkg/api/openapi/model_error.go (1)
  • Error (21-28)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Red Hat Konflux / maestro-on-pull-request
  • GitHub Check: Red Hat Konflux / maestro-e2e-on-pull-request
  • GitHub Check: e2e-with-istio
  • GitHub Check: e2e-broadcast-subscription
  • GitHub Check: migration
  • GitHub Check: e2e
  • GitHub Check: e2e-grpc-broker
🔇 Additional comments (79)
cmd/maestro/agent/cmd.go (1)

66-76: LGTM – comment typo fixed with no behavioral impact

The updated comment removes the duplicated word and better reflects intent; no code or behavior changes involved here.

pkg/dispatcher/hash_dispatcher.go (4)

76-90: LGTM! Proper contextual logging implementation.

The function correctly extracts the logger from context and uses structured logging throughout. The context propagation and error handling are appropriate.


100-133: LGTM! Context and logger properly threaded through.

The function signature correctly accepts both context and logger parameters, and they are properly used throughout. The change from context.TODO() to the passed context parameter is exactly what was needed. The verbose logging at V(4) level is appropriate for detailed consumer set updates.


151-203: LGTM! Comprehensive contextual logging throughout.

The function properly extracts the logger from context and uses it consistently for both error and verbose logging. The call to updateConsumerSet correctly passes both context and logger parameters.


207-241: LGTM! Previous concern about rate limiter properly addressed.

The function correctly uses contextual logging throughout. The addition of the else block with d.workQueue.Forget(key) on line 237 properly addresses the previous review concern about clearing the rate limiter's backoff state after successful resync.

pkg/db/db_session/test.go (1)

3-8: klog/v2 import usage is appropriate

The added k8s.io/klog/v2 import is used below and aligns with the project-wide migration to klog; no issues here.

pkg/client/cloudevents/source_client.go (5)

8-8: LGTM! Klog import added.

The import of k8s.io/klog/v2 is appropriate for the contextual logging migration.


58-88: LGTM! Contextual logging properly implemented.

The OnCreate method correctly implements the klog contextual logging pattern:

  • Logger is extracted from context and enriched with resourceID
  • Context is updated with the enriched logger for downstream calls
  • All logging statements use the contextual logger with appropriate levels (Info/Error)

91-115: LGTM! Consistent with OnCreate.

The OnUpdate method follows the same contextual logging pattern as OnCreate, ensuring consistency across the codebase.


118-146: LGTM! Consistent implementation.

The OnDelete method maintains the same contextual logging pattern, providing consistency across all CRUD operations.


153-164: LGTM! Appropriate contextual values.

The Resync method correctly uses consumers as the contextual value, which is appropriate for this operation. The logging pattern remains consistent with the rest of the file.

cmd/maestro/server/metrics_server.go (4)

10-10: LGTM!

The klog/v2 import is correctly added to support contextual logging throughout this file.


44-45: LGTM!

The empty Serve implementation with unused parameters is appropriate since this metrics server uses the Start() method directly rather than the Listen/Serve pattern.


47-61: LGTM!

The context propagation and klog integration are correctly implemented. The logger is properly derived from context, and Line 59 now correctly references env().Config.Metrics.BindPort, addressing the previous review comment.


65-66: LGTM!

Context propagation to the check function and termination logging are correctly implemented.

go.mod (4)

1-62: Verify Zap imports have been removed from codebase.

Zap has been moved to indirect dependency, which is correct. Confirm that all direct Zap imports and usage have been replaced with klog throughout the codebase. Search for any remaining occurrences of go.uber.org/zap imports and zap.* function calls (NewProduction, NewDevelopment, NewLogger, SugaredLogger) in Go source files. If no results are found, the migration is complete.


56-56: Klog v2.130.1 is a valid, widely-used Kubernetes version with no known compatibility issues.

Web search confirms that k8s.io/klog/v2 v2.130.1 is the latest v2 release, published on pkg.go.dev, and is compatible with Kubernetes Go packages. The v2 API maintains semantic stability across the v2.x series. No security advisories were identified for this version. This version is routinely used in Kubernetes-related projects and is suitable for the v0.33.4 Kubernetes dependencies (k8s.io/api, k8s.io/client-go, k8s.io/apimachinery) already specified in the module.


3-3: No action required. Go version 1.24.4 is a valid, released version. As of December 2025, go1.25.5 is the latest stable release, but 1.24.4 remains a supported version in the 1.24 series and is appropriate for go.mod specification.

Likely an incorrect or invalid review comment.


93-93: Confirm complete removal of viper dependency.

The PR should have removed spf13/viper from direct requires per the PR objectives. Verify that viper is not present in the direct require block and has been completely removed from the codebase (not just moved to indirect). This includes checking for any remaining imports or usage patterns in the code.

pkg/controllers/event_filter.go (1)

46-59: LGTM! Clean migration to contextual logging.

Good use of the EventID constant from framework.go for structured field naming, and the logger is correctly derived from context with appropriate values attached.

pkg/api/metadata.go (1)

34-35: LGTM! Consistent per-request contextual logging.

The logger is correctly derived from r.Context() in both SendAPI and SendAPIV1, with appropriate structured fields for error paths. Sentry integration is preserved.

Also applies to: 58-58, 69-70, 95-96

cmd/maestro/server/auth_interceptor.go (2)

100-114: LGTM! Contextual logging in unary interceptor.

The logger is correctly derived from the gRPC context, and error logging is appropriately placed before returning errors for authentication failures.


160-174: LGTM! Contextual logging in stream interceptor.

Correctly uses ss.Context() to derive the logger for the stream interceptor, maintaining consistency with the unary interceptor pattern.

pkg/api/error.go (2)

42-43: LGTM! Consistent error logging across HTTP handlers.

Logger is correctly derived from r.Context() in all error write paths, with structured "path" field for debugging context. Sentry integration is preserved.

Also applies to: 64-65, 76-77


108-110: Appropriate use of global klog.Error in init().

Using klog.Error() directly is correct here since init() runs before any request context exists. The error leads to os.Exit(1), so context-based logging isn't applicable.

pkg/client/grpcauthorizer/kube_authorizer.go (1)

46-54: LGTM! Well-structured contextual logging for AccessReview.

The logger is correctly derived from context with distinct, well-named structured fields. Using V(4) for this debug-level tracing is appropriate to avoid log noise in production.

pkg/services/resource.go (2)

161-200: LGTM!

The contextual logging implementation is well-structured. The logger is correctly derived from context with resourceID for traceability, and V(4) is appropriately used for verbose event payload logging.


86-93: LGTM!

The change from err to eErr correctly references the event creation error variable declared on line 86, fixing the error handling to properly propagate event creation failures.

pkg/dispatcher/noop_dispatcher.go (1)

35-48: LGTM!

The logger is correctly captured from context at startup and passed to the onInstanceUpdate callback, ensuring consistent logging context across async operations.

pkg/db/db_session/default.go (2)

141-167: LGTM!

The logging implementation in waitForNotification is well-structured with appropriate verbosity levels: V(4) for routine notification events and Info for significant state changes like connection loss.


170-177: LGTM!

The logger is correctly captured in the closure for the plog callback, ensuring structured logging with context is available when the listener reports state changes.

pkg/controllers/status_controller.go (3)

51-66: LGTM!

The Run method correctly implements context-driven lifecycle management with proper logger derivation and context-aware scheduling via wait.JitterUntilWithContext and wait.UntilWithContext.


104-106: LGTM!

The context construction pattern correctly combines klog.NewContext for the enriched logger with context.WithValue for the event ID, ensuring both are available to downstream handlers.


161-190: LGTM!

The syncStatusEvents method has proper context-aware logging with appropriate verbosity levels (V(2) for detailed operational info) and consistent error handling.

pkg/controllers/framework.go (4)

88-104: LGTM!

The Run method follows the same well-structured pattern as StatusController, with proper context-driven lifecycle management and context-aware scheduling functions.


204-230: LGTM!

The processNextEvent method correctly handles queue operations with proper error logging. While the logger at line 214 adds the key field only for local use, this is acceptable since handleEvent independently enriches its context with EventID.


118-121: LGTM!

The handleEvent method correctly creates a per-event logger enriched with EventID and properly constructs a request context that carries both the logger and the event ID value for downstream handlers.


232-258: LGTM!

The syncEvents method properly implements context-aware logging and database operations with appropriate error handling and metrics tracking.

pkg/controllers/framework_test.go (2)

87-89: LGTM!

The test correctly passes the existing ctx to handleEvent, aligning with the updated context-aware signature. The context was already properly initialized at line 54.


198-200: LGTM!

Same pattern as the first test—context is properly threaded through to handleEvent calls.

cmd/maestro/server/logging/formatter.go (1)

8-11: LGTM!

The interface now accepts a per-context logger, enabling contextual logging throughout the request/response formatting pipeline. This aligns well with the klog migration.

cmd/maestro/server/routes.go (3)

18-23: LGTM!

The function now properly accepts and propagates context. The check function receives context for contextual error handling/logging.


30-31: Auth middleware uses mocks unconditionally (confirmed intentional).

Per past review discussion, EnableJWT and EnableAuthz flags are deprecated, so unconditional mock usage is the intended behavior.


40-41: LGTM!

The logging middleware now receives context to create per-request loggers with operation IDs, aligning with the klog contextual logging pattern.

cmd/maestro/common/otlp_sdk.go (3)

14-17: LGTM!

The klog import is properly placed with other third-party imports. The errors alias for weberr avoids conflict with standard library.


26-27: LGTM!

Function signature updated to accept the klog logger for contextual logging. The initialization message is properly logged.


59-61: LGTM!

The error handler correctly uses klog's Error(err, msg) signature to log OpenTelemetry errors.

cmd/maestro/server/controllers.go (3)

14-16: LGTM!

Constructor properly extracts the logger from context for contextual logging during initialization.


26-27: LGTM!

Appropriate use of verbose logging (V(4)) for debug information about the message broker setup.


59-76: LGTM!

The Start method properly creates a named logger for the controllers subsystem, propagates it via context to child goroutines, and logs all lifecycle events. The pattern of WithName + NewContext enables hierarchical logging with proper context propagation.

cmd/maestro/server/logging/writer.go (1)

1-53: LGTM! Clean migration to klog-based per-request logging.

The implementation correctly:

  • Passes the logger through the constructor and stores it in the struct
  • Uses V(4).Info for verbose request/response logging
  • Properly delegates the logger to formatter methods matching the updated LogFormatter interface
cmd/maestro/server/event_server.go (2)

77-117: LGTM! Proper context-aware logging with resource enrichment.

Good patterns observed:

  • Logger enriched with resourceID and action via WithValues
  • Context updated with the enriched logger for downstream use
  • Structured logging follows klog conventions correctly

163-253: LGTM! Consistent logging in status update handlers.

The handleStatusUpdate and broadcastStatusEvent functions properly:

  • Derive loggers from context
  • Enrich with relevant identifiers (resourceID, instanceID, eventID)
  • Use structured key-value logging for status events
cmd/maestro/server/healthcheck_server.go (4)

29-50: LGTM! Constructor updated for context-aware middleware registration.

The RegisterLoggerMiddleware(ctx, router) call correctly wires the logging middleware to the router, enabling per-request context-bound logging for the healthcheck endpoints.


52-87: LGTM! Proper context propagation in Start method.

Good implementation:

  • Logger enriched with instanceID and stored back in context
  • Context propagated to pulse and checkInstances goroutines via wait.UntilWithContext
  • Shutdown logging uses the enriched logger

89-125: LGTM! Appropriate verbosity levels in pulse method.

The V(4).Info for "Creating new maestro instance" is appropriate for debug-level operational messages, keeping regular logs clean while allowing verbose debugging when needed.


177-204: LGTM! Request-scoped logging in health check handler.

Correctly derives logger from r.Context() to leverage any per-request context enrichment from the middleware.

cmd/maestro/server/logging/request_logging_middleware.go (1)

14-49: LGTM! Well-structured middleware with proper context propagation.

The middleware correctly:

  • Derives logger from the parent context and enriches with operation ID
  • Creates a new request context with the enriched logger
  • Passes the enriched context to downstream handlers
  • Conditionally logs request/response based on path to reduce noise
cmd/maestro/server/grpc_broker.go (3)

127-212: LGTM! Comprehensive context integration in gRPC broker constructor.

The constructor properly:

  • Derives logger from context for startup messages
  • Uses check(ctx, ...) for consistent error handling with Sentry integration
  • Logs TLS configuration status with structured key-value pairs

214-232: LGTM! Improved error handling in Start method.

Good changes:

  • Uses check(ctx, err, ...) instead of direct os.Exit(1) for consistent error reporting
  • Context-aware logging for shutdown message with bind address

266-298: LGTM! Appropriate verbosity for debug-level reconciliation logs.

Using V(4).Info for "The resource has been deleted, mark the event as reconciled" is appropriate as this is operational debugging information that shouldn't clutter regular logs.

cmd/maestro/server/logging/formatter_json.go (1)

18-34: LGTM! Efficient verbosity gating with klog.

Using logger.V(4).Enabled() to conditionally include request headers and body is an efficient pattern—it avoids processing verbose data when the log level won't emit it.

cmd/maestro/server/api_server.go (2)

39-143: LGTM! Proper context propagation through API server construction.

Good implementation:

  • Context passed to routes(ctx) for middleware registration
  • Context passed to NewGRPCServer(ctx, ...) for consistent logging
  • Error handling uses check(ctx, ...) for Sentry integration

145-198: LGTM! Clean lifecycle management with context-aware logging.

The Serve and Start methods correctly:

  • Derive loggers from context
  • Use structured key-value logging for port information
  • Handle errors gracefully (return instead of os.Exit, addressing past review)
  • Propagate context to gRPC server startup
cmd/maestro/servecmd/cmd.go (3)

52-56: LGTM! Proper root logger and context initialization.

Good pattern for establishing the logging foundation:

  • Creates a named logger with klog.NewKlogr().WithName("maestro-server")
  • Initializes context with cancellation
  • Stores logger in context for downstream propagation

113-117: LGTM! Correct error handling for tracing shutdown.

The shutdown error is now properly captured and logged as shutdownErr, addressing the previous review feedback.


60-82: LGTM! Consistent logging across broker type setup paths.

Both gRPC and message queue paths now use the context-derived logger with proper structured logging for configuration messages.

cmd/maestro/server/grpc_server.go (5)

149-159: LGTM - Start method correctly implements contextual logging.

The method properly:

  • Accepts context.Context as a parameter
  • Derives a logger from the context
  • Uses the context-derived logger for all log statements

168-194: LGTM - Publish method logging correctly uses context.

The method properly derives a logger from the incoming RPC context and uses it for event logging. The use of V(4) for detailed event logging is appropriate.


243-361: LGTM - Subscribe method properly implements contextual logging.

The method correctly:

  • Derives a logger from the context (created via context.WithCancel from the RPC context)
  • Uses the logger throughout the method, including in goroutines and callbacks
  • Threads context through to WritePBMessage and Unregister calls
  • The Register callback correctly captures the logger in its closure

445-470: LGTM - respondResyncStatusRequest correctly uses contextual logging.

The method properly derives a logger from the context and uses it for logging.


48-146: Verify the check() function signature matches the calling pattern.

The constructor changes appear sound—context is threaded through TLS setup error paths via consistent check(ctx, ...) calls, and the logger is properly derived via klog.FromContext(ctx). However, the check() function definition must be verified to confirm it accepts context.Context as the first parameter, followed by error and message arguments, as the usage pattern suggests.

test/helper.go (7)

143-158: LGTM - Server constructors properly updated to accept context.

The helper correctly passes ctx to NewHealthCheckServer and NewGRPCBroker, aligning with the PR's context propagation changes.


198-209: LGTM - startAPIServer correctly implements contextual logging.

The method properly:

  • Derives a logger from helper.Ctx
  • Passes context to NewAPIServer constructor
  • Passes context to Start method
  • Uses the context-derived logger for all log statements

218-242: LGTM - Server start methods correctly implement contextual logging.

Both startMetricsServer and startHealthCheckServer properly:

  • Derive a logger from helper.Ctx
  • Pass context to the Start method
  • Use the context-derived logger for all log statements

249-265: LGTM - Event server and broadcaster start methods correctly implement contextual logging.

Both startEventServer and startEventBroadcaster properly:

  • Derive a logger from helper.Ctx
  • Pass context to the Start method
  • Use the context-derived logger for all log statements

362-374: LGTM - Restart methods correctly use contextual logging.

Both RestartServer and RestartMetricsServer properly derive a logger from helper.Ctx and use it for logging.


376-396: LGTM - Reset method correctly implements contextual logging.

The method properly derives a logger from helper.Ctx and uses it. The typo fix ("Resetting" instead of "Reseting") has already been addressed.


516-538: LGTM - CleanDB correctly uses contextual logging.

The method properly derives a logger from helper.Ctx and uses it for error logging in the database cleanup loop.

kubeConfig, err := clientcmd.BuildConfigFromFlags("", e.Config.GRPCServer.GRPCAuthorizerConfig)
if err != nil {
log.Warnf("Unable to load kubeconfig from file %s: %v, falling back to in-cluster config", e.Config.GRPCServer.GRPCAuthorizerConfig, err)
klog.V(4).Infof("Unable to load kubeconfig from file %s: %v, falling back to in-cluster config", e.Config.GRPCServer.GRPCAuthorizerConfig, err)
Copy link
Contributor

Choose a reason for hiding this comment

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

should be klog.Info

log.Infof("received action %s for resource %s", action, resource.ID)
logger := klog.FromContext(ctx).WithValues("resourceID", resource.ID, "action", action)
logger.Info("received action for resource")
ctx = klog.NewContext(ctx, logger)
Copy link
Contributor

Choose a reason for hiding this comment

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

why reset ctx here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it is to set logger into the ctx, any following func can get logger with the above values


// broadcast the resource status to subscribers
log.Infof("Broadcast the resource status, id=%s, source=%s, statusEventType=%s", resource.ID, resource.Source, statusEvent.StatusEventType)
logger.Info("Broadcast the resource status", "statusEventType", statusEvent.StatusEventType)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
logger.Info("Broadcast the resource status", "statusEventType", statusEvent.StatusEventType)
logger.Info("Broadcast the resource status", "resoruceSource", resource.Source, "statusEventType", statusEvent.StatusEventType)

// if the resource is not found, it indicates the resource has been handled by other instances.
if svcErr.Is404() {
log.Debugf("The resource %s has been deleted, mark the event as reconciled", evt.SourceID)
logger.V(4).Info("The resource has been deleted, mark the event as reconciled", "source", evt.SourceID)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
logger.V(4).Info("The resource has been deleted, mark the event as reconciled", "source", evt.SourceID)
logger.V(4).Info("The resource has been deleted, mark the event as reconciled", "resourceID", evt.SourceID)

here the event source id should be resource id

Copy link
Contributor Author

Choose a reason for hiding this comment

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

evt.SourceID should this be also changed to resourceID?

Copy link
Contributor

Choose a reason for hiding this comment

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

no, because here is the spec event, we use soruceId as the resourceID ...

log.Infof("receive the event from client, %s", evt.Context)
log.Debugf("receive the event from client, evt=%s", evt)
logger.Info("receive the event from client", "context", evt.Context)
logger.V(4).Info("receive the event from client", "event", evt)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
logger.V(4).Info("receive the event from client", "event", evt)
if logger.V(4).Enabled() {
logger.V(4).Info("receive the event from client", "event", evt)
}

log.Infof("send the event to status subscribers, %s", evt.Context)
log.Debugf("send the event to status subscribers, evt=%s", evt)
logger.Info("send the event to status subscribers", "context", evt.Context)
logger.V(4).Info("send the event to status subscribers", "event", evt)
Copy link
Contributor

@skeeey skeeey Dec 5, 2025

Choose a reason for hiding this comment

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

Suggested change
logger.V(4).Info("send the event to status subscribers", "event", evt)
if logger.V(4).Enabled() {
logger.V(4).Info("send the event to status subscribers", "event", evt)
}

if !ok {
// ignore the resource that is not on the source, but exists on the maestro, wait for the source deleting it
log.Infof("The resource %s is not found from the maestro, ignore", obj.GetUID())
logger.Info("The resource is not found from the maestro, ignore", "objectID", obj.GetUID())
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
logger.Info("The resource is not found from the maestro, ignore", "objectID", obj.GetUID())
logger.Info("The resource is not found from the maestro, ignore", "resourceID", obj.GetUID())

Signed-off-by: Jian Qiu <[email protected]>
Copy link
Contributor

@clyang82 clyang82 left a comment

Choose a reason for hiding this comment

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

LGTM

@clyang82 clyang82 merged commit d0b44e2 into openshift-online:main Dec 5, 2025
11 checks passed
@qiujian16 qiujian16 deleted the klog branch December 5, 2025 07:01
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.

3 participants