Skip to content

Commit

Permalink
Sort by label keys before generating labels key and value lists (#3698)
Browse files Browse the repository at this point in the history
* sort by label keys

* changelog

* test

* review

* linting

* Update contrib SHA

---------

Co-authored-by: Leighton Chen <lechen@microsoft.com>
Co-authored-by: Diego Hurtado <ocelotl@users.noreply.github.com>
  • Loading branch information
3 people committed Apr 17, 2024
1 parent 73e207b commit b51a6f8
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ env:
# Otherwise, set variable to the commit of your branch on
# opentelemetry-python-contrib which is compatible with these Core repo
# changes.
CONTRIB_REPO_SHA: 3c2788469834aa4f5976e1644d757f43d60bc219
CONTRIB_REPO_SHA: 9ce1c26d2732dfbdadbb492fc38c562dcd08ed2e
# This is needed because we do not clone the core repo in contrib builds anymore.
# When running contrib builds as part of core builds, we use actions/checkout@v2 which
# does not set an environment variable (simply just runs tox), which is different when
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#3785](https://github.com/open-telemetry/opentelemetry-python/pull/3785))
- Add capture the fully qualified type name for raised exceptions in spans
([#3837](https://github.com/open-telemetry/opentelemetry-python/pull/3837))
- Prometheus exporter sort label keys to prevent duplicate metrics when user input changes order
([#3698](https://github.com/open-telemetry/opentelemetry-python/pull/3698))

## Version 1.24.0/0.45b0 (2024-03-28)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def _translate_to_prometheus(
label_keys = []
label_values = []

for key, value in number_data_point.attributes.items():
for key, value in sorted(number_data_point.attributes.items()):
label_keys.append(self._sanitize(key))
label_values.append(self._check_value(value))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,3 +436,24 @@ def test_target_info_sanitize(self):
prometheus_metric.samples[0].labels["ratio"],
"0.1",
)

def test_label_order_does_not_matter(self):
metric_reader = PrometheusMetricReader()
provider = MeterProvider(metric_readers=[metric_reader])
meter = provider.get_meter("getting-started", "0.1.2")
counter = meter.create_counter("counter")

counter.add(1, {"cause": "cause1", "reason": "reason1"})
counter.add(1, {"reason": "reason2", "cause": "cause2"})

prometheus_output = generate_latest().decode()

# All labels are mapped correctly
self.assertIn('cause="cause1"', prometheus_output)
self.assertIn('cause="cause2"', prometheus_output)
self.assertIn('reason="reason1"', prometheus_output)
self.assertIn('reason="reason2"', prometheus_output)

# Only one metric is generated
metric_count = prometheus_output.count("# HELP counter_total")
self.assertEqual(metric_count, 1)

0 comments on commit b51a6f8

Please sign in to comment.