From 9bfb59894c715fa5dd554b59af12fca5380db170 Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Wed, 6 Aug 2025 08:25:17 -0400 Subject: [PATCH] Make telemetry group ordering deterministic --- docs/instrumentation-list.yaml | 8 +-- .../docs/utils/YamlHelper.java | 3 +- .../docs/utils/YamlHelperTest.java | 65 +++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/docs/instrumentation-list.yaml b/docs/instrumentation-list.yaml index 40a5d44c4289..93f3892ce60c 100644 --- a/docs/instrumentation-list.yaml +++ b/docs/instrumentation-list.yaml @@ -4776,12 +4776,10 @@ libraries: type: boolean default: false telemetry: - - when: otel.instrumentation.kafka.experimental-span-attributes=true + - when: default spans: - span_kind: CONSUMER attributes: - - name: kafka.record.queue_time_ms - type: LONG - name: messaging.batch.message_count type: LONG - name: messaging.client_id @@ -4802,10 +4800,12 @@ libraries: type: STRING - name: messaging.system type: STRING - - when: default + - when: otel.instrumentation.kafka.experimental-span-attributes=true spans: - span_kind: CONSUMER attributes: + - name: kafka.record.queue_time_ms + type: LONG - name: messaging.batch.message_count type: LONG - name: messaging.client_id diff --git a/instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/utils/YamlHelper.java b/instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/utils/YamlHelper.java index e111e6f2b3d5..98ed802d6047 100644 --- a/instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/utils/YamlHelper.java +++ b/instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/utils/YamlHelper.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.TreeSet; import java.util.logging.Logger; import java.util.stream.Collectors; import org.yaml.snakeyaml.DumperOptions; @@ -143,7 +144,7 @@ private static Map baseProperties(InstrumentationModule module) addConfigurations(module, moduleMap); // Get telemetry grouping lists - Set telemetryGroups = new java.util.HashSet<>(module.getMetrics().keySet()); + Set telemetryGroups = new TreeSet<>(module.getMetrics().keySet()); telemetryGroups.addAll(module.getSpans().keySet()); if (!telemetryGroups.isEmpty()) { diff --git a/instrumentation-docs/src/test/java/io/opentelemetry/instrumentation/docs/utils/YamlHelperTest.java b/instrumentation-docs/src/test/java/io/opentelemetry/instrumentation/docs/utils/YamlHelperTest.java index 384a7725b69e..be63541917f9 100644 --- a/instrumentation-docs/src/test/java/io/opentelemetry/instrumentation/docs/utils/YamlHelperTest.java +++ b/instrumentation-docs/src/test/java/io/opentelemetry/instrumentation/docs/utils/YamlHelperTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.docs.utils; +import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import com.fasterxml.jackson.core.JsonProcessingException; @@ -22,6 +23,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -420,4 +422,67 @@ void testSpanParsing() throws Exception { assertThat(expectedYaml).isEqualTo(stringWriter.toString()); } + + @Test + void testTelemetryGroupsAreSorted() throws Exception { + EmittedMetrics.Metric metric = + new EmittedMetrics.Metric("a.metric", "description", "COUNTER", "1", emptyList()); + EmittedSpans.Span span = new EmittedSpans.Span("SERVER", emptyList()); + + // First ordering + Map> metrics1 = new LinkedHashMap<>(); + metrics1.put("z-group", List.of(metric)); + metrics1.put("a-group", List.of(metric)); + + Map> spans1 = new LinkedHashMap<>(); + spans1.put("c-group", List.of(span)); + spans1.put("f-group", List.of(span)); + spans1.put("b-group", List.of(span)); + + List modules1 = new ArrayList<>(); + modules1.add( + new InstrumentationModule.Builder() + .srcPath("instrumentation/test/test-1.0") + .instrumentationName("test-1.0") + .namespace("test") + .group("test") + .metrics(metrics1) + .spans(spans1) + .build()); + + StringWriter stringWriter1 = new StringWriter(); + BufferedWriter writer1 = new BufferedWriter(stringWriter1); + YamlHelper.generateInstrumentationYaml(modules1, writer1); + writer1.flush(); + String yaml1 = stringWriter1.toString(); + + // Different ordering + Map> metrics2 = new LinkedHashMap<>(); + metrics2.put("a-group", List.of(metric)); + metrics2.put("z-group", List.of(metric)); + + Map> spans2 = new LinkedHashMap<>(); + spans2.put("f-group", List.of(span)); + spans2.put("b-group", List.of(span)); + spans2.put("c-group", List.of(span)); + + List modules2 = new ArrayList<>(); + modules2.add( + new InstrumentationModule.Builder() + .srcPath("instrumentation/test/test-1.0") + .instrumentationName("test-1.0") + .namespace("test") + .group("test") + .metrics(metrics2) + .spans(spans2) + .build()); + + StringWriter stringWriter2 = new StringWriter(); + BufferedWriter writer2 = new BufferedWriter(stringWriter2); + YamlHelper.generateInstrumentationYaml(modules2, writer2); + writer2.flush(); + String yaml2 = stringWriter2.toString(); + + assertThat(yaml1).isEqualTo(yaml2); + } }