-
Notifications
You must be signed in to change notification settings - Fork 104
feat: [#726][Trace] Add OpenTelemetry Tracing Support for Distributed Tracing #1283
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
base: master
Are you sure you want to change the base?
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #1283 +/- ##
==========================================
- Coverage 68.56% 68.49% -0.07%
==========================================
Files 264 274 +10
Lines 15566 15945 +379
==========================================
+ Hits 10673 10922 +249
- Misses 4430 4553 +123
- Partials 463 470 +7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
Pull request overview
This PR claims to add OpenTelemetry tracing support for distributed tracing (issue #726), but the implementation is incomplete. The PR only creates a placeholder file with no actual functionality, no OpenTelemetry dependencies, and no tests.
Key observations:
- Only a single file is added:
contracts/telemetry/telemetry.gocontaining only a package declaration and a placeholder comment - No OpenTelemetry dependencies are added to
go.mod - No actual tracing interfaces, types, or implementation code exists
- No test coverage is provided
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Pull request overview
Copilot reviewed 26 out of 27 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Exporters Configuration | ||
| // | ||
| // Configure exporters for sending telemetry data. | ||
| // Supported drivers: "otlp", "zipkin", "console" |
Copilot
AI
Dec 7, 2025
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.
The comment says "Supported drivers" but should say "Supported exporters" for consistency with the rest of the configuration comments and the actual setting name ("exporter").
| // Supported drivers: "otlp", "zipkin", "console" | |
| // Supported exporters: "otlp", "zipkin", "console" |
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.
⚠️ 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: 212a54b | Previous: 6ef4277 | Ratio |
|---|---|---|---|
Benchmark_DecryptString |
5648 ns/op 2032 B/op 16 allocs/op |
2017 ns/op 2032 B/op 16 allocs/op |
2.80 |
Benchmark_DecryptString - ns/op |
5648 ns/op |
2017 ns/op |
2.80 |
BenchmarkFile_ReadWrite |
197815 ns/op 6258 B/op 99 allocs/op |
128378 ns/op 6257 B/op 99 allocs/op |
1.54 |
BenchmarkFile_ReadWrite - ns/op |
197815 ns/op |
128378 ns/op |
1.54 |
This comment was automatically generated by workflow using github-action-benchmark.
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.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| "go.opentelemetry.io/otel/attribute" | ||
| "go.opentelemetry.io/otel/sdk/resource" | ||
| semconv "go.opentelemetry.io/otel/semconv/v1.37.0" |
Copilot
AI
Dec 7, 2025
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.
The import semconv "go.opentelemetry.io/otel/semconv/v1.37.0" is used but this dependency is not declared in go.mod or go.sum. This will cause compilation failures. The semconv package needs to be added as a direct dependency in go.mod.
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.
Because this is not direct dependency but a subpart of otel#v1.138.0 package
| // | ||
| // cfg.GetString(ConfigServiceName.String()) | ||
| // cfg.GetString(ConfigExporter.With("otlp")) | ||
| type Key string |
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.
Previously, configuration keys were declared as plain strings on-demand throughout the framework, making them inconsistent and error-prone. This package (support/config) provides a Key type that each package can use to define their own configuration keys in a consistent manner. (open to move the type in different package)
hwbrzzl
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.
Awesome 👍 Two middleware (http/grpc) should be needed, correct? Normally, users don't need to use facades.Telemetry() directly.
| Install( | ||
| modify.AddProviderApply(modulePath, telemetryServiceProvider), | ||
| modify.File(telemetryConfigPath).Overwrite(stubs.Config(packages.GetModuleNameFromArgs(os.Args))), | ||
| modify.WhenFacade(facades.Telemetry, modify.File(telemetryFacadePath).Overwrite(stubs.TelemetryFacade())), |
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.
There is only one facade, so modify.WhenFacade and modify.WhenNoFacades are unnecessary here. I'm going to remove others later.
| "name": config.Env("OTEL_SERVICE_NAME", "goravel"), | ||
| "version": config.Env("OTEL_SERVICE_VERSION", ""), | ||
| "environment": config.Env("OTEL_SERVICE_ENVIRONMENT", ""), |
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.
How about using APP_NAME, APP_ENV, and APP_VERSION?
| // Propagators | ||
| // | ||
| // Propagators define how trace context is passed between services. | ||
| // Supported: "tracecontext", "baggage", "b3", "b3multi", "none" |
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.
When will the none be used? Can it be removed and use empty instead?
| // Configure distributed tracing for your application. | ||
| "traces": map[string]any{ | ||
| // The exporter determines where traces are sent. | ||
| // Supported: "otlp", "zipkin", "console", "none" |
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.
Ditto
| "args": map[string]any{ | ||
| // Sampling ratio for "traceidratio" (0.0 to 1.0) | ||
| "ratio": config.Env("OTEL_TRACES_SAMPLER_RATIO", 0.05), | ||
| }, |
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.
How about args.ratio -> ratio? Add a parent level args seems to be unnecessary.
| if len(propagators) == 0 { | ||
| return defaultCompositePropagator | ||
| } |
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.
| if len(propagators) == 0 { | |
| return defaultCompositePropagator | |
| } |
| if nameStr == "" { | ||
| return defaultCompositePropagator | ||
| } | ||
|
|
||
| if nameStr == propagatorNone { | ||
| return nonePropagator | ||
| } |
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.
propagators should be declared.
| if nameStr == "" { | |
| return defaultCompositePropagator | |
| } | |
| if nameStr == propagatorNone { | |
| return nonePropagator | |
| } |
| exporterName := r.config.GetString(configTracesExporter.String()) | ||
| if exporterName == "" || exporterName == "none" { | ||
| return nil | ||
| } |
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.
This judgment can be moved to createExporter.
| if r.propagator == nil { | ||
| return defaultCompositePropagator | ||
| } |
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.
r.propagator needs to respect newCompositeTextMapPropagator's result, I think. r.propagator should be not reset here.
| if r.propagator == nil { | |
| return defaultCompositePropagator | |
| } |
| propagator propagation.TextMapPropagator | ||
| } | ||
|
|
||
| func NewApplication(cfg config.Config) (*Application, error) { |
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.
When writing test cases, we have to mock every configuration. Sometimes it's very complicated. Ideally, every module should have its own config interface to fetch configuration, and have a Config struct to be initiated in NewApplication, then the config can be mocked. We can optimized it later if you agree.
📑 Description
RelatedTo goravel/goravel#726
Summary
Introduces a new
Telemetrymodule providing OpenTelemetry-based distributed tracing for Goravel applications.Features:
Note
Currently It doesn't support custom exporter, I will add this feature in next couple of PR
Usage
Configuration (
.env)Creating Traces
Context Propagation
Shutdown
Configuration Reference
OTEL_TRACES_EXPORTERotlpotlp,zipkin,console,noneOTEL_TRACES_SAMPLER_TYPEalways_onalways_on,always_off,traceidratioOTEL_PROPAGATORStracecontext,baggagetracecontext,baggage,b3,b3multi✅ Checks