Skip to content

Commit

Permalink
Modify Prometheus exporter to translate non-monotonic Sums into gauges
Browse files Browse the repository at this point in the history
Add unit tests for translating monotonic and non-monotonic Sums to prometheus metrics

Update prometheus metric translation to match spec

Added a check for the aggregation temporality of a Sum.
"If the aggregation temporality is cumulative and the sum is non-monotonic, it MUST be converted to a Prometheus Gauge."

Update changelog
  • Loading branch information
brettimus authored and Brett Beutell committed May 10, 2023
1 parent 3732fd4 commit 01fc016
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 8 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

- Modify Prometheus exporter to translate non-monotonic Sums into Gauges
([#3306](https://github.com/open-telemetry/opentelemetry-python/pull/3306))
- Select histogram aggregation with an environment variable
([#3265](https://github.com/open-telemetry/opentelemetry-python/pull/3265))
- Move Protobuf encoding to its own package
Expand Down Expand Up @@ -41,7 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Version 1.16.0/0.37b0 (2023-02-17)

- Change ``__all__`` to be statically defined.
- Change `__all__` to be statically defined.
([#3143](https://github.com/open-telemetry/opentelemetry-python/pull/3143))
- Remove the ability to set a global metric prefix for Prometheus exporter
([#3137](https://github.com/open-telemetry/opentelemetry-python/pull/3137))
Expand All @@ -64,7 +66,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Create a single resource instance
([#3118](https://github.com/open-telemetry/opentelemetry-python/pull/3118))


## Version 1.15.0/0.36b0 (2022-12-09)

- PeriodicExportingMetricsReader with +Inf interval
Expand All @@ -82,7 +83,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#3027](https://github.com/open-telemetry/opentelemetry-python/pull/3027))
- Update logging to include logging api as per specification
([#3038](https://github.com/open-telemetry/opentelemetry-python/pull/3038))
- Fix: Avoid generator in metrics _ViewInstrumentMatch.collect()
- Fix: Avoid generator in metrics \_ViewInstrumentMatch.collect()
([#3035](https://github.com/open-telemetry/opentelemetry-python/pull/3035)
- [exporter-otlp-proto-grpc] add user agent string
([#3009](https://github.com/open-telemetry/opentelemetry-python/pull/3009))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,13 @@ def _translate_to_prometheus(
for pre_metric_family_id, label_values, value in zip(
pre_metric_family_ids, label_valuess, values
):
if isinstance(metric.data, Sum):
is_non_monotonic_sum = isinstance(metric.data, Sum) and metric.data.is_monotonic == False
is_cumulative = isinstance(metric.data, Sum) and metric.data.aggregation_temporality == AggregationTemporality.CUMULATIVE

# The prometheus compatibility spec for sums says: If the aggregation temporality is cumulative and the sum is non-monotonic, it MUST be converted to a Prometheus Gauge.
should_convert_sum_to_gauge = (is_non_monotonic_sum and is_cumulative)

if isinstance(metric.data, Sum) and not should_convert_sum_to_gauge:

metric_family_id = "|".join(
[pre_metric_family_id, CounterMetricFamily.__name__]
Expand All @@ -262,7 +268,7 @@ def _translate_to_prometheus(
metric_family_id_metric_family[
metric_family_id
].add_metric(labels=label_values, value=value)
elif isinstance(metric.data, Gauge):
elif isinstance(metric.data, Gauge) or should_convert_sum_to_gauge:

metric_family_id = "|".join(
[pre_metric_family_id, GaugeMetricFamily.__name__]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def test_histogram_to_prometheus(self):
),
)

def test_sum_to_prometheus(self):
def test_monotonic_sum_to_prometheus(self):
labels = {"environment@": "staging", "os": "Windows"}
metric = _generate_sum(
"test@sum",
Expand Down Expand Up @@ -163,6 +163,50 @@ def test_sum_to_prometheus(self):
prometheus_metric.samples[0].labels["os"], "Windows"
)

def test_non_monotonic_sum_to_prometheus(self):
labels = {"environment@": "staging", "os": "Windows"}
metric = _generate_sum(
"test@sum",
123,
attributes=labels,
description="testdesc",
unit="testunit",
is_monotonic=False
)

metrics_data = MetricsData(
resource_metrics=[
ResourceMetrics(
resource=Mock(),
scope_metrics=[
ScopeMetrics(
scope=Mock(),
metrics=[metric],
schema_url="schema_url",
)
],
schema_url="schema_url",
)
]
)

collector = _CustomCollector()
collector.add_metrics_data(metrics_data)

for prometheus_metric in collector.collect():
self.assertEqual(type(prometheus_metric), GaugeMetricFamily)
self.assertEqual(prometheus_metric.name, "test_sum_testunit")
self.assertEqual(prometheus_metric.documentation, "testdesc")
self.assertTrue(len(prometheus_metric.samples) == 1)
self.assertEqual(prometheus_metric.samples[0].value, 123)
self.assertTrue(len(prometheus_metric.samples[0].labels) == 2)
self.assertEqual(
prometheus_metric.samples[0].labels["environment_"], "staging"
)
self.assertEqual(
prometheus_metric.samples[0].labels["os"], "Windows"
)

def test_gauge_to_prometheus(self):
labels = {"environment@": "dev", "os": "Unix"}
metric = _generate_gauge(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def _generate_metric(


def _generate_sum(
name, value, attributes=None, description=None, unit=None
name, value, attributes=None, description=None, unit=None, is_monotonic=True
) -> Metric:
if attributes is None:
attributes = BoundedAttributes(attributes={"a": 1, "b": True})
Expand All @@ -55,7 +55,7 @@ def _generate_sum(
)
],
aggregation_temporality=AggregationTemporality.CUMULATIVE,
is_monotonic=True,
is_monotonic=is_monotonic,
),
description=description,
unit=unit,
Expand Down

0 comments on commit 01fc016

Please sign in to comment.