Skip to content

6195: Creation of DelegatingMetricData class#7159

Closed
vasantteja wants to merge 10 commits intoopen-telemetry:mainfrom
vasantteja:teja/delegating-metric-data
Closed

6195: Creation of DelegatingMetricData class#7159
vasantteja wants to merge 10 commits intoopen-telemetry:mainfrom
vasantteja:teja/delegating-metric-data

Conversation

@vasantteja
Copy link
Contributor

This Change

Context

This PR tries to solve this ticket. I preserved the original PR that was initially raised to add this class but I added a couple other enhancements that were mentioned in the PR. @jack-berg proposed two approaches for exposing other PointData interfaces:

  1. Creating Delegating Classes
  2. Adding Static Create Methods to Interfaces

I went with the second approach because it keeps the API simpler, consistent and avoids code duplication..

Implementation Example

Finally I am thinking people might be using this class with Metric Exporter as below:

import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.metrics.data.Data;
import io.opentelemetry.sdk.metrics.data.DelegatingMetricData;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.data.MetricDataType;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import io.opentelemetry.sdk.resources.Resource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Function;

/**
 * A MetricExporter that transforms metrics using a custom DelegatingMetricData implementation
 * before exporting them through a delegate exporter.
 */
public class TransformingMetricExporter implements MetricExporter {
    private final MetricExporter delegate;
    private final Function<MetricData, MetricData> transformer;

    /**
     * Creates a new TransformingMetricExporter.
     *
     * @param delegate The underlying exporter to send metrics to
     * @param namePrefix Prefix to add to all metric names
     * @param scaleFactor Factor to multiply all numeric values by (if applicable)
     */
    public TransformingMetricExporter(MetricExporter delegate, String namePrefix, double scaleFactor) {
        this.delegate = delegate;
        this.transformer = metric -> new CustomMetricData(metric, namePrefix, scaleFactor);
    }

    @Override
    public CompletableResultCode export(Collection<MetricData> metrics) {
        // Transform each metric before delegating to the wrapped exporter
        Collection<MetricData> transformedMetrics = new ArrayList<>(metrics.size());
        for (MetricData metric : metrics) {
            transformedMetrics.add(transformer.apply(metric));
        }
        return delegate.export(transformedMetrics);
    }

    @Override
    public CompletableResultCode flush() {
        return delegate.flush();
    }

    @Override
    public CompletableResultCode shutdown() {
        return delegate.shutdown();
    }

    /**
     * Custom implementation of DelegatingMetricData that modifies metric names and scales values.
     */
    private static class CustomMetricData extends DelegatingMetricData {
        private final String name;
        private final double scaleFactor;

        CustomMetricData(MetricData delegate, String namePrefix, double scaleFactor) {
            super(delegate);
            this.name = namePrefix + delegate.getName();
            this.scaleFactor = scaleFactor;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public Data<?> getData() {
            // Here you could implement value scaling logic based on the metric type
            // For example, you could create custom scaled versions of:
            // - LongSumData/DoubleSumData values
            // - HistogramData/ExponentialHistogramData values
            // - etc.
            
            return super.getData();
        }
        
        @Override
        public String toString() {
            return "CustomMetricData{name='" + name + "', scaled by " + scaleFactor + 
                   ", delegate=" + super.toString() + "}";
        }
    }
}

@vasantteja vasantteja requested a review from a team as a code owner February 28, 2025 02:16
@codecov
Copy link

codecov bot commented Feb 28, 2025

Codecov Report

Attention: Patch coverage is 73.61111% with 19 lines in your changes missing coverage. Please review.

Project coverage is 89.81%. Comparing base (3796992) to head (97a8cec).
Report is 37 commits behind head on main.

Files with missing lines Patch % Lines
...lemetry/sdk/metrics/data/DelegatingMetricData.java 95.65% 0 Missing and 2 partials ⚠️
...pentelemetry/sdk/metrics/data/DoublePointData.java 0.00% 2 Missing ⚠️
...telemetry/sdk/metrics/data/HistogramPointData.java 0.00% 2 Missing ⚠️
.../opentelemetry/sdk/metrics/data/LongPointData.java 0.00% 2 Missing ⚠️
...telemetry/sdk/metrics/data/DoubleExemplarData.java 0.00% 1 Missing ⚠️
.../sdk/metrics/data/ExponentialHistogramBuckets.java 0.00% 1 Missing ⚠️
...try/sdk/metrics/data/ExponentialHistogramData.java 0.00% 1 Missing ⚠️
...dk/metrics/data/ExponentialHistogramPointData.java 0.00% 1 Missing ⚠️
...a/io/opentelemetry/sdk/metrics/data/GaugeData.java 0.00% 1 Missing ⚠️
.../opentelemetry/sdk/metrics/data/HistogramData.java 0.00% 1 Missing ⚠️
... and 5 more
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #7159      +/-   ##
============================================
- Coverage     89.85%   89.81%   -0.05%     
- Complexity     6613     6643      +30     
============================================
  Files           740      756      +16     
  Lines         19991    20079      +88     
  Branches       1966     1976      +10     
============================================
+ Hits          17963    18033      +70     
- Misses         1439     1455      +16     
- Partials        589      591       +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.

@vasantteja vasantteja marked this pull request as draft March 10, 2025 15:44
@vasantteja vasantteja closed this Mar 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant