Skip to content

feat: [#726][Log] add distributed logging and auto-instrumentation using OpenTelemetry [3]#1295

Merged
krishankumar01 merged 17 commits intomasterfrom
kkumar-gcc/#726-4
Dec 17, 2025
Merged

feat: [#726][Log] add distributed logging and auto-instrumentation using OpenTelemetry [3]#1295
krishankumar01 merged 17 commits intomasterfrom
kkumar-gcc/#726-4

Conversation

@krishankumar01
Copy link
Member

@krishankumar01 krishankumar01 commented Dec 12, 2025

📑 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 the custom driver. This uses the new TelemetryChannel factory to instantiate the hook. (It will be automatically added when you install telemetry package using package:install command)

// config/logging.go
import (
    telemetrylog "github.com/goravel/framework/telemetry/instrumentation/log"
)

// ... inside "channels" map ...
"otel": map[string]any{
    "driver": "custom",
    "via":    telemetrylog.NewTelemetryChannel(),
},

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.

"stack": map[string]any{
    "driver":   "stack",
    "channels": []string{"daily", "otel"},
},

The integration supports full structured logging. Maps and slices are preserved as native OTel attributes, making them queryable in your backend.

facades.Log().With(map[string]any{
    "tags": []string{"payment", "v1"},
    "meta": map[string]any{
        "ip": "127.0.0.1",
        "geo": "US",
    },
}).Info("Payment Processed")

Option B: Use On-Demand

You can manually send logs to the OTel collector using the channel selector:

// TraceID is automatically injected if present in ctx
facades.Log().Channel("otel").Info("Payment processed")

Note

Currently, WithContext(ctx) doesn't work with Channel method, so we need to optimize this to work with them.

ScreenShots

Screenshot 2025-12-12 at 6 38 42 PM Screenshot 2025-12-12 at 6 40 30 PM

✅ Checks

  • Added test cases for my code

Copilot AI review requested due to automatic review settings December 12, 2025 10:55
@krishankumar01 krishankumar01 requested a review from a team as a code owner December 12, 2025 10:55
@krishankumar01 krishankumar01 marked this pull request as draft December 12, 2025 10:56
@codecov
Copy link

codecov bot commented Dec 12, 2025

Codecov Report

❌ Patch coverage is 71.02804% with 93 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.24%. Comparing base (ae61a85) to head (26682c7).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
telemetry/instrumentation/log/mapper.go 71.01% 38 Missing and 2 partials ⚠️
telemetry/setup/setup.go 0.00% 30 Missing ⚠️
telemetry/instrumentation/log/hook.go 80.76% 5 Missing and 5 partials ⚠️
log/logrus_writer.go 0.00% 6 Missing ⚠️
telemetry/application.go 55.55% 3 Missing and 1 partial ⚠️
telemetry/service_provider.go 0.00% 3 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI left a 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 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 NewLoggerProvider with support for OTLP (HTTP/gRPC), console, and custom log exporters
  • Adds LogsConfig and LogsProcessorConfig to the telemetry configuration structure
  • Integrates the logger provider into the telemetry Application with 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.

Copy link
Contributor

Copilot AI left a 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 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.

@krishankumar01 krishankumar01 marked this pull request as ready for review December 14, 2025 20:50
Copy link

@github-actions github-actions bot left a 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: 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.

@krishankumar01 krishankumar01 changed the title feat: [#726][Log] Add OpenTelemetry Tracing Support for Distributed Tracing [3] feat: [#726][Log] add distributed logging and auto-instrumentation using OpenTelemetry [3] Dec 15, 2025
Copy link
Contributor

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

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

Awesome, only left a question.

Copy link
Contributor

Choose a reason for hiding this comment

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

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",
	...
},

Copy link
Member Author

@krishankumar01 krishankumar01 Dec 15, 2025

Choose a reason for hiding this comment

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

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.
Screenshot 2025-12-15 at 1 38 17 PM

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

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(),
},

Copy link
Member Author

Choose a reason for hiding this comment

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

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Member Author

@krishankumar01 krishankumar01 Dec 15, 2025

Choose a reason for hiding this comment

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

@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.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, good catch. We can create an issue for it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Created an issue for above 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

@hwbrzzl Can you please review it again? I have added setup to automatically register this new channel in logging.go

Copy link
Contributor

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

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

Great, LGTM.

@krishankumar01 krishankumar01 merged commit eb83c9f into master Dec 17, 2025
14 checks passed
@krishankumar01 krishankumar01 deleted the kkumar-gcc/#726-4 branch December 17, 2025 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants