-
Notifications
You must be signed in to change notification settings - Fork 29
Use klog's contextual logging #424
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughReplaces 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
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)
Estimated code review effort🎯 5 (Critical) | ⏱️ ~150 minutes Areas needing extra attention:
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro Cache: Disabled due to data retention organization setting Knowledge base: Disabled due to 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (1)
🧰 Additional context used🧬 Code graph analysis (3)cmd/maestro/server/event_server.go (3)
cmd/maestro/server/grpc_server.go (4)
cmd/maestro/server/grpc_broker.go (3)
⏰ 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)
🔇 Additional comments (11)
Comment |
There was a problem hiding this 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 usesklog.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
logimport on line 6 can be removed.pkg/db/db_session/test.go (1)
77-79:initDatabasecan hang in an infinite loop on connection errorThe loop never re-executes
dbx.Exec; if the first call returns an error,errstays 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 ServerNameIn
InitializeSentry:hostname, err := os.Hostname() if err != nil && hostname != "" { options.ServerName = hostname }This only sets
ServerNamewhenos.Hostname()returns an error, which is the opposite of what you want. It should setServerNamewhen the call succeeds (andhostnameis 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
logConfigFileandvarLogLevelare 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 actualctxparameter 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
ctxparameter is available in this function, consider usingklog.FromContext(ctx)instead of the globalklog.Infoffunctions. 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 fieldsUsing
k8s.io/klog/v2withlogger := klog.FromContext(listCtx.ctx)andlogger.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 foronInstanceUpdateif you can pass a context
onInstanceUpdatenow uses the package-levelklog.Infof/klog.Errorf, while the rest of the file usesklog.FromContext(ctx)+ a contextual logger. That mix is fine functionally, but slightly inconsistent.If the
NewListenerAPI can be evolved to pass acontext.Contextinto the callback, you could switchonInstanceUpdateto:
- Accept a
ctx context.Contextparameter, 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 structuredklog.ErrorSinstead of formattedErrorfTo 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
ErrorSis 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 pathCurrently, when
NewContextfails,operationIDis derived fromctxeven though the context creation failed. Whileklog.FromContext(ctx)is safe (it falls back to the global logger if the context is nil or has no logger), usingr.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 requestloggeris only used in the error branch, so instantiating it after checkingerris a minor optimizationA 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 inwaitForNotificationlooks good; consider enriching the ping‑failure logUsing
logger := klog.FromContext(ctx)once and reusing it through the loop is a solid pattern, and the addedchannel/extrafields improve observability. For the ping failure case you might want more consistency and severity:
- Include the
channelfield so all listener recreation paths are filterable by channel.- Consider using
Errorinstead ofInfofor 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.Errorsignature 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 hereSwitching to
klog.Fatalfpreserves the previous fatal-exit behavior and looks fine. Longer term, you might want to plumb acontext.ContextintoMigrateToand use a contextual logger instead ofcontext.Background(), but that can be deferred.pkg/db/context.go (1)
26-58: Contextual logging usage is correct; minor nit on error constructionUsing
klog.FromContext(ctx)andlogger.Info/Errorhere 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(orErrorS) 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 messageDeriving both the logger and
operationIDfromctxhere is aligned with the rest of the PR and looks correct. One small improvement: instead oflogger.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 payloadUsing a context-derived logger here and splitting 4xx as Info vs others as Error is sound. If
*errors.ServiceErrorcontains 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 stdlog.Fatalfand klog: consider consolidating on klog
Initializenow logs startup and several info/debug messages via klog but still useslog.Fatalffor fatal error paths (unknown env, Visit* failures, etc.), andTeardownalso useslog.Fatalf. Functionally this works, but for consistency with the rest of the PR you may want to swap these toklog.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 structuredErrorSover deprecatedklog.Errorin initThe panic-body initialization fallback currently does:
klog.Error(err) sentry.CaptureException(err) os.Exit(1)Per the klog/v2 docs, the global
Errorhelper is deprecated in favor ofErrorS(or a contextualLogger.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 inupdateConsumerSetinstead ofcontext.TODO()
checknow derives a contextual logger and passes it intoupdateConsumerSet, which is good. InsideupdateConsumerSet, you still call:consumers, err := d.consumerDao.All(context.TODO())Given
checkalready has actx, it’d be cleaner and more cancellable to either:
- Change the signature to
updateConsumerSet(ctx context.Context, logger klog.Logger)and passctxthrough toconsumerDao.All, or- Make
updateConsumerSetderive its own logger fromctxand drop theloggerparameter.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 messagesBoth in
resyncOnReconnectandprocessNextResync, 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/v2import on line 5 is placed between standard library imports (flagandos). 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/v2import 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 usingklog.Fatalfor consistency.Since the codebase is migrating to klog, using
klog.Fatalorklog.Fatalfhere 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/v2import is placed between standard library imports (contextandos), 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/v2is 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/v2import 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/v2import 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.Loggerdoesn't expose aWarningmethod directly, consider either removing the prefix or usinglogger.V(0).Infowith 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 errorcmd/maestro/servecmd/cmd.go (1)
77-78: Consider usingklog.Fatalfor fatal errors.The pattern of
logger.Errorfollowed byos.Exit(1)works, butklog.Fatalorklog.Fatalfprovides 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 inNewControllersServer.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/v2import 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/v2import 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/v2import 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 tohandleEventfor consistency.The logger at line 214 enriches with
"key", but the originalctx(without this enrichment) is passed tohandleEvent, which then creates its own logger withEventID. 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
handleEventalready enriches the logger withEventID(which equalskey), 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
⛔ Files ignored due to path filters (1)
go.sumis 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.Fatalfor 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.Errorftoklog.Errorfis correct. Note that contextual logging (klog.FromContext(ctx)) is not applicable here since theReportAfterSuitecallback 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.1is 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, andgoogle.golang.org/genprotoall 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
OnUpdatemethod follows the same correct klog contextual logging pattern asOnCreate, maintaining consistency across the codebase.
117-146: LGTM!The
OnDeletemethod consistently applies the klog contextual logging pattern, maintaining uniformity withOnCreateandOnUpdate.
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 withresourceID, and re-attaching to context. However, this pattern depends on callers providing contexts with initialized loggers viaklog.NewContext(). Verify that all callers ofOnCreateproperly initialize their contexts with a logger before invocation to ensure the logging enrichment works as intended.
152-164: LGTM!The
Resyncmethod correctly applies the klog contextual logging pattern with appropriate enrichment (consumersinstead ofresourceID), 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 migrationImporting
k8s.io/klog/v2here matches the PR’s move to contextual klog usage and looks correct.pkg/dispatcher/noop_dispatcher.go (1)
6-6: Contextual klog usage inStart/resyncOnReconnectlooks goodUsing
klog.FromContext(ctx)and the logr-stylelogger.Info/logger.Errorcalls is consistent with klog v2’s contextual logging and correctly tied to the lifecycle ofctx(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 correctUsing
k8s.io/klog/v2here 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 globallyThe
k8s.io/klog/v2import is correct. Verify that klog's contextual logging is initialized once during startup (typically viaklog.SetLogger(klog.NewKlogr())or similar in your main/init) so thatklog.FromContext(ctx)uses your structured backend instead of the bare global logger. Check for klog initialization patterns likeInitFlags,SetLoggerWithOptions, orEnableContextualLoggingelsewhere in the codebase to confirm this is in place.pkg/api/error.go (1)
38-79: HTTP error handlers: contextual logging is wired correctlyUsing
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 observabilityThe switch to a context-derived logger in
NewAdvisoryLock,NewNonBlockingLock, andUnlockis correct and the structured fields (owner,lockID,lockType) inUnlockshould 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.Infofis appropriate here. SinceTestMaindoesn't have a request context, usingklog.Infofdirectly (rather thanklog.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 theLogFormatterinterface (fromformatter.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
NewLoggingWriterand storing it in the struct ensures consistent contextual logging throughout the request lifecycle.
31-38: LGTM!Good logging pattern:
V(4).Infofor debug-level successful logs andError(err, msg)for error conditions. The verbosity level is consistent withformatter_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.Contextparameter and its use incheck()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 signaturehandleEvent(ctx context.Context, id string).
198-200: LGTM!Consistent context propagation matching the updated
handleEventsignature.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
checkfunction 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
WithValuesto enrich the logger withresourceIDandaction, and proper context propagation viaklog.NewContext.
255-295: LGTM!The
broadcastStatusEventfunction 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
Startmethod 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
Registermethod properly accepts context and uses structured logging with relevant fields.
60-74: LGTM!Good use of
WithValuesto pre-attach theidfield to the logger for consistent logging throughout the method.
82-106: LGTM!The
Startmethod properly initializes the logger from context and uses structured logging withresourceIDfor 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.Ctxand the context is properly passed toNewAPIServerandStart. 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
NewAPIServerfunction correctly accepts a context parameter and propagates it toroutes(ctx)and later toNewGRPCServer. This ensures consistent context-based logging throughout the API server lifecycle.
180-193: LGTM on context-aware server lifecycle.The
Startmethod correctly obtains a logger from context, passes the context to the gRPC server'sStartmethod, and propagates it toServe. 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 viaklog.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
Runmethod correctly useswait.JitterUntilWithContextandwait.UntilWithContextfor context-aware periodic execution and worker management. The shutdown is handled by waiting onctx.Done().pkg/controllers/framework.go (2)
88-104: LGTM on context-aware controller lifecycle.The
Runmethod correctly uses context-aware utilities (JitterUntilWithContext,UntilWithContext) and properly shuts down by waiting onctx.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 viaklog.NewContext, and adding theEventIDas a context value is consistent withStatusControllerand 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
resourceServicemethods.
149-159: Context-aware Start method looks good.The
Startmethod now acceptscontext.Contextand properly extracts the logger for startup and error logging. This is a breaking API change—ensure all call sites ofGRPCServer.Start()have been updated to pass a context parameter.
77-116: Verify thecheck()function signature.Multiple calls to
check()have been updated to passcontext.Contextas the first parameter. Ensure that thecheck()function definition has been updated accordingly.
354-359: Verify EventBroadcaster.Unregister signature accepts context.Context.The calls to
eventBroadcaster.Unregisterat lines 355 and 358 now passctxas the first parameter. Confirm that theUnregistermethod signature has been updated to acceptcontext.Contextas the first parameter, matching the pattern of theRegistermethod.
98-98: VerifynewAuthStreamInterceptorsignature.The call to
newAuthStreamInterceptoron line 98 now passesctxas the first parameter. Ensure that the function definition has been updated to acceptcontext.Contextas the first parameter.
48-53: Context-aware constructor follows klog best practices.The addition of
context.Contextas the first parameter and extraction of the logger from context usingklog.FromContext(ctx)aligns with proper contextual logging patterns and enables better log attribution.Ensure all call sites of
NewGRPCServerin the codebase have been updated to pass the context parameter as the first argument.
There was a problem hiding this 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'slog.Fatal. For consistency with the PR's goal of migrating to klog-based logging, both fatal error paths should useklog.Fatal.Apply this diff:
- log.Fatal(err) + klog.Fatal(err)After applying this change, you can remove the unused standard
logimport 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 usecheck(ctx, ...)for consistent fatal handlingIn
Start, a failure froms.Listen()is logged and followed byos.Exit(1)directly, which again bypasses the centralizedcheck(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 terminatesIf you prefer to keep the explicit
logger.Errormessage, you can log first and still delegate exit behaviour tocheck(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%splaceholder in skip log message.The skip message currently includes a
%splaceholder but no corresponding value, so the literal%swill appear in the logs and is slightly confusing. Since you already haveresourceIDandactionas 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 portIn the TLS branch you’re still logging
env().Config.HTTPServer.BindPort, but the server is configured withenv().Config.Metrics.BindPort(seeAddrconstruction). 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%splaceholders 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
errvariable 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
Resetstill 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; usecheck(ctx, ...)instead ofos.Exit(1)The
Startmethod logs and callsos.Exit(1)directly on listen/serve failures, which skips the centralizedcheck(ctx, ...)error path that also reports to Sentry. Aligning these fatal paths withcheckimproves 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/v2import on line 6 is placed between standard library imports (fmtandsync). 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
updateConsumerSetfunction now receives a logger (presumably derived from a context), but line 106 still usescontext.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.NewContextto 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 inhandleStatusUpdate.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 inbroadcastStatusEvent.You’re already enriching the logger with
resourceID,instanceID, andeventID; mirroring the pattern fromstartSubscriptionby putting this logger back intoctxwould let any downstream code that callsklog.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 beforeos.Exitin the shutdown pathIn 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 packageSince you already initialize klog flags, using
klog.Fatalfhere keeps logging consistent with the rest of the binary and avoids pulling inlogjust 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 includeoperationIDin the structured log fieldsYou already compute
operationIDfrom 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 syntheticerrors.NewallocationsYou’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
errorsimport 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 acceptableBringing in
k8s.io/klog/v2and using it for structured test logs alongside the standardlogpackage for fatal conditions is reasonable for test code. If you later want fully uniform logging, you could consider migrating the remaininglog.*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 tohelper.Ctxhere 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
⛔ Files ignored due to path filters (1)
go.sumis 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.Erroris called with the correct signature: error, message, and structured key-value pairs- The
eventTypefield properly captures the listener event type
200-203: LGTM!The migration from printf-style to structured logging is correct, with the
channelfield 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/v2import 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
ctxand 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 correctDeriving the logger from
ctxand using it for the “Could not create transaction” path, while keeping the user-facing error generic and keyed byoperationID, 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 clientUsing
klog.FromContext(ctx).WithValues(...)and thenklog.NewContext(ctx, logger)inOnCreate/OnUpdate/OnDelete/Resynccleanly scopes logs withresourceID/consumersand 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 usefulRegister/Unregister now accept
ctxand useklog.FromContext(ctx)(withid/sourcefields) plusStartuses 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.FromContextwith structured key-value pairs viaWithValues. The logger is correctly injected back into the context for downstream use.
87-122: LGTM!The
pulsemethod correctly derives a logger from context and uses proper structured logging with key-value pairs for alllogger.Errorandlogger.V(4).Infocalls.
176-201: LGTM!The
healthCheckHandlercorrectly 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 withklog.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 acceptcontext.Context.
122-124: LGTM!Context is correctly passed to the
Startmethods of the servers, enabling context-aware lifecycle management and logging throughout the server components.pkg/controllers/status_controller.go (4)
51-66: LGTM!The
Runmethod correctly derives a logger from context, useswait.JitterUntilWithContextandwait.UntilWithContextfor context-aware goroutine management, and properly waits onctx.Done()for graceful shutdown.
76-99: LGTM!The
processNextEventmethod correctly propagates context tohandleStatusEventand 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 theStatusEventIDvalue for downstream handlers.
161-190: LGTM!The
syncStatusEventsmethod 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.Errorffor 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.Infofappropriately 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.Infoffor initialization logging and retaininglog.Fatalffor fatal errors is appropriate. Fatal errors need immediate termination whichlog.Fatalfprovides.
159-170: LGTM!Appropriate use of
klog.V(4).Infofor 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).Infoandklog.V(4).Infoffor 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).Infofandklog.V(4).Infofor Sentry initialization logging at debug verbosity level.cmd/maestro/server/server.go (1)
16-21: Context-aware Server interface and check helper look consistentSwitching
Server.Start/Serveandcheckto acceptcontext.Contextand usingklog.FromContext(ctx)for fatal logging keeps existing behaviour (including thehttp.ErrServerClosedspecial-case) while enabling contextual logs. Looks good and matches how callers now passctx.Also applies to: 30-39
cmd/maestro/server/grpc_broker.go (2)
127-188: NewGRPCBroker context plumbing and TLS handling look correctDeriving
logger := klog.FromContext(ctx)and routing all TLS / CA configuration failures throughcheck(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 integratedUsing
logger := klog.FromContext(ctx)andlogger.V(4).Infofor 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 initAccepting
ctxinNewAPIServer, passing it intoroutes(ctx)andNewGRPCServer(ctx, ...), and usingcheck(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 goodDeriving
logger := klog.FromContext(ctx), validating TLS files viacheck(ctx, ...), and then usingcheck(ctx, err, "Web server terminated with errors")afterServe/ServeTLScorrectly 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 correctAccepting
ctxand usinglogger := 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 loggerDeriving
logger := klog.FromContext(ctx).WithName("maestro-controllers"), re‑embedding it viaklog.NewContext, and then passing that context intoKindControllerManager.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 correctlySwitching to
Run(ctx context.Context)withwait.JitterUntilWithContextforsyncEventsandwait.UntilWithContextforrunWorker, plus a final<-ctx.Done()and deferredeventsQueue.ShutDown(), keeps the original behaviour while making shutdown driven byctx. This matches upstream controller patterns.
118-194: handleEvent(ctx, id) context and logging refactor looks soundCreating an event-scoped logger (
WithValues(EventID, id)) and areqContextthat carries both the logger (klog.NewContext) andEventIDkey, then consistently using that context foreventFilter.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 onprocessNextEvent(ctx), andprocessNextEventderives a per-item logger with thekeyfield and delegates tohandleEvent(ctx, key). Requeueing viaAddRateLimitedon non‑reconciled events andForgeton 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 logsUsing
klog.FromContext(ctx)to log “purge all reconciled events” and “sync all unreconciled events”, and passingctxdown intoDeleteAllReconciledEventsandFindAllUnreconciledEvents, 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 correctlyCreating
ctx, cancel := context.WithCancel(context.Background())once and using that same context forNewGRPCBroker(ctx, helper.EventBroadcaster),startHealthCheckServer(), andstartEventServer()ensures all test-managed components share a single cancellation root (ContextCancelFunc). This should make teardown viasendShutdownSignalbehave predictably. No functional issues spotted.
198-209: startAPIServer uses context-aware server APIs and logs lifecycleUsing
logger := klog.FromContext(helper.Ctx), constructing the API server withserver.NewAPIServer(helper.Ctx, helper.EventBroadcaster), and then starting it in a goroutine with contextual V(4) logs for start/stop aligns with the newServer.Start(ctx)signature and provides useful test logs.
218-226: startMetricsServer context/logging changes are consistentThe metrics server is now started with
helper.Ctxand 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 lifecycleStarting the health check server with
helper.Ctxand 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 patternUsing
klog.FromContext(helper.Ctx)for logs andhelper.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 StartWrapping
EventBroadcaster.Start(helper.Ctx)with V(4) logs for start/stop adds useful visibility in tests, and usinghelper.Ctxhooks broadcaster lifetime into the same cancellation mechanism as the servers.
362-367: RestartServer now emits debug logs using the shared context loggerAfter 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 loggingThe 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.
There was a problem hiding this 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 usesklog.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
logimport 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: MissingForgetcall 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 callsAddRateLimited, but withoutForgeton success, the rate limiter's backoff state for this key persists.Apply this diff to add the
Forgetcall: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.Infocalls use printf-style%sformat 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.Errorcalls mix printf-style format specifiers with structured key-value logging. The%splaceholders 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 variableerrwhenEnableJWTis false.This issue was already flagged in a previous review. The
errvariable is only declared inside theif env().Config.HTTPServer.EnableJWTblock (line 33), so this code will fail to compile when JWT is disabled.
41-45: Undefined variableerrwhenEnableJWTis false.This issue was already flagged in a previous review. The
check(ctx, err, ...)call referenceserrwhich is only in scope ifEnableJWTwas 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 thecheck()function's Sentry error capture. Consider usingcheck(ctx, err, "...")for consistency with error reporting elsewhere.cmd/maestro/server/event_server.go (1)
103-103: Format specifier%sin log message with no arguments.This log message contains
%sbut 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: Incorrectklog.Errorusage with empty message string.The second argument to
logger.Errorshould 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) != nilbut logs theerrvariable 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 fieldsUsing
loggertracing.GetOperationID(ctx)together withklog.FromContext(ctx)and distinguishing 4xx asInfovs others asErroris 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
klogcontextual 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
Inituses globalklog.Errorfinstead ofklog.FromContext(ctx). This is becauseInitlacks acontext.Contextparameter.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.Doare not propagated, which may obscure initialization failures in tests.pkg/dispatcher/noop_dispatcher.go (2)
77-90: Consider context-aware logging for consistency.The
onInstanceUpdatecallback 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
onInstanceDownto 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
onInstanceUpdateto also accept and propagate context (see previous comment).cmd/maestro/main.go (2)
3-6: Prefer klog for fatal path and ensure logs are flushedSince this binary is now klog-centric, using
log.Fatalfhere 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 neededThese 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/v2import 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/v2import 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/v2import 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/v2import 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 soundPassing
ctxthroughrunWorkerintoprocessNextEventand on tohandleStatusEventaligns the whole processing path with contextual logging and cancellation, and the queue semantics (Done,Forget,AddRateLimitedon error,quithandling) remain unchanged.If you want slightly better observability on shutdown, consider logging once when
eventsQueue.Get()returnsquit == true(queue draining) so operators can distinguish “no work” from “controller exiting”.
104-145: Context‑scoped logger and per‑event context are wired correctlyDeriving a per‑event logger from
klog.FromContext(ctx)and wrapping it back intoreqContextkeeps logs and downstream calls (service/DAO + handlers) aligned on the same event, while preserving the existing metrics and reconciliation logic.If
StatusEventIDis not read fromctx.Valueanywhere else, you could drop the additionalcontext.WithValuelayer and rely solely onWithValuesfor logging; otherwise, leave as-is. A quick repo search forStatusEventIDusages can confirm this.
161-190: Sync loop now respects context and uses structured loggingMaking
syncStatusEventscontext‑aware and deriving the logger fromctxintegrates 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
readyInstanceIDsinstead 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 configurationYou're using
klog/v2alongside the standardflagpackage. The recommended pattern is to callklog.InitFlags(nil)beforeflag.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 inmain()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
⛔ Files ignored due to path filters (1)
go.sumis 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/v2aligns with the PR objective to migrate to klog's contextual logging.
31-34: LGTM!The migration from the custom logger to
klog.Fatalfor 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
resourceIDfor request tracing- Propagates the enriched context to downstream calls (
ResourceService.Get,ResourceService.Delete,CloudEventSourceClient.Publish)- Uses structured logging with
logger.Info()andlogger.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
consumerslist, 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
checkmethod properly extracts the logger from context and uses it consistently for all log statements. Context is correctly passed toinstanceDao.All(ctx).
100-109: Inconsistent context usage inupdateConsumerSet.The method signature now accepts a
loggerparameter for contextual logging, but Line 106 still usescontext.TODO()for the database call. This is inconsistent with the PR's objective of propagating context throughout the codebase.Consider either:
- Accepting a
context.Contextparameter alongside the logger, or- Extracting the context from the logger if klog supports it, or
- 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.Errorfis 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.FromContextis correct, and thelogger.Infocalls 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).Infofis correctAlso 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.Loggeris consistent with the PR objectives:
- All logging properly uses the passed logger
- Structured logging with
logger.Infoandlogger.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
instanceIDand 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
healthCheckHandlerAlso applies to: 78-84, 88-122, 132-146, 177-202
pkg/controllers/framework_test.go (2)
87-89: LGTM!The context propagation to
handleEventcalls is correct and aligns with the signature change. Using the existingctxfromcontext.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.Errorffor error logging in the report generation failure path.
246-252: LGTM!The pod log dumping now uses
klog.Infofconsistently. The structured output for container status and pod logs is appropriate.cmd/maestro/server/routes.go (1)
18-18: LGTM!The
routesmethod correctly accepts a context parameter for propagating context-aware error handling.cmd/maestro/server/server.go (2)
16-21: LGTM!The
Serverinterface correctly updated to require context inStartandServemethods, enabling context-aware logging and cancellation throughout the server lifecycle.
31-38: LGTM!The
checkfunction 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
PredicateEventmethod correctly uses context-derived logging withV(4)verbosity level for debug messages, which is appropriate for high-frequency event processing.pkg/event/event.go (3)
41-57: LGTM!The
Registermethod 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
Startmethod 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
WithValuesfor 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. TheRun(ctx)call correctly aligns with the updatedKindControllerManager.Runsignature that now accepts context instead ofctx.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
Servemethod 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
Startmethod properly uses context-derived logging. Usinglogger.Errorfollowed byos.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.Contextas the first parameter.pkg/controllers/framework.go (4)
88-104: LGTM!The
Runmethod correctly uses context-derived logging and properly useswait.JitterUntilWithContextandwait.UntilWithContextfor context-aware scheduling. Shutdown logging is appropriately placed after<-ctx.Done().
118-134: LGTM!Good pattern: enriching the logger with
EventIDviaWithValuesand storing the event ID in context via bothklog.NewContext(for logging) andcontext.WithValue(for downstream access). The deferred action pattern ensures cleanup regardless of early returns.
204-230: LGTM!The
processNextEventmethod correctly extracts a logger from context, adds thekeyfield for traceability, and properly handles error logging with structured output.
232-257: LGTM!The
syncEventsmethod 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.Contextas the first parameter toNewGRPCServeraligns with the PR's objective to propagate context throughout the codebase. Logger derivation usingklog.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
Startmethod 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()andUnregister()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 thatnewAuthStreamInterceptorproperly utilizes the context.The interceptor now receives a context parameter. Ensure that the implementation of
newAuthStreamInterceptoractually 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.NewGRPCBrokernow 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.Ctxinternally 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.Ctxand propagates the context to both theNewAPIServerconstructor and theStartmethod, 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
Startmethod 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
Startmethod.
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
Startmethod with appropriate structured logging.
362-374: LGTM! Server restart methods correctly use contextual logging.Both
RestartServerandRestartMetricsServerproperly derive loggers fromhelper.Ctxand 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 patternUsing 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.modmatches the rest of your Kubernetes client libraries to avoid subtle incompatibilities.
51-66: Controller lifecycle correctly tied tocontext.Context
Run(ctx)now cleanly binds the controller lifetime toctx.Done(), starts the sync and worker loops with*WithContext, and shuts down the workqueue viadefer 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) intoRunso shutdown behaves as expected.test/mocks/workserver/main.go (2)
155-159: klog migration for initialization/startup logs looks goodThe 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 consistentThe failure and shutdown paths now using
klog.Fatalf/klog.Errorf/klog.Infofare 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
There was a problem hiding this 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
Forgetcall 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) != nilbut logs theerrvariable 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 thecheck()function's centralized error handling and Sentry reporting (see cmd/maestro/server/server.go). This is inconsistent with line 225, which usescheck()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 inwaitForNotificationlooks good; consider including channel on ping failuresUsing
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", channelthere 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.Errorfwithklog.Errorf. Since theInitfunction 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
EventIDis 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
EventIDcontext value is needed downstream (e.g., for non-logging purposes), this is fine. Otherwise, consider relying solely on the logger'sWithValues.pkg/controllers/framework_test.go (2)
87-89: Consider checkinghandleEventreturn values.The
handleEventmethod now returns(bool, error), but the return values are ignored here. While the tests validate side effects (counters andReconciledDate), 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
handleEventare ignored. Given that event "2" and "3" are expected to not be processed (counters remain 0), checking thereconciledreturn 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.Errorsignature isError(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: Missingsentry.CaptureExceptionand message casing differs.Two minor inconsistencies compared to
SendAPI:
- Message casing differs: "Can't send..." vs "cannot send..." on line 58
sentry.CaptureException(err)is called inSendAPI(line 59) but not hereConsider 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 inNewSourceClientconstructor for proper context propagation.The constructor uses
context.Background()which bypasses caller-controlled cancellation, timeouts, and tracing context. This prevents downstream operations incegeneric.NewCloudEventSourceClientfrom 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{}toauthMiddleware, 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 wiringctxinto HTTP server shutdown, not just logging
Serve(ctx, listener)currently usesctxonly to derive a logger and to pass intocheck, but the HTTP server lifecycle itself isn’t driven byctx. If the caller expects cancelingctxto eventually stop the HTTP server, you may want to add a goroutine that waits onctx.Done()and callss.httpServer.Shutdown(ctx)(or usehttp.Server.BaseContext) so cancellation semantics match the method signature.
188-199: Reconsider ordering of gRPC shutdown vs DB pool closeAfter
s.Serve(ctx, listener)returns, you closeenv().Database.SessionFactoryand only then (viadeferset 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 thedefer) 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
⛔ Files ignored due to path filters (1)
go.sumis 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 appropriateDeriving the logger from the incoming
ctxand using it inside theplogcallback 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:NewListenercontext propagation and startup log are consistent with the new logging modelCreating the listener with the passed
ctx, then logging a structured “Starting listener” message before spawningwaitForNotificationmaintains 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
EventIDkey matches the constant defined inframework.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 andcontext.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 ofcontext.Background()to propagate the cobra command's contextpkg/controllers/status_controller.go (5)
6-6: LGTM: Import aligns with contextual logging migration.The addition of
k8s.io/klog/v2is 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 (
syncStatusEventsandrunWorker)- 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
StatusEventIDfor automatic inclusion in log messages- The context value stores
StatusEventIDfor programmatic access by downstream handlers- The enhanced logger is embedded via
klog.NewContextfor contextual loggingThis 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.Infofis appropriate inTestMainwhere 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
loggertracingpackagepkg/event/event.go (2)
42-42: LGTM!Context-derived logger usage is correct throughout:
- Structured logging with appropriate fields
WithValuesused 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
RegisterandUnregistermethods now acceptcontext.Contextas 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
updateConsumerSetfunction to avoid redundant context lookupsAlso applies to: 152-152, 208-208
go.mod (1)
93-93: LGTM!Dependency reorganization aligns with the klog migration:
go.uber.org/zapmoved to indirect (no longer directly used)github.com/fsnotify/fsnotifymoved 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.SugaredLoggertoklog.Logger. Ensure all callers ofInstallOpenTelemetryTracerhave been updated to pass aklog.Loggerinstance.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
Startmethod correctly:
- Extracts the logger from context and adds a component name (
maestro-controllers)- Re-injects the enriched logger into the context for downstream use
- Uses the logger consistently for all log statements
This ensures proper log attribution and context propagation to child goroutines via the
ctxparameter passed toRun,NewListener, etc.pkg/controllers/framework.go (3)
88-104: LGTM! Context-aware Run method with proper lifecycle.The method correctly:
- Extracts logger from context
- Uses
wait.JitterUntilWithContextandwait.UntilWithContextfor context-aware scheduling- Blocks on
ctx.Done()for graceful shutdown
196-230: LGTM! Context propagation through worker and event processing.The
runWorkerandprocessNextEventmethods correctly accept and propagate context. The logger is extracted per-event with thekeyvalue for traceability, and errors are logged with proper context.
232-258: LGTM! Context-aware event synchronization.The
syncEventsmethod properly extracts the logger from context and passesctxto 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.Errorcall 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
Startmethods 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.Fatalfis consistent with the broader logging migration. SinceMigrateTois primarily for testing purposes and doesn't have a context available, using the package-levelklog.Fatalfis 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 (resourceTypeandresource). 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 thecheckhelper 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
Serverinterface now requirescontext.ContextinStart(ctx context.Context)andServe(ctx context.Context, listener net.Listener)methods. This is a breaking change—confirm that all implementations of theServerinterface 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 withklog.NewContextensures downstream calls receive the enriched logger. This is correctly applied acrossOnCreate,OnUpdate,OnDelete, andResync.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
ctxparameter 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
NewAPIServercall andStartmethod invocation with context parameters align with the new server API signatures.cmd/maestro/server/api_server.go (3)
6-9: klog andosimports are appropriate and used correctlyThe new imports for contextual logging and process exit are used in this file (
klog.FromContextandos.Exit) and there are no obvious issues or redundancies here.
40-44: Context propagation into router, auth handler, and gRPC server looks consistentPassing
ctxintos.routes(ctx)andNewGRPCServer(ctx, ...), and updating thecheckcalls tocheck(ctx, err, ...), aligns with the newServerinterface (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 goodPropagating
ctxintos.grpcServer.Start(ctx)and deriving a per-context logger inStart(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.
There was a problem hiding this 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 failureIn
Unlock, iflock.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: FixinitDatabaseloop: it can sleep forever without re‑trying the queryIn
initDatabase, this loop only callsExeconce in the init statement. If that first call returns a non‑nil error,errnever changes and the loop sleeps forever without re‑trying the query.To actually poll until the DB is ready, re‑issue
Execon 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 toWritePBMessageinstead ofcontext.TODO().
WritePBMessageuses the context parameter to control encoding behavior and handle cancellation. Passingcontext.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 avoidingFatalfin 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
MigrateToto 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 formattederrMsgin lock acquisition logsThe new klog usage is fine, but you’re still building
errMsgwithfmt.Sprintfand 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
idandlockType, 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 inMarkForRollbackerror logIn
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
errandmsgare meaningful.Also applies to: 35-36, 50-54, 57-58
cmd/maestro/server/logging/writer.go (1)
8-10: IncludelogMsgin the error-path log for better diagnosticsWhen 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
logMsgas 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 contextUnary interceptor correctly derives
logger := klog.FromContext(ctx)inside the per-RPC closure, but the stream interceptor captures a logger from the constructor’sctx:func newAuthStreamInterceptor(ctx context.Context, authNType string, ...) grpc.StreamServerInterceptor { logger := klog.FromContext(ctx) return func(..., ss grpc.ServerStream, ...) error { // logs use logger hereIf you attach request-scoped values (operation IDs, correlation IDs, etc.) to
ss.Context(), those won’t show up in these logs.Consider moving the
FromContextcall 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/v2import 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
logConfigFileandvarLogLevelconstants 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/v2import 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
authMiddlewareis unconditionally assigned a mock on line 32 (authMiddleware = &auth.AuthMiddlewareMock{}), and if JWT is enabled, it's either successfully assigned orcheckterminates 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/v2import 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/v2import 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/v2import 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/v2import 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
loggervariable on line 14 is only used inside theif !env().Config.MessageBroker.Disableblock (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/v2import on line 8 is placed between standard library imports (fmtandnet). 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, thek8s.io/klog/v2import is placed after standard library imports but before external packages, which is correct, butk8s.io/apimachinery/api/metashould 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 useslogger.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/v2import on line 6 is placed betweenfmtandtime(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, andlogare 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/v2andlogimports 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 usescontext.Background()for shutdown, which is inconsistent with the context-aware design throughout the rest of the file. Whilecontext.Background()is acceptable for cleanup paths, consider whether the method should accept a context parameter for timeout control and cancellation.If the
Serverinterface 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
⛔ Files ignored due to path filters (1)
go.sumis 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.Errorwith the correct signature at line 175 (error as first argument, followed by message and structured fields)- Includes the
eventTypefield to provide useful debugging context for listener state changes
199-206: LGTM! Public API cleanly migrated to contextual logging.The
NewListenerfunction 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
Forgeton 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
loggertracingappropriately avoids confusion with the localloggervariable.
34-40: Verify logger middleware configuration before mergingThe contextual logging implementation correctly uses klog's API, but its effectiveness depends on two critical prerequisites:
klog.EnableContextualLogging(true)must be called during application startup before spawning goroutines; otherwiseklog.FromContext(ctx)silently falls back to the global logger- Request middleware must inject the logger into context using
klog.NewContext(ctx, logger)and propagate context withr.WithContext(ctx)Verify that:
- Logger middleware exists and calls
klog.NewContextto attach a per-request loggerklog.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 inTest.Initlooks correct; just confirm it matches repo-wide logging conventionsImporting
k8s.io/klog/v2and switching the two error paths inInitto: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 consistentThe switch to
kloghere (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 goodDeriving 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; ensurego mod tidystays cleanMarking
github.com/fsnotify/fsnotify,go.uber.org/zap, andgoogle.golang.org/genprotoas indirect is consistent with removing direct logger/config usages elsewhere. Just ensure CI runsgo mod tidy(and thatgo.sumis 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 usageUsing
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.Infofandklog.Errorfcalls 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.Fatalffor 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.Infoffor environment initialization andklog.V(4).Info/Infoffor 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.Loggerparameter 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
Serverinterface andcheckfunction are correctly implemented. Usingklog.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
Startmethod 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
Startmethod correctly creates a named logger ("maestro-controllers"), injects it into the context viaklog.NewContext, and uses it consistently for all controller lifecycle logging. The context propagation toRunand 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
Startmethod now properly derives a context-bound logger and usescheck(ctx, ...)for error handling in both the listener setup and server goroutine. This addresses the previous review feedback aboutos.Exit(1)bypassing Sentry reporting.
269-285: LGTM!The
PredicateEventmethod 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
Startmethod 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
broadcastStatusEventfunction properly enriches the logger with relevant context fields (resourceID,instanceID,eventID) for effective log correlation.pkg/controllers/framework.go (4)
88-104: LGTM!The
Runmethod properly uses context-aware wait utilities (JitterUntilWithContext,UntilWithContext) and derives a context-bound logger for lifecycle messages.
118-121: LGTM!The
handleEventmethod properly enriches the context with both the logger (containing the EventID) and the EventID value for downstream handler access.
203-230: LGTM!The
processNextEventmethod properly derives a logger with the queue key for effective error tracing.
232-258: LGTM!The
syncEventsmethod 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
NewGRPCBrokercall correctly passes the context parameter to match the updated constructor signature.
198-265: LGTM!All test server startup methods consistently derive loggers from
helper.Ctxand 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
CleanDBmethod 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.Contextand propagates it toroutes(). This aligns with the PR's goal of enabling contextual logging throughout the server lifecycle.
148-171: LGTM: Context-aware logging properly implemented.The
Servemethod correctly:
- Accepts
context.Contextas 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 thecheckfunction implementation.The
checkfunction is now called withctxas the first argument. Ensure that its implementation properly uses the context for logging viaklog.FromContext(ctx).cmd/maestro/server/grpc_server.go (7)
48-54: LGTM: Constructor signature updated correctly.The constructor now accepts
context.Contextas 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
Startmethod correctly:
- Accepts
context.Contextas a parameter- Derives a logger from the context
- Uses context-aware logging for errors
167-240: LGTM: Publish method uses per-request context.The
Publishmethod 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()andUnregister()(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
respondResyncStatusRequestfunction 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
ctxtonewAuthStreamInterceptor(). Verify whether:
- The interceptor uses this context at construction time (problematic) or stores it only as configuration
- The interceptor extracts the actual request context from the stream itself via
stream.Context()- 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 thectxparameter.
There was a problem hiding this 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
!okmeans the resource exists in maestro (objis fromobjs) but is NOT found in the source'sstatusHashes. 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 deferreds.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 fieldsThe 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
ctxwith a logger injected (soklog.FromContextbehaves as expected).pkg/dispatcher/noop_dispatcher.go (1)
77-90: Consider using a closure to enable contextual logging.The
onInstanceUpdatecallback uses globalklog.Infof/klog.ErrorfwhileStartandresyncOnReconnectuse contextual logging viaklog.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 goodUsing
klog.FromContext(r.Context())in the write‑error paths keeps logs tied to the request while preserving Sentry reporting and control flow. The init‑timeklog.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 fromss.Context()instead of constructor ctx
newAuthUnaryInterceptorcorrectly uses the per‑RPCctx, butnewAuthStreamInterceptorbindslogger := klog.FromContext(ctx)at construction time. That ctx is typically process/server‑scoped, so stream logs won’t pick up per‑request values injected intoss.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 usesklog.FromContext(ctx)for TLS/non‑TLS startup logs, validates TLS config viacheck(ctx, ...), and relies oncheckto handle non‑http.ErrServerClosedtermination 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 intoShutdowninstead ofcontext.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 andcheckconsistently
NewGRPCBrokerandStartnow route TLS validation, listener errors, and Serve failures throughcheck(ctx, ...)and useklog.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 successfulnet.ListeninStart, 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, andStartnow useklog.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.FromContextgracefully 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/v2import is placed between stdlib imports (fmtandtime). 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- thek8s.io/klog/v2import is placed between stdlib imports.import ( "context" "crypto/tls" "crypto/x509" "fmt" - "k8s.io/klog/v2" "net" "os" "time"Move
k8s.io/klog/v2to 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/v2import is placed between stdlib imports.
76-99: Minor inconsistency with framework.go pattern.In
framework.go,processNextEventenriches 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
keydeclaration before the logger creation, which changes the flow slightly.
161-190: Consider verbosity level for instance IDs logging.Line 169 logs all
readyInstanceIDswhich could be verbose in large deployments. Consider usingV(2)orV(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
⛔ Files ignored due to path filters (1)
go.sumis 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:
fsnotifyandvipermoved to indirect dependencies, consistent with removing log config managementzapmoved to indirect, expected since klog replaces the custom Zap loggerklog/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
genprotoreorganization (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 goodUsing
k8s.io/klog/v2pluslogtracingforGetOperationIDaligns 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
handleStatusUpdatereceive the enriched logger.
103-103: LGTM: Previous format specifier issue addressed.The log message correctly removed the
%sformat 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/v2aligns 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
resourceIDfor structured logging.klog.FromContextsafely 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 useslogger.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.Infoftologger.Infoandlog.Debugftologger.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 useslogger.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
Resolvefunction 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 goodStartup logging via
klog.Infofand callingCleanDB()beforeos.Exitintegrate cleanly with the new logging approach and improve integration test teardown.cmd/maestro/server/server.go (1)
16-21: Server interface andchecknow properly carry context for loggingUpdating
ServertoStart(ctx)/Serve(ctx, listener)and threading ctx intocheck(ctx, err, msg)centralizes fatal error handling with a context‑derived klog logger while still skippinghttp.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
instanceIDfor 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
shutdownErrand 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
NewGRPCBrokercall 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 updatedNewAPIServerconstructor.
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
Runis well-structured. The logger is correctly derived from context, and the context is properly passed towait.JitterUntilWithContextandwait.UntilWithContextfor cancellation support.
118-134: LGTM!The context enrichment pattern is well-implemented. The logger is enriched with
EventIDfor structured logging, and the same ID is stored in the context for handlers to access viacontext.Value(). This dual approach enables both contextual logging and programmatic access to the event ID.
204-230: LGTM!The local logger enrichment with
keyfor error logging is appropriate. ThehandleEventmethod correctly creates its own enriched context withEventID, so there's no need to propagate the key-enriched logger.
232-258: LGTM!The
syncEventsmethod 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
ctxparameter 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). TheStart()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
Startmethod 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
Runmethod follows the same correct pattern asKindControllerManager.Run(), with proper context propagation to background workers.
104-106: LGTM!The context enrichment pattern with
StatusEventIDis consistent with thehandleEventpattern inframework.go.
There was a problem hiding this 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 messageThe 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{}andauth.NewAuthzMiddlewareMock()without config-gated creation based onEnableJWT/EnableAuthzflags. 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.Marshalfails, 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 intoonInstanceDowninstead of usingcontext.TODO()
onInstanceUpdatenow has aklog.Logger, butonInstanceDownstill usescontext.TODO()and only returnsfmt.Errorfwithout contextual logging. If you want full consistency with the PR’s contextual-logging goal, consider passingctxand/orloggerfrom the call site intoonInstanceDownso 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 pathsBoth 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
Infolevel 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 messagesYou currently log:
- An
Infomessage:"Updating resource status".- A
V(4)message with the same text plus theeventpayload.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 plainInfo.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 createserrors.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 flowInitialization and client/Sentry setup now emit clearer info and debug-level logs (including when mock implementations are used) while retaining the existing
log.Fatalfbehavior on unrecoverable errors; this is a safe, incremental improvement. If you later thread acontext.ContextthroughEnv.InitializeandLoadClients, 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
Startnow takes acontext.Context, derives a logger from it, logs using the Metrics bind port, and passesctxintocheck, which is exactly what you want for contextual logging and termination handling. The no-opServeis acceptable to satisfy theServerinterface; 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
loadListnow 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/v2import 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/v2should 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/v2should 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/v2should 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/v2should 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/v2import 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, thek8s.io/klog/v2import 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/v2import 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/v2import is placed between stdlib imports (errorsandlog).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 intervalsUsing expressions like
time.Duration(s.heartbeatInterval/3*int(time.Second))andtime.Duration(int(-3*time.Second)*s.heartbeatInterval)works numerically but is hard to read and has edge cases (e.g.,heartbeatInterval < 3makesheartbeatInterval/3zero, socheckInstanceswould run in a tight loop). It also disagrees with the comment about “three check intervals” (current threshold is3 * heartbeatIntervalseconds, not3 * checkInterval).Consider refactoring to derive durations directly from
time.Duration(s.heartbeatInterval) * time.Secondand a namedcheckInterval, 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-TypeUsing
klog.FromContext(r.Context()).WithValues("instanceID", s.instanceID)and logging all DAO/response-write errors vialogger.Erroris a solid improvement in observability. As a small follow-up, you might setContent-Type: application/jsonon 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
⛔ Files ignored due to path filters (1)
go.sumis 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 wiredThe added
k8s.io/klog/v2import is used byAccessReviewand 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 toctxUsing
klog.FromContext(ctx).WithValues(...)with distinct keys (action,resourceType,resource,user,groups) and logging atV(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., viaklog.NewContextin 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
logtracingto avoid naming conflicts while retaining access toGetOperationID.
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 patternImporting
k8s.io/klog/v2here aligns with the new logger usage below; nothing else needed in this section.
35-44: Context-derived logger usage inStartlooks goodDeriving the logger once from
ctxand capturing it in theNewListenercallback 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.FromContextsafely returns the global logger if the context doesn't contain one, so this is robust.
18-18: LGTM: Logger field properly encapsulated.The
loggerfield 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 usesError()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 migrationThe new
k8s.io/klog/v2import 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 withresourceIDis a solid patternUsing
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
UpdateStatuspropagate 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 behaviorThe
Unlockchanges are well-implemented:
- Contextual logger with
WithValues("owner", uuid)and theV(4).Info("Caller not lock owner")debug line maintains previous behavior while improving queryability.- Error path logs via
logger.Error()and incrementsUpdateAdvisoryUnlockCountMetric(lockType, "ERROR")appropriately.- Success path increments
UpdateAdvisoryUnlockCountMetric(lockType, "OK")andUpdateAdvisoryLockDurationMetric(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 concernUsing
klog.FromContext(ctx)and switching error paths inNewAdvisoryLock/NewNonBlockingLocktologger.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
errintoerrMsgand also passerras the first argument tologger.Error. Per the logr API,msgshould be a short, simple description without formatting, and the error is already surfaced as structured data via theerrparameter. 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
keysAndValuespairs 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 goodBoth
SendAPIandSendAPIV1now derive a logger from the request context and log failures fromw.Writewith 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 simpleSwitching to the standard library’s
log.Fatalffor command execution errors keeps behavior straightforward and decouplesmainfrom 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
InstallOpenTelemetryTracernow 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 refactorMarking
fsnotify,zap, andgenprotoas indirect dependencies is consistent with dropping direct usage in this repo while still satisfying transitive requirements; this looks correct. Please just ensure your usualgo 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 correctThe updated comment for
addFlagsaccurately 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
klogis correctly implemented. Using non-contextualklog.Infof/klog.Fatalf/klog.Errorfis 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"toklog.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 withlogger.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:
RegisterandUnregisternow accept context and useklog.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 theUnregisteroperation.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 bothKindControllerManagerandStatusController.cmd/maestro/server/grpc_broker.go (3)
128-212: Context-aware initialization looks good.The
NewGRPCBrokerfunction now properly accepts a context, derives a logger from it, and usescheck(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 deferreds.grpcServer.Stop()has been replaced withreturn, 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
NewGRPCBrokernow receives the context, and the helper's start methods internally usehelper.Ctxfor 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
shutdownErrfrom the tracing shutdown call.cmd/maestro/server/grpc_server.go (6)
48-54: Context-aware constructor is well implemented.The
NewGRPCServerfunction 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
Runnow cleanly useswait.JitterUntilWithContext/wait.UntilWithContextand blocks onctx.Done()while deferringeventsQueue.ShutDown(), so worker and sync goroutines respect cancellation without changing controller semantics.
118-194: Event-scoped logger/context usage is consistentDeriving an event-scoped logger via
WithValues(EventID, id)and threadingreqContextthrougheventFilter, 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
runWorkerandprocessNextEventcorrectly takectx, useeventsQueue.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
syncEventsnow usesctxfor 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 reasonableAccepting
ctxinNewHealthCheckServerand registering logger middleware there, then deriving an instance-scoped logger inStartviaWithValues("instanceID", s.instanceID)andklog.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 correctThe advisory lock is acquired with
ctxand always unlocked via defer; klog is used for structured errors and the new-instance path usesV(4).Inforather than ad‑hoc debug logging, while the create/get/update flows are otherwise unchanged.
126-174: checkInstances(ctx) adopts contextual logging cleanlySwitching 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-awarewaithelpers and blocks onctx.Done(), whilerunWorker/processNextEventdrive the queue with the same backoff andAddRateLimitedbehavior, 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
handleStatusEventnow derives a logger withStatusEventID, wraps it intoreqContextviaklog.NewContext, and threads that through the service and handler calls. Logging “no handler functions” as an Info withstatusEventTypeplus existing metrics gives good visibility without altering behavior.
161-190: syncStatusEvents(ctx) context/logging changes look goodUsing
ctxfor DAO calls andklog.FromContext(ctx)for structured errors and thereadyInstanceIDsdebug log preserves the existing batching/deletion and metrics logic while making operations observable per-context.
There was a problem hiding this 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 failsOn event creation failure, you’re returning an error derived from
err(which isnilhere) instead ofeErr, 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 wordingThe 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: ClarifyaddFlagscomment to match the actual flags and options structThe current comment says this overrides cluster name and leader election flags from
agentOption, but the implementation usescommonOptionsand 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 commonOptionspkg/dispatcher/noop_dispatcher.go (1)
100-119: Consider threading context throughonInstanceDown.This function uses
context.TODO()while callers likeonInstanceUpdatehave access to a context-derived logger. For consistency with the PR's contextual logging pattern, consider acceptingctx context.Contextto 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
onInstanceUpdateto 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 semanticsUsing
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.:
and similarly for the migration failure.if err := dbConfig.ReadFiles(); err != nil { klog.Fatalf("failed to read DB config: %v", err) }- 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 withklog.Error/Errorfand then callos.Exit(code)explicitly.pkg/auth/helpers.go (2)
13-32: Consider logging the internal service error code in addition to HTTP statusThe structured logs currently include
error,code(HTTP status), andop-id. For troubleshooting, it would be useful to also log the internalerrors.ServiceErrorCodepassed intohandleError, 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
writeJSONResponsecurrently ignores bothjson.Marshalandw.Writeerrors, and setsContent-Typewithout 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-8as 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 noiseIf stale status events are common in steady state, logging them at base
Infocould 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 fromklog.Fatalfto context‑bound error loggingThe direct
klog.Fatalfcall 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.ContextintoMigrateToinstead of usingcontext.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 constantsTwo small follow‑ups:
- To ensure klog output is flushed on normal process exit, it’s typical to add a flush in
mainafterklog.InitFlags:- // add klog flags - klog.InitFlags(nil) + // add klog flags + klog.InitFlags(nil) + defer klog.Flush()
logConfigFileandvarLogLevelno 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 incmd/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/v2import on line 6 is placed betweenfmtandstrings(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, thek8s.io/klog/v2import 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/v2import is placed between stdlib imports (contextandos).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/v2import 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/v2import 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
logandklogare necessary -logappears to only be used forlog.FatalfinNewServerCommand(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
klogimport is placed between standard library imports (fmtandnet/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
ListenAndServeorListenAndServeTLSreturns an error,check()is called which likely logs/handles the error, thenlogger.Info("HealthCheck server terminated")runs, followed by waiting onctx.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 tohandleEvent. ThehandleEventmethod receives the originalctxand creates its own enriched logger. The "key" information is only available for the error log at line 218, not withinhandleEvent.Consider passing the enriched context to
handleEventfor 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
handleEventalso 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,
klogis 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.Registerreceives a context but creates logs using the outerloggervariable. 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
⛔ Files ignored due to path filters (1)
go.sumis 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.1as a direct dependency and the removal ofspf13/viperfrom 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:
- The move of
go.uber.org/zapto indirect is intentional and does not break any transitive dependencies that previously relied on it being direct.- The removal of
spf13/viper(and its dependency on fsnotify for dynamic config watching) does not cause issues elsewhere in the codebase.- 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.Errorfis 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.Loggerenables 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 goodThe 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
plogcallback closure. Thelogger.Errorcall 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
newListenerandwaitForNotification, ensuring consistent contextual logging throughout the listener lifecycle.pkg/auth/helpers.go (1)
3-11: Contextual klog usage is consistent; confirm logger injection into contextUsing
klog.FromContext(ctx)andlogtracing.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
errorsandk8s.io/klog/v2packages 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 loggingImporting
k8s.io/klog/v2here 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 scopingDeriving the logger from
ctxand 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 verboseUsing a lightweight
Infowithout payload plus aV(4)log with theeventpayload 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 issueThe 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 migrationImporting
k8s.io/klog/v2here is consistent with the rest of the PR’s shift away from the custom logger; nothing blocking from this file’s perspective. Please just confirmk8s.io/klog/v2is properly listed ingo.modand aligned with the repo’s chosen klog version.pkg/db/db_session/test.go (1)
55-64: klog migration in test Init preserves behaviorSwitching the Init error paths to
klog.Errorkeeps 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 goodThe swap to
klogfor 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 improvedNice changes here:
updateConsumerSetnow takesctxand uses it forconsumerDao.All, eliminating thecontext.TODO()and aligning with the rest of the context‑aware code.- Deriving
logger := klog.FromContext(ctx)inresyncOnReconnect,check, andprocessNextResynckeeps 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 correctDeriving a logger from
r.Context()and logging write failures withlogger.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 loggingAll 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 handleEventPassing
ctxintomgr.handleEventin 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
Startmethod correctly derives the logger from context and uses it for all logging paths (TLS/non-TLS startup messages and termination). The error handling withcheck(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
checkfunction 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
Startmethod correctly derives the logger from context and uses it consistently for startup/shutdown messages.
93-117: LGTM!Good use of structured logging with
WithValuesto enrich the logger withresourceIDandaction. The context is properly updated usingklog.NewContextso downstream functions receive the enriched logger.
163-253: LGTM!The
handleStatusUpdatefunction 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
broadcastStatusEventfunction 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
NewGRPCBrokerconstructor correctly accepts context, derives the logger, and uses the context-awarecheck()function consistently for error handling. The TLS configuration logging is clear and includes relevant port information.
214-232: LGTM!The
Startmethod correctly usescheck(ctx, ...)for error handling (addressing the previous review comment about Sentry reporting). The graceful shutdown flow withGracefulStop()is appropriate.
269-298: LGTM!The
PredicateEventmethod correctly useslogger.V(4).Infofor 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
NewAPIServerconstructor correctly accepts context and propagates it to route setup, authentication handler creation, and gRPC server initialization. Thecheck(ctx, ...)calls ensure consistent error handling.
147-170: LGTM!The
Servemethod correctly derives the logger from context and uses structured logging with port information for TLS status messages.
179-198: LGTM!The
Startmethod correctly addresses the previous review concern - it now returns on listener error instead of callingos.Exit(1), ensuring the deferreds.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
shutdownErrfromtracingShutdown(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
Startmethods, 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
Runmethod correctly derives the logger from context, starts background goroutines with context propagation usingwait.JitterUntilWithContextandwait.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
syncEventsmethod 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
Runmethod correctly follows the same context-aware pattern asKindControllerManager.Run, with proper logger derivation, goroutine startup with context, and graceful shutdown on context cancellation.
76-99: LGTM!The
processNextEventmethod 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
handleEventinframework.go, correctly creating an enriched logger with the status event ID and embedding it into the request context.
161-190: LGTM!The
syncStatusEventsmethod 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.Ctxand use appropriate log levels (V(4) for debug-level test infrastructure messages). The pattern is uniform across all startup methods.
376-396: LGTM!The
Resetmethod 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
NewGRPCServerconstructor properly accepts context, derives a logger for initialization logging, and passes context to thecheck()helper for fatal error handling. All TLS configuration paths log with structured fields.
149-159: LGTM!The
Startmethod correctly derives a logger from context, logs the startup, and properly handles and logs listen errors before returning.
445-488: LGTM!The
respondResyncStatusRequestmethod 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.
There was a problem hiding this 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 sharedctxinsideSubscribecallback (data race and context leakage)The callback captures and then reassigns the outer
ctxvariable withctx = klog.NewContext(ctx, logger). IfSubscribeinvokes 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.ctxis available in bothInitialize()(lines 155-159) andStart()(line 172), consider usingklog.FromContext(s.ctx)instead of the package-levelklogfunctions 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 IDUsing
loggertracing.GetOperationID(ctx)andklog.FromContext(ctx)makeshandleErrorfully 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
opIDintoAsOpenapiError.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: Preferklog.ErrorSoverklog.Errorand avoid odd formatting
klog.Erroris deprecated in favor ofklog.ErrorS, which gives structured logging with the error attached under the standarderrfield. (pkg.go.dev) Usingklog.Error(err, "…")also produces a slightly awkward log line because the error and message are just concatenated viafmt.Sprintwith 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-IDheader is absent,opIDwill 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/v2import (third-party) is placed before the standard librarylogimport. 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
idandlockTypeas key/value pairs instead of only insideerrMsg, 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/lockTypemuch easier.
114-127: Apply the same structured logging pattern for non-blocking lock errors (optional).Similarly to
NewAdvisoryLock, you can exposeidandlockTypeas 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
⛔ Files ignored due to path filters (1)
go.sumis 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 transitivepkg/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
elseblock that callsd.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.Errorusage 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
tracingShutdownis 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/v2is appropriate for Kubernetes ecosystem projects.pkg/handlers/framework.go (1)
3-12: Contextual logging imports are consistent with usageThe addition of
k8s.io/klog/v2and theloggertracingalias lines up cleanly with howklog.FromContextandloggertracing.GetOperationIDare 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.FromContextto derive a logger. If the incoming context lacks a logger,FromContextreturns 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
logpackage for fatal errors inmain()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 isklog.InitFlags(flag.CommandLine)(notnil), 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 migrationImporting
k8s.io/klog/v2here 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.Errorfis 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 withlogger.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
resourceIDviaWithValuesenables effective tracing of status updates. The use oflogger.V(4).Infofor 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 oferr(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
Startmethod now properly usescheck(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).Infofor 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
LogFormatterinterface now acceptsklog.Loggeras 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
Serverinterface properly threadscontext.ContextthroughStartandServemethods, enabling per-request/per-operation logging throughout the server lifecycle.
31-38: LGTM! Proper context-based logging in error handler.The
checkfunction correctly extracts the logger from context before logging the error. The existing Sentry integration andos.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
NewLoggingWriterconstructor correctly accepts aklog.Loggerparameter and initializes the struct with it, enabling per-request logging.
31-38: LGTM! Logging implementation is correct.The
logmethod properly uses verbosity levelV(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
prepareRequestLogandprepareResponseLogcorrectly pass the logger to the formatter methods, aligning with the updatedLogFormatterinterface.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 loggingcmd/maestro/server/api_server.go (4)
39-43: LGTM! Constructor properly propagates context.The
NewAPIServerconstructor correctly accepts context and passes it toroutes(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 theglogimport is required here for OCM SDK'sNewGlogLoggerBuildercompatibility—this is separate from the klog migration.
147-170: LGTM! Serve method with proper context-based logging.The
Servemethod correctly:
- Extracts the logger from context
- Uses structured logging with key-value pairs (
"port", ...)- Propagates context to the
checkfunction for error logging
179-198: LGTM! Start method correctly handles errors without bypassing defer.The previous review concern about
os.Exit(1)bypassing the deferreds.grpcServer.Stop()has been properly addressed—the code now usesreturn(line 190) to allow the defer to execute.cmd/maestro/server/healthcheck_server.go (4)
78-85: Potential blocking issue after server termination.If
ListenAndServereturns due to an error (other thanhttp.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
pulsemethod correctly derives the logger from context and uses structured logging with appropriate key-value pairs for error logging.
126-173: LGTM!The
checkInstancesmethod properly uses context-derived logging with structured key-value pairs for both info and error messages.
177-202: LGTM!The
healthCheckHandlercorrectly derives the logger from the request context and enriches it withinstanceID. 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
CleanDBmethod 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
NewGRPCServerconstructor correctly accepts a context as the first parameter and derives a logger for use in the initialization path.
266-361: LGTM!The
Subscribemethod 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 withsendErrChis well-designed for unregistering subscribers on connection failures.
149-159: LGTM!The
Startmethod correctly derives a logger from context and uses structured logging for lifecycle and error messages.
167-194: LGTM!The
Publishmethod 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
Runmethod correctly derives a logger from context and uses context-awarewaitfunctions for the periodic sync and worker goroutines.
104-106: LGTM!The per-event logger enrichment with
StatusEventIDprovides 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
syncStatusEventsmethod 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
Runmethod correctly derives a logger from context, uses deferred shutdown, and properly employs context-awarewaitfunctions for periodic sync and worker goroutines.
118-120: LGTM!The per-event logger enrichment pattern is well-designed. Creating
reqContextwith 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
processNextEventmethod 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
syncEventsmethod 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/v2here is consistent with the new contextual logging approach. Just make surego.mod/go.sumare 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")andUpdateAdvisoryLockDurationMetricinto 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 goodUsing
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
handleStatusUpdatecorrectly pulls a logger fromctxand 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 inbroadcastStatusEventis appropriately keyedThe logger derived via
klog.FromContext(ctx).WithValues("resourceID", resourceID, "instanceID", instanceID, "eventID", eventID)and theInfocalls for “skipping resource as it is not found” and “Broadcast the resource status” give clear, structured diagnostics without changing control flow or error handling.
Signed-off-by: Jian Qiu <[email protected]>
There was a problem hiding this 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 inInitlooks correct; consider structured logging optionallySwitching the two error paths in
Inittoklog.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 toklog.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 usescontext.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 updatingStop()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/v2import is placed between standard library imports (contextandreflect), 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, theklog/v2import 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 toonInstanceDown.This function uses
context.TODO()while the rest of the file has migrated to context-based patterns. SinceonInstanceUpdatehas access to the logger but not a context, and this function is only called from there, consider either:
- Passing the logger as a parameter for potential future logging needs
- Storing context in the struct during
Startfor use in callbacksThis 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/v2import 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
nilinjsonResponseLoginitialization (line 37), butResponseInfocontains 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) andklog.Fatalf(line 46), but the import still includes the standardlogpackage. Iflogis 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
⛔ Files ignored due to path filters (1)
go.sumis 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 impactThe 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
updateConsumerSetcorrectly 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 appropriateThe added
k8s.io/klog/v2import 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/v2is 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
consumersas 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
Serveimplementation with unused parameters is appropriate since this metrics server uses theStart()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/zapimports andzap.*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
EventIDconstant 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 bothSendAPIandSendAPIV1, 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 sinceinit()runs before any request context exists. The error leads toos.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
resourceIDfor traceability, andV(4)is appropriately used for verbose event payload logging.
86-93: LGTM!The change from
errtoeErrcorrectly 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
onInstanceUpdatecallback, ensuring consistent logging context across async operations.pkg/db/db_session/default.go (2)
141-167: LGTM!The logging implementation in
waitForNotificationis well-structured with appropriate verbosity levels:V(4)for routine notification events andInfofor significant state changes like connection loss.
170-177: LGTM!The logger is correctly captured in the closure for the
plogcallback, ensuring structured logging with context is available when the listener reports state changes.pkg/controllers/status_controller.go (3)
51-66: LGTM!The
Runmethod correctly implements context-driven lifecycle management with proper logger derivation and context-aware scheduling viawait.JitterUntilWithContextandwait.UntilWithContext.
104-106: LGTM!The context construction pattern correctly combines
klog.NewContextfor the enriched logger withcontext.WithValuefor the event ID, ensuring both are available to downstream handlers.
161-190: LGTM!The
syncStatusEventsmethod 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
Runmethod follows the same well-structured pattern asStatusController, with proper context-driven lifecycle management and context-aware scheduling functions.
204-230: LGTM!The
processNextEventmethod correctly handles queue operations with proper error logging. While the logger at line 214 adds thekeyfield only for local use, this is acceptable sincehandleEventindependently enriches its context withEventID.
118-121: LGTM!The
handleEventmethod correctly creates a per-event logger enriched withEventIDand properly constructs a request context that carries both the logger and the event ID value for downstream handlers.
232-258: LGTM!The
syncEventsmethod 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
ctxtohandleEvent, 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
handleEventcalls.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
checkfunction receives context for contextual error handling/logging.
30-31: Auth middleware uses mocks unconditionally (confirmed intentional).Per past review discussion,
EnableJWTandEnableAuthzflags 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
errorsalias 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+NewContextenables 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).Infofor verbose request/response logging- Properly delegates the logger to formatter methods matching the updated
LogFormatterinterfacecmd/maestro/server/event_server.go (2)
77-117: LGTM! Proper context-aware logging with resource enrichment.Good patterns observed:
- Logger enriched with
resourceIDandactionviaWithValues- 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
handleStatusUpdateandbroadcastStatusEventfunctions 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
instanceIDand 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).Infofor "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 directos.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).Infofor "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
ServeandStartmethods 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.Contextas 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.WithCancelfrom the RPC context)- Uses the logger throughout the method, including in goroutines and callbacks
- Threads context through to
WritePBMessageandUnregistercalls- 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 thecheck()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 viaklog.FromContext(ctx). However, thecheck()function definition must be verified to confirm it acceptscontext.Contextas 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
ctxtoNewHealthCheckServerandNewGRPCBroker, 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
NewAPIServerconstructor- Passes context to
Startmethod- Uses the context-derived logger for all log statements
218-242: LGTM - Server start methods correctly implement contextual logging.Both
startMetricsServerandstartHealthCheckServerproperly:
- Derive a logger from
helper.Ctx- Pass context to the
Startmethod- Use the context-derived logger for all log statements
249-265: LGTM - Event server and broadcaster start methods correctly implement contextual logging.Both
startEventServerandstartEventBroadcasterproperly:
- Derive a logger from
helper.Ctx- Pass context to the
Startmethod- Use the context-derived logger for all log statements
362-374: LGTM - Restart methods correctly use contextual logging.Both
RestartServerandRestartMetricsServerproperly derive a logger fromhelper.Ctxand use it for logging.
376-396: LGTM - Reset method correctly implements contextual logging.The method properly derives a logger from
helper.Ctxand 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.Ctxand 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) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why reset ctx here?
There was a problem hiding this comment.
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
cmd/maestro/server/event_server.go
Outdated
|
|
||
| // 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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| logger.Info("Broadcast the resource status", "statusEventType", statusEvent.StatusEventType) | |
| logger.Info("Broadcast the resource status", "resoruceSource", resource.Source, "statusEventType", statusEvent.StatusEventType) |
cmd/maestro/server/grpc_broker.go
Outdated
| // 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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 ...
cmd/maestro/server/grpc_server.go
Outdated
| 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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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) | |
| } |
cmd/maestro/server/grpc_server.go
Outdated
| 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()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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]>
clyang82
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
No description provided.