Skip to content

Plugins: Chore: Renamed instrumentation middleware to metrics middleware#4

Closed
ShashankFC wants to merge 1 commit into
mainfrom
plugins/rename-instrumentation-middleware-to-metrics-middleware
Closed

Plugins: Chore: Renamed instrumentation middleware to metrics middleware#4
ShashankFC wants to merge 1 commit into
mainfrom
plugins/rename-instrumentation-middleware-to-metrics-middleware

Conversation

@ShashankFC

@ShashankFC ShashankFC commented Dec 31, 2025

Copy link
Copy Markdown
Collaborator

Test 3nn

Summary by CodeRabbit

  • New Features

    • Added context-aware logging that enriches request logs with plugin ID, endpoint name, data source information, and user login details for improved plugin operation visibility and debugging.
  • Refactor

    • Refactored plugin middleware architecture to better separate logging and metrics concerns, improving code maintainability and clarity.

✏️ Tip: You can customize this high-level summary in your review settings.

nn---n*Replicated from [ai-code-review-evaluation/grafana-coderabbit#3](https://github.com/ai-code-review-evaluation/grafana-coderabbit/pull/3)*

…are (#76186)

* Plugins: Chore: Renamed instrumentation middleware to metrics middleware

* Removed repeated logger attributes in middleware and contextual logger

* renamed loggerParams to logParams

* PR review suggestion

* Add contextual logger middleware

* Removed unused params from logRequest

* Removed unwanted changes

* Safer FromContext method

* Removed traceID from logParams
@ShashankFC

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jan 12, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jan 12, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This change standardizes the logging API by replacing interface{} with any, adds a FromContext method to extract loggers from context, introduces a new ContextualLoggerMiddleware to enrich request context with logging metadata, and refactors the middleware architecture by renaming InstrumentationMiddleware to MetricsMiddleware while separating concerns between metrics and contextual logging.

Changes

Cohort / File(s) Summary
Logger API Updates
pkg/plugins/log/fake.go, pkg/plugins/log/ifaces.go, pkg/plugins/log/logger.go
Standardized variadic parameters from interface{} to any across Logger and PrettyLogger interfaces; added FromContext(context.Context) Logger method to Logger interface; implemented FromContext in TestLogger and grafanaInfraLogWrapper; added Ctx []any field to Logs struct.
Middleware Architecture Refactoring
pkg/services/pluginsintegration/clientmiddleware/metrics_middleware.go, pkg/services/pluginsintegration/clientmiddleware/metrics_middleware_test.go
Renamed InstrumentationMiddleware to MetricsMiddleware; updated constructor and all method receivers; removed contextual logger instrumentation and log package dependency; preserved metric collection logic.
Contextual Logger Middleware
pkg/services/pluginsintegration/clientmiddleware/contextual_logger_middleware.go
New middleware component that instruments request context with endpoint, pluginId, dsName, dsUID, and uname attributes for QueryData, CallResource, CheckHealth, and CollectMetrics operations; forwards streaming operations without instrumentation.
Logger Middleware Refactoring
pkg/services/pluginsintegration/clientmiddleware/logger_middleware.go
Simplified logRequest signature to accept only context and callback function; removed plugin-specific metadata parameters (pluginCtx, endpoint); changed to use logger.FromContext(ctx) for retrieving contextual logger.
Middleware Integration Update
pkg/services/pluginsintegration/pluginsintegration.go
Updated middleware instantiation from NewInstrumentationMiddleware to NewMetricsMiddleware; added NewContextualLoggerMiddleware in middleware chain before LoggerMiddleware.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 From interface{} to any, so clean and bright,
Context flows through loggers with newfound might,
Middleware dances in separation's grace,
Metrics and logging each find their place,
A refactor most tidy, a changelog's delight! 📝✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring: renaming InstrumentationMiddleware to MetricsMiddleware and introducing contextual logging middleware alongside other supporting changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (4)
pkg/services/pluginsintegration/clientmiddleware/contextual_logger_middleware.go (1)

59-69: Streaming methods skip contextual logging instrumentation.

Unlike the non-streaming methods (QueryData, CallResource, etc.), these streaming methods (SubscribeStream, PublishStream, RunStream) do not call instrumentContext. If this is intentional due to different lifecycle semantics of streaming operations, consider adding a brief comment explaining why. Otherwise, consider adding instrumentation for consistency.

pkg/plugins/log/fake.go (1)

46-48: Test fake discards context - consider preserving for assertions.

The FromContext implementation returns a fresh TestLogger, discarding any contextual attributes stored in the provided context. While acceptable for a simple fake, this means tests using this logger won't be able to verify that contextual attributes were properly propagated.

Consider storing the context or returning the same logger instance if tests need to assert on contextual logging behavior:

♻️ Optional: preserve context for test assertions
-func (f *TestLogger) FromContext(_ context.Context) Logger {
-	return NewTestLogger()
+func (f *TestLogger) FromContext(ctx context.Context) Logger {
+	// Return same instance to allow tests to capture logs with context
+	return f
 }
pkg/plugins/log/logger.go (1)

48-56: Silent fallback may obscure configuration issues.

When the type assertion fails (line 49-51), the method silently returns a new logger via d.New(), potentially losing contextual attributes. While this "safe" fallback prevents panics, consider logging a warning when this fallback occurs to aid debugging if contextual logging unexpectedly stops working.

♻️ Optional: add debug logging on fallback
 func (d *grafanaInfraLogWrapper) FromContext(ctx context.Context) Logger {
 	concreteInfraLogger, ok := d.l.FromContext(ctx).(*log.ConcreteLogger)
 	if !ok {
+		d.l.Debug("FromContext: unexpected logger type, falling back to new logger")
 		return d.New()
 	}
 	return &grafanaInfraLogWrapper{
 		l: concreteInfraLogger,
 	}
 }
pkg/services/pluginsintegration/clientmiddleware/metrics_middleware_test.go (1)

21-21: Consider renaming test function to match middleware rename.

The test function is still named TestInstrumentationMiddleware while the middleware has been renamed to MetricsMiddleware. For consistency and discoverability, consider renaming to TestMetricsMiddleware.

♻️ Suggested rename
-func TestInstrumentationMiddleware(t *testing.T) {
+func TestMetricsMiddleware(t *testing.T) {
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5dac673 and 00393c2.

📒 Files selected for processing (8)
  • pkg/plugins/log/fake.go
  • pkg/plugins/log/ifaces.go
  • pkg/plugins/log/logger.go
  • pkg/services/pluginsintegration/clientmiddleware/contextual_logger_middleware.go
  • pkg/services/pluginsintegration/clientmiddleware/logger_middleware.go
  • pkg/services/pluginsintegration/clientmiddleware/metrics_middleware.go
  • pkg/services/pluginsintegration/clientmiddleware/metrics_middleware_test.go
  • pkg/services/pluginsintegration/pluginsintegration.go
🧰 Additional context used
🧬 Code graph analysis (4)
pkg/services/pluginsintegration/clientmiddleware/logger_middleware.go (1)
pkg/services/contexthandler/contexthandler.go (1)
  • FromContext (46-51)
pkg/services/pluginsintegration/clientmiddleware/contextual_logger_middleware.go (2)
pkg/plugins/ifaces.go (2)
  • ClientMiddleware (142-145)
  • ClientMiddlewareFunc (150-150)
pkg/infra/log/log.go (1)
  • WithContextualAttributes (285-291)
pkg/plugins/log/ifaces.go (2)
pkg/plugins/log/logger.go (1)
  • New (9-13)
pkg/services/contexthandler/contexthandler.go (1)
  • FromContext (46-51)
pkg/services/pluginsintegration/clientmiddleware/metrics_middleware.go (3)
pkg/plugins/ifaces.go (2)
  • ClientMiddleware (142-145)
  • ClientMiddlewareFunc (150-150)
pkg/plugins/errors.go (1)
  • ErrPluginNotRegistered (9-9)
pkg/tsdb/prometheus/querydata/request.go (1)
  • QueryData (37-47)
🔇 Additional comments (11)
pkg/services/pluginsintegration/pluginsintegration.go (1)

157-167: LGTM! Middleware chain order is logical.

The middleware ordering is sensible:

  1. TracingMiddleware - establishes trace context first
  2. MetricsMiddleware - records metrics including duration
  3. ContextualLoggerMiddleware - enriches context with logging attributes
  4. LoggerMiddleware - consumes enriched context for logging

This ensures logging attributes are available to downstream middlewares and the logger.

pkg/services/pluginsintegration/clientmiddleware/metrics_middleware_test.go (1)

78-84: LGTM!

The constructor call correctly updated to use newMetricsMiddleware, consistent with the middleware rename.

pkg/services/pluginsintegration/clientmiddleware/contextual_logger_middleware.go (2)

12-42: LGTM! Middleware implementation follows established patterns.

The constructor and core instrumentation logic are well-structured. The use of log.WithContextualAttributes correctly enriches the context with logging metadata, and the endpoint constants are properly defined.


26-37: No actionable concerns. The logging of user login information via pCtx.User.Login is consistent with existing patterns throughout the codebase (e.g., pkg/api/featuremgmt.go, pkg/api/pluginproxy/), indicating this is an accepted logging practice.

Likely an incorrect or invalid review comment.

pkg/services/pluginsintegration/clientmiddleware/logger_middleware.go (3)

62-74: LGTM!

The QueryData method correctly delegates to logRequest with the context and inner operation. The nil-check early return is preserved.


76-127: LGTM!

All remaining methods follow the established pattern consistently. The streaming methods (SubscribeStream, PublishStream, RunStream) intentionally bypass logging, which aligns with the design to only instrument request-response style operations.


36-60: Middleware ordering dependency confirmed.

The refactored logRequest correctly relies on FromContext(ctx) to obtain a logger with contextual metadata (endpoint, pluginId, dsName, dsUID, uname) injected by ContextualLoggerMiddleware. This achieves clean separation of concerns between context enrichment and logging.

The middleware chain in pluginsintegration.go correctly places ContextualLoggerMiddleware (line 160) before LoggerMiddleware (line 161), ensuring context is enriched before logging occurs.

pkg/services/pluginsintegration/clientmiddleware/metrics_middleware.go (2)

84-142: LGTM!

The helper methods are well-structured:

  • pluginTarget correctly handles the case where the plugin is not registered
  • instrumentPluginRequestSize properly tracks request sizes
  • instrumentPluginRequest handles timing, status tracking, and Prometheus exemplars for tracing correlation

144-197: LGTM!

The interface methods are consistently implemented. The rename from InstrumentationMiddleware to MetricsMiddleware better reflects the purpose (Prometheus metrics collection). Streaming methods appropriately pass through without instrumentation.

pkg/plugins/log/ifaces.go (2)

26-40: LGTM!

Consistent modernization of PrettyLogger interface to use any instead of interface{}.


3-24: Good modernization with context-aware logging properly implemented across all components.

The changes to the Logger interface are well-designed:

  1. Using any instead of interface{} aligns with Go 1.18+ idiomatic style
  2. The new FromContext(ctx context.Context) Logger method enables context-aware logging, allowing middleware to inject contextual metadata

All Logger implementations have been properly updated with the FromContext method: both grafanaInfraLogWrapper and TestLogger include the required implementation.

Comment on lines +75 to 82
// NewMetricsMiddleware returns a new MetricsMiddleware.
func NewMetricsMiddleware(promRegisterer prometheus.Registerer, pluginRegistry registry.Service) plugins.ClientMiddleware {
imw := newMetricsMiddleware(promRegisterer, pluginRegistry)
return plugins.ClientMiddlewareFunc(func(next plugins.Client) plugins.Client {
imw.next = next
return imw
})
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

rg -n 'NewMetricsMiddleware' --type go -A 3 -B 1

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 1457


🏁 Script executed:

# Also check the metrics registration in newMetricsMiddleware
rg -n 'newMetricsMiddleware' --type go -A 20

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 7992


🏁 Script executed:

# Check if there are any tests for this middleware
fd -e test.go | xargs rg -l 'MetricsMiddleware|metrics_middleware' --type go

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 718


🏁 Script executed:

# Find where the middleware list is used after creation
rg -n 'clientmiddleware\.New' --type go -B 2 -A 10

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 3072


🏁 Script executed:

# Check how middlewares are applied to clients
rg -n 'ClientMiddleware' --type go -A 5 | head -100

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 10945


🏁 Script executed:

# Check how the middleware list is used - find where it's passed/applied
rg -n 'CreateMiddlewares\|middlewares' --type go -B 2 -A 5 | grep -A 10 'CreateMiddlewares'

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 65


🏁 Script executed:

# Look for plugin client creation/wrapping logic
rg -n 'ClientMiddlewareFunc|plugins\.Client' --type go -B 2 -A 8 | head -120

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 8090


🏁 Script executed:

# Check the ClientMiddleware interface definition
rg -n 'type ClientMiddleware' --type go -A 3

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 630


🏁 Script executed:

# Find where the middlewares are used after CreateMiddlewares returns
rg -n 'CreateMiddlewares' --type go -B 2 -A 15

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 4121


🏁 Script executed:

# Look for how many plugin clients are created and if they share middlewares
rg -n 'NewDecorator\|clientFromMiddlewares' --type go -B 3 -A 8

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 65


🏁 Script executed:

# Check how NewDecorator is used - is it called once or multiple times?
rg -n 'NewDecorator' --type go -B 2 -A 5

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 3823


🏁 Script executed:

# Look at the Decorator implementation to understand the flow better
cat -n pkg/plugins/manager/client/decorator.go | head -50

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 1680


🏁 Script executed:

# Look at how clientFromMiddlewares is called - is it called per request?
cat -n pkg/plugins/manager/client/decorator.go | sed -n '29,75p'

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 1834


🏁 Script executed:

# Check how many methods call clientFromMiddlewares
rg -n 'clientFromMiddlewares' pkg/plugins/manager/client/decorator.go

Repository: AI-Code-Review-Evals/coderabbit-grafana

Length of output: 625


Race condition when middleware is used with concurrent requests.

The NewMetricsMiddleware factory creates a single *MetricsMiddleware instance and returns a closure that sets imw.next each time it's invoked. The closure is called once per request via clientFromMiddlewares() (called in every Decorator method: QueryData, CallResource, CollectMetrics, CheckHealth, SubscribeStream, PublishStream, CallRoute). With concurrent requests, multiple goroutines will simultaneously write to imw.next, causing a data race and potential request routing errors.

Compare to other middlewares like NewTracingMiddleware and NewCachingMiddleware, which correctly create a new instance per closure invocation. The fix requires creating a new middleware instance per request while registering Prometheus metrics once at initialization.

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 2 weeks if no further activity occurs. Please feel free to give a status update or ping for review. Thank you for your contributions!

@github-actions github-actions Bot added the stale label Feb 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been automatically closed because it has not had any further activity in the last 2 weeks. Thank you for your contributions!

@github-actions github-actions Bot closed this Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant