Skip to content

feat: [#726][Metric] Add OpenTelemetry Tracing Support for Distributed Tracing [2]#1293

Merged
krishankumar01 merged 25 commits intomasterfrom
kkumar-gcc/#726-2
Dec 12, 2025
Merged

feat: [#726][Metric] Add OpenTelemetry Tracing Support for Distributed Tracing [2]#1293
krishankumar01 merged 25 commits intomasterfrom
kkumar-gcc/#726-2

Conversation

@krishankumar01
Copy link
Member

@krishankumar01 krishankumar01 commented Dec 10, 2025

📑 Description

RelatedTo goravel/goravel#726

Summary

Introduces Metric Telemetry support to the framework, completing the observability triad. This PR provides a flexible way to collect and export application metrics using the OpenTelemetry SDK.

Features:

  • Multiple exporters: OTLP (gRPC/HTTP), Console
  • Custom Driver Support: Allows injection of custom sdkmetric.Reader instances or factory functions
  • Aggregation Control: Configurable cumulative vs delta temporality
  • Resource Attributes: Automatic injection of service identity (name, version, environment)

Note

This PR includes full support for Custom Drivers, allowing integration with specialized backends or custom reader implementations via the via configuration key.

Usage

Configuration (config/telemetry.go)

// config/telemetry.go
"metrics": map[string]any{
    "exporter": "otlp",
    "reader": map[string]any{
        "interval": 60, // Push every 60s
        "timeout":  30,
    },
},
"exporters": map[string]any{
    "otlp": map[string]any{
        "driver":   "otlp",
        "endpoint": "http://localhost:4318",
        "metric_temporality": "cumulative", // or "delta"
    },
}

Recording Metrics

package controllers

import (
    "github.com/goravel/framework/contracts/http"
    "github.com/goravel/framework/facades"
)

func (c *UserController) Show(ctx http.Context) http.Response {
    // 1. Get the Meter
    meter := facades.Telemetry().Meter("user_module")

    // 2. Create Instrument
    counter, _ := meter.Int64Counter("user.view_count")

    // 3. Record Value
    counter.Add(ctx, 1)

    return ctx.Response().Success().Json(http.Json{"status": "recorded"})
}

Custom Driver Implementation

// config/telemetry.go
"my_custom_exporter": map[string]any{
    "driver": "custom",
    "via": func(ctx context.Context) (metric.Reader, error) {
        return my_custom_pkg.NewReader(), nil
    },
},

Shutdown

// Flushes traces, logs, and metrics gracefully
defer facades.Telemetry().Shutdown(context.Background())

Configuration Reference

Option Config Key Default Description
Exporter metrics.exporter "" (Disabled) otlp, console, custom
Interval metrics.reader.interval 60 Flush interval in seconds
Temporality exporters.{name}.metric_temporality cumulative cumulative, delta
Protocol exporters.{name}.protocol http/protobuf grpc, http/protobuf

Screenshots

Trace in JaegerUI

Screenshot 2025-12-12 at 3 18 51 PM

Metrics in Grafana (via Prometheus)

Screenshot 2025-12-12 at 3 26 11 PM

✅ Checks

  • Added test cases for my code

@krishankumar01 krishankumar01 requested a review from a team as a code owner December 10, 2025 19:15
Copilot AI review requested due to automatic review settings December 10, 2025 19:15
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: c653f2b Previous: 18d63ba Ratio
Benchmark_Fatal 0.0000023 ns/op 0 B/op 0 allocs/op 3e-7 ns/op 0 B/op 0 allocs/op 7.67
Benchmark_Fatal - ns/op 0.0000023 ns/op 3e-7 ns/op 7.67

This comment was automatically generated by workflow using github-action-benchmark.

@codecov
Copy link

codecov bot commented Dec 10, 2025

Codecov Report

❌ Patch coverage is 80.55556% with 49 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.01%. Comparing base (18d63ba) to head (c5735cb).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
telemetry/setup/stubs.go 0.00% 40 Missing ⚠️
telemetry/application.go 78.26% 3 Missing and 2 partials ⚠️
telemetry/metric.go 95.23% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1293      +/-   ##
==========================================
+ Coverage   66.93%   69.01%   +2.07%     
==========================================
  Files         275      278       +3     
  Lines       19761    16071    -3690     
==========================================
- Hits        13227    11091    -2136     
+ Misses       6062     4506    -1556     
- Partials      472      474       +2     

☔ 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 OpenTelemetry metrics support to the existing distributed tracing implementation, refactors code organization by consolidating exporter logic, and updates configuration structures to support both traces and metrics.

  • Introduces metric collection capabilities alongside existing trace functionality
  • Refactors timeout configuration from int (milliseconds) to time.Duration for better type safety
  • Consolidates trace exporter logic from separate files into trace.go

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
telemetry/metric.go Adds new metric provider implementation with OTLP and console exporters (OTLP implementation incomplete)
telemetry/trace.go Consolidates trace exporter creation logic previously in exporter.go, implements factory pattern for custom exporters
telemetry/shutdown.go Introduces shutdown utilities for graceful cleanup of telemetry providers
telemetry/config.go Adds metrics configuration structures, changes Timeout from int to time.Duration, adds custom exporter Via field
telemetry/resource.go Updates to accept full Config instead of ServiceConfig, adds support for custom resource attributes, makes service name required
telemetry/application.go Integrates both trace and meter providers, implements unified shutdown for multiple providers
telemetry/resource_test.go Enhances tests for new resource requirements including service name validation and custom attributes
telemetry/trace_test.go Moves TracerProvider tests from application_test.go, updates to reflect configuration changes
telemetry/application_test.go Updates tests to include required service name in configurations
telemetry/setup/stubs.go Updates configuration template with metrics support, separate trace/metric exporters, and new resource attributes
contracts/telemetry/telemetry.go Extends interface with Meter and MeterProvider methods for metrics support
mocks/telemetry/Telemetry.go Regenerates mocks to include new meter-related interface methods
errors/list.go Adds new error types for validation (service name, zipkin endpoint, via field requirements)
go.mod, go.sum Updates OpenTelemetry dependencies to support metrics SDK
Comments suppressed due to low confidence (2)

telemetry/trace_test.go:42

  • The Timeout field is being set to an integer value (5000) but the ExporterEntry.Timeout field is now defined as time.Duration in config.go. This will be interpreted as 5000 nanoseconds instead of the intended 5000 milliseconds. Use time.Duration with proper units, such as 5000 * time.Millisecond or 5 * time.Second.
    telemetry/trace_test.go:161
  • The Timeout field is being set to an integer value (5000) but the ExporterEntry.Timeout field is now defined as time.Duration in config.go. This will be interpreted as 5000 nanoseconds instead of the intended 5000 milliseconds. Use time.Duration with proper units, such as 5000 * time.Millisecond or 5 * time.Second.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@krishankumar01 krishankumar01 marked this pull request as draft December 10, 2025 19:23
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 17 out of 18 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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 job. Do you need a platform to test the trace and metric?

@krishankumar01
Copy link
Member Author

krishankumar01 commented Dec 12, 2025

Great job. Do you need a platform to test the trace and metric?

On my local, I’ve tested using Docker with the following:

  • Different backends for traces like Jaeger and Zipkin (with various formats such as OTLP HTTP, gRPC, and Zipkin)
  • For metrics, I’ve tested OTLP (HTTP and gRPC) and Prometheus (as a custom driver in the Goravel repo), and visualized everything in Grafana as well.

And a console driver for all.

But we can test it on a deployed application also

@hwbrzzl
Copy link
Contributor

hwbrzzl commented Dec 12, 2025

Great job. Do you need a platform to test the trace and metric?

On my local, I’ve tested using Docker with the following:

  • Different backends for traces like Jaeger and Zipkin (with various formats such as OTLP HTTP, gRPC, and Zipkin)
  • For metrics, I’ve tested OTLP (HTTP and gRPC) and Prometheus (as a custom driver in the Goravel repo), and visualized everything in Grafana as well.

And a console driver for all.

But we can test it on a deployed application also

Great, could you add some screenshots in the description?

@krishankumar01
Copy link
Member Author

Great, could you add some screenshots in the description?

@hwbrzzl I’ve resolved the comments and also added the screenshots. Could you please re-review it?

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, thanks!

@krishankumar01 krishankumar01 merged commit 8d66b1f into master Dec 12, 2025
14 checks passed
@krishankumar01 krishankumar01 deleted the kkumar-gcc/#726-2 branch December 12, 2025 10:16
hwbrzzl pushed a commit that referenced this pull request Dec 12, 2025
…d Tracing [2] (#1293)

* add metric methods to telemetry interface

* optimise trace configuration

* optimise tracer setting

* add meter provider skelton

* fix test cases

* make service name mandatory in resources

* add resource key to add additional resources

* add resource key to add additional resources

* add custom driver for metric

* add custom driver for trace

* optimise resources

* fix test cases

* optimise config stub

* remove parse headers

* remove extra space from config stub

* implement otlp metric exporter

* optimise trace custom exporter logic

* optimise metric custom exporter logic

* add test cases for metric feature

* resolve copilot comments

* add comments in stub

* remove instance_id

* optimise comments for config stub

* remove providers

* optimise test cases
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