diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bd0a53c3c..c73d00e596 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- `opentelemetry-exporter-prometheus`: Add `preferred_aggregation` parameter to `PrometheusMetricReader` to allow configuring default aggregation per instrument kind + ([#5117](https://github.com/open-telemetry/opentelemetry-python/pull/5117)) - Fix incorrect code example in `create_tracer()` docstring ([#5072](https://github.com/open-telemetry/opentelemetry-python/issues/5072)) - `opentelemetry-sdk`: add `load_entry_point` shared utility to declarative file configuration for loading plugins via entry points; refactor propagator loading to use it diff --git a/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py b/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py index 608d8f6d30..47b16c70ed 100644 --- a/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py +++ b/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py @@ -105,6 +105,9 @@ MetricsData, Sum, ) +from opentelemetry.sdk.metrics.view import ( + Aggregation, +) from opentelemetry.semconv._incubating.attributes.otel_attributes import ( OtelComponentTypeValues, ) @@ -135,7 +138,10 @@ class PrometheusMetricReader(MetricReader): """Prometheus metric exporter for OpenTelemetry.""" def __init__( - self, disable_target_info: bool = False, prefix: str = "" + self, + disable_target_info: bool = False, + prefix: str = "", + preferred_aggregation: dict[type, Aggregation] | None = None, ) -> None: super().__init__( preferred_temporality={ @@ -146,6 +152,7 @@ def __init__( ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, ObservableGauge: AggregationTemporality.CUMULATIVE, }, + preferred_aggregation=preferred_aggregation, otel_component_type=OtelComponentTypeValues.PROMETHEUS_HTTP_TEXT_METRIC_EXPORTER, ) self._collector = _CustomCollector( diff --git a/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py b/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py index 26770c9e1f..4a67555cac 100644 --- a/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py +++ b/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py @@ -28,6 +28,7 @@ _CustomCollector, ) from opentelemetry.metrics import NoOpMeterProvider +from opentelemetry.sdk.metrics import Histogram as HistogramInstrument from opentelemetry.sdk.metrics import MeterProvider from opentelemetry.sdk.metrics.export import ( AggregationTemporality, @@ -38,6 +39,7 @@ ResourceMetrics, ScopeMetrics, ) +from opentelemetry.sdk.metrics.view import ExplicitBucketHistogramAggregation from opentelemetry.sdk.resources import Resource from opentelemetry.test.metrictestutil import ( _generate_gauge, @@ -719,3 +721,21 @@ def test_multiple_data_points_with_different_label_sets(self): """ ), ) + + def test_preferred_aggregation(self): + """Test that preferred_aggregation parameter is passed to MetricReader.""" + custom_aggregation = { + HistogramInstrument: ExplicitBucketHistogramAggregation( + boundaries=[1.0, 5.0, 10.0] + ) + } + reader = PrometheusMetricReader( + preferred_aggregation=custom_aggregation + ) + provider = MeterProvider(metric_readers=[reader]) + meter = provider.get_meter("test") + histogram = meter.create_histogram("test_histogram") + histogram.record(5) + result = list(reader._collector.collect()) + self.assertTrue(len(result) > 0) + reader.shutdown()