Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))
- `opentelemetry-api`: Enforce W3C Baggage size limits on outbound propagation in `W3CBaggagePropagator.inject()`. Previously only inbound extraction enforced limits; now inject also caps entries at 180, individual pairs at 4096 bytes, and total header at 8192 bytes per the W3C Baggage spec. The extract path max_pairs limit now counts all size-valid entries rather than only successfully parsed ones.
([#5163](https://github.com/open-telemetry/opentelemetry-python/pull/5163))
- `opentelemetry-sdk`: add `additional_properties` support to generated config models via custom `datamodel-codegen` template, enabling plugin/custom component names to flow through typed dataclasses
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@
MetricsData,
Sum,
)
from opentelemetry.sdk.metrics.view import (
Aggregation,
)
from opentelemetry.semconv._incubating.attributes.otel_attributes import (
OtelComponentTypeValues,
)
Expand Down Expand Up @@ -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={
Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -47,6 +49,7 @@
)


# pylint: disable=too-many-public-methods
class TestPrometheusMetricReader(TestCase):
def setUp(self):
self._mock_registry_register = Mock()
Expand Down Expand Up @@ -719,3 +722,30 @@ 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)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we do some additional verification here to actually verify that the boundaries specified above are respected?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done! Added verification to check that the custom boundaries [1.0, 5.0, 10.0] are present in the Prometheus output. Thanks for the suggestion.

prometheus_metric = result[1]
bucket_bounds = [
sample.labels["le"]
for sample in prometheus_metric.samples
if "le" in sample.labels
]
self.assertIn("1.0", bucket_bounds)
self.assertIn("5.0", bucket_bounds)
self.assertIn("10.0", bucket_bounds)
reader.shutdown()
Loading