feat: [#726][Log] add distributed logging and auto-instrumentation using OpenTelemetry [3]#1295
feat: [#726][Log] add distributed logging and auto-instrumentation using OpenTelemetry [3]#1295krishankumar01 merged 17 commits intomasterfrom
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #1295 +/- ##
==========================================
+ Coverage 69.16% 69.24% +0.08%
==========================================
Files 276 280 +4
Lines 16168 16477 +309
==========================================
+ Hits 11182 11410 +228
- Misses 4510 4583 +73
- Partials 476 484 +8 ☔ 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 comprehensive OpenTelemetry logging support to the telemetry module, complementing the existing tracing and metrics functionality. It introduces a new Logger provider that integrates seamlessly with the telemetry application architecture.
Key changes:
- Implements
NewLoggerProviderwith support for OTLP (HTTP/gRPC), console, and custom log exporters - Adds
LogsConfigandLogsProcessorConfigto the telemetry configuration structure - Integrates the logger provider into the telemetry
Applicationwith proper initialization and shutdown handling
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| telemetry/log.go | Implements core logging functionality with support for multiple exporter types and batch processing |
| telemetry/log_test.go | Provides comprehensive test coverage for logger provider creation and exporter configurations |
| telemetry/config.go | Adds logging configuration structures for exporter and processor settings |
| telemetry/application.go | Integrates logger provider into the telemetry application with proper lifecycle management |
| telemetry/application_test.go | Updates existing tests to verify logger provider initialization and removes redundant comment |
| contracts/telemetry/telemetry.go | Extends the Telemetry interface with Logger method and documentation |
| mocks/telemetry/Telemetry.go | Generates mock implementation for the Logger method |
| errors/list.go | Adds TelemetryLogViaTypeMismatch error for custom logger validation |
| go.mod | Adds required OpenTelemetry logging dependencies (v0.15.0) |
| go.sum | Updates checksums for new logging dependencies |
💡 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 16 out of 17 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.
⚠️ 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: 87961f7 | Previous: 6e3ccd0 | Ratio |
|---|---|---|---|
BenchmarkFile_ReadWrite |
283964 ns/op 6257 B/op 99 allocs/op |
183255 ns/op 6257 B/op 99 allocs/op |
1.55 |
BenchmarkFile_ReadWrite - ns/op |
283964 ns/op |
183255 ns/op |
1.55 |
This comment was automatically generated by workflow using github-action-benchmark.
hwbrzzl
left a comment
There was a problem hiding this comment.
Awesome, only left a question.
There was a problem hiding this comment.
Why is the instrumentation needed instead of log directly? And the files in the log folder are for the log channel. Can they be moved to the framework/log folder directly?
And for the new configuration:
// config/telemetry.go
"instrumentation": map[string]any{
"log": map[string]any{
"enabled": true,
"name": "goravel/log",
},
},
Is it required? Can it be removed? It can be considered as enabled if user uses the log channel.
And for the log configuration:
"otel": map[string]any{
"driver": "custom",
"via": telemetrylog.NewTelemetryChannel(),
},
We can set otel as the framework internal driver:
"otel": map[string]any{
"driver": "otel",
...
},
There was a problem hiding this comment.
That makes sense. I agree that exposing it as a native driver is cleaner, it removes the need for the separate telemetry config since adding the driver effectively 'enables' it. But I don't want to add a direct dependencies on telemetry pacakge when we use package:install command to install log package.

Regarding the file location, I’d prefer to keep it in instrumentation/log. I plan to add other OTel instrumentations (like http_server and http_client) soon, and grouping all the OTel adapters together under telemetry/instrumentation/ keeps the project structure much more organized than scattering them across different packages.
There was a problem hiding this comment.
Good point, it's heavy to install Telemetry when installing Log, given that most users should not use Telemetry. It's fine to keep the new hook in instrumentation/log, but the otel log driver can be kept as well, the configuration below can be added when installing the Telemetry facade.
"otel": map[string]any{
"driver": "custom",
"via": telemetrylog.NewTelemetryChannel(),
},
There was a problem hiding this comment.
But the OpenTelemetry log driver can be kept as well.
Do we need to expose this channel as both the otel log driver and a custom one?
The configuration below can be added when installing the Telemetry facade.
Good idea, I’ll add this to the setup file so it gets registered automatically.
There was a problem hiding this comment.
Only the otel log driver should be fine, and the otel driver doesn't need to be pointed out in the log config, given that it will be added to the log config when installing Telemetry.
There was a problem hiding this comment.
@hwbrzzl By the way, we need to optimize the log.WithContext method. Currently, it returns an instance of log.Writer, and because of this we can’t use:
facades.Log().WithContext(ctx).Channel("otel").Info()Because we should be able to pass the ctx even when we use inline channel and stacked method calling.
There was a problem hiding this comment.
Yes, good catch. We can create an issue for it.
There was a problem hiding this comment.
Created an issue for above 👍
There was a problem hiding this comment.
@hwbrzzl Can you please review it again? I have added setup to automatically register this new channel in logging.go
📑 Description
RelatedTo goravel/goravel#726
Configuration
To enable this feature, update your configuration files as follows.
1. Register the Channel
In
config/logging.go, add a new channel using thecustomdriver. This uses the newTelemetryChannelfactory to instantiate the hook. (It will be automatically added when you install telemetry package using package:install command)Usage
You can integrate the OTel channel into your existing stack or use it independently.
Option A: Add to Default Stack (Recommended)
Add
"otel"to your stack channel to broadcast logs to both your file/daily driver and OpenTelemetry.The integration supports full structured logging. Maps and slices are preserved as native OTel attributes, making them queryable in your backend.
Option B: Use On-Demand
You can manually send logs to the OTel collector using the channel selector:
Note
Currently, WithContext(ctx) doesn't work with Channel method, so we need to optimize this to work with them.
ScreenShots
✅ Checks