feat: [#726] Add gRPC telemetry instrumentation [4]#1305
feat: [#726] Add gRPC telemetry instrumentation [4]#1305krishankumar01 merged 26 commits intomasterfrom
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1305 +/- ##
==========================================
+ Coverage 69.20% 69.41% +0.20%
==========================================
Files 280 282 +2
Lines 16517 16630 +113
==========================================
+ Hits 11431 11543 +112
+ Misses 4599 4596 -3
- Partials 487 491 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR adds automatic HTTP instrumentation for OpenTelemetry tracing and metrics to the Goravel framework. It introduces a configurable middleware that creates spans, records metrics (request duration, body sizes), and propagates trace context for incoming HTTP requests.
- Adds a new HTTP telemetry middleware with configurable span naming, path/method exclusion, and custom filters
- Introduces global telemetry and config facades in the service provider for convenient access
- Provides configuration options for enabling/disabling instrumentation and customizing behavior
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| telemetry/service_provider.go | Adds global facades for Config and Telemetry, and updates Boot method to initialize them |
| telemetry/instrumentation/http/middleware.go | Implements HTTP server instrumentation middleware with tracing and metrics collection |
| telemetry/instrumentation/http/config.go | Defines configuration structure and options for HTTP instrumentation |
| telemetry/alias.go | Adds KeyValue type alias for OpenTelemetry attributes |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.
| Benchmark suite | Current: 3c4d11a | Previous: 91bf06d | Ratio |
|---|---|---|---|
Benchmark_Fatal |
5e-7 ns/op 0 B/op 0 allocs/op |
2e-7 ns/op 0 B/op 0 allocs/op |
2.50 |
Benchmark_Fatal - ns/op |
5e-7 ns/op |
2e-7 ns/op |
2.50 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
hwbrzzl
left a comment
There was a problem hiding this comment.
Great PR, LGTM 👍 Could you fill the PR description and add some screenshots for the testing and show how to use the handler?
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 22 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 22 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 22 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for _, h := range app.serverStatsHandlers { | ||
| if h == nil { | ||
| continue | ||
| } | ||
| opts = append(opts, grpc.StatsHandler(h)) | ||
| } |
There was a problem hiding this comment.
gRPC only supports registering one stats handler per server. When multiple grpc.StatsHandler() calls are made, only the last one takes effect (they overwrite each other). This loop will result in only the last non-nil handler being registered, making all previous handlers ineffective.
If multiple handlers are needed, consider creating a composite stats handler that internally delegates to multiple handlers, or document that only one handler should be registered.
There was a problem hiding this comment.
@copilot No, this behavior has already changed. gRPC now supports multiple StatsHandlers, and all of them are used.
I have added the steps to enable auto telemetry for the gRPC server and client, along with screenshots I used to test the feature locally. I have also optimized the gRPC facade to support the new requirements and provided clearer warnings on how to use it. |
hwbrzzl
left a comment
There was a problem hiding this comment.
func (s *GrpcServiceProvider) Boot() {
// Register a client handler for a specific group (e.g., "user")
facades.Grpc().ClientStatsHandlerGroups(map[string][]stats.Handler{
"user": {
telemetrygrpc.NewClientStatsHandler(),
},
})
// Register a global server handler
facades.Grpc().ServerStatsHandlers([]stats.Handler{
telemetrygrpc.NewServerStatsHandler(),
})
}
We can use the With* functions instead of the above, correct?
"interceptors": []string{"user"} is for interceptor, should a new configuration for StatsHandler be added in the config file?
Yes, you can use
I thought it would be more convenient for users to use the same key for both and register it in one place. Since interceptors and stats handlers are different, I added a new |
📑 Description
RelatedTo goravel/goravel#726
This PR introduces
stats.Handlersupport to enable metrics emission and trace propagation for both gRPC servers and clients. Specifically, it exposes newNewServerStatsHandlerandNewClientStatsHandlerutilities via thegithub.com/framework/telemetry/instrumentation/grpcpackage.Registration
You can register these stats handlers using the new
ClientStatsHandlerGroupsandServerStatsHandlersmethods on the gRPC facade, typically within your custom Service Providers.Note
These handlers usually depend on the Telemetry facade. If the Telemetry service is not available or registered, the system will log a warning to prevent issues with nil service providers.
Example: Registering in a Service Provider
Warning
Important Configuration Note
When registering client handlers, the key you use (e.g., "user") acts as a "group name." For the handler to actually take effect, this same group name must be listed in your config/grpc.go file under the client's
stats_handlersarray. The framework automatically loads the Stats Handlers assigned to that group key.Example: config/grpc.go
Bootstrap Configuration
For applications using the new slim skeleton, you can also configure these handlers directly in
bootstrap/app.gousing the fluentWithGrpcClientStatsHandlersandWithGrpcServerStatsHandlersmethods.Options
The
instrumentation/grpcpackage exposes several options to further customize the handlers, such asWithFilter(to skip instrumentation based on specific criteria),WithSpanAttributes, andWithMetricAttributes.Example: Using Filters and Attributes
Configuration
General tracing and metrics settings (exporters, sampling, etc.) can continue to be customized in
config/telemetry.go.Screenshots
✅ Checks