diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/BaggageLabelsProcessor.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/BaggageLabelsProcessor.java new file mode 100644 index 00000000000..ae297337b3a --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/BaggageLabelsProcessor.java @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.processor; + +import io.opentelemetry.api.baggage.Baggage; +import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.metrics.common.LabelsBuilder; +import io.opentelemetry.context.Context; + +/** + * A labels processor which extracts labels from {@link io.opentelemetry.api.baggage.Baggage}. + * Delegates actual extraction implementation to {@link BaggageMetricsLabelsExtractor} + */ +public final class BaggageLabelsProcessor implements LabelsProcessor { + private final BaggageMetricsLabelsExtractor baggageMetricsLabelsExtractor; + + public BaggageLabelsProcessor(BaggageMetricsLabelsExtractor baggageMetricsLabelsExtractor) { + this.baggageMetricsLabelsExtractor = baggageMetricsLabelsExtractor; + } + + @Override + public Labels onLabelsBound(Context ctx, Labels labels) { + LabelsBuilder labelsBuilder = labels.toBuilder(); + baggageMetricsLabelsExtractor.fromBaggage(Baggage.fromContext(ctx)).forEach(labelsBuilder::put); + + return labelsBuilder.build(); + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/BaggageMetricsLabelsExtractor.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/BaggageMetricsLabelsExtractor.java new file mode 100644 index 00000000000..74a4cfd74a9 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/BaggageMetricsLabelsExtractor.java @@ -0,0 +1,15 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.processor; + +import io.opentelemetry.api.baggage.Baggage; +import io.opentelemetry.api.metrics.common.Labels; + +/** Uses {@link Baggage} to extract labels for metrics. Used with {@link BaggageLabelsProcessor} */ +public interface BaggageMetricsLabelsExtractor { + + Labels fromBaggage(Baggage ctx); +} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/processor/BaggageLabelsProcessorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/processor/BaggageLabelsProcessorTest.java new file mode 100644 index 00000000000..3fbf5c0d195 --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/processor/BaggageLabelsProcessorTest.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.processor; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.metrics.common.LabelsBuilder; +import io.opentelemetry.context.Context; +import org.junit.jupiter.api.Test; + +public class BaggageLabelsProcessorTest { + + @Test + void testLabelsExtractedAndAdded() { + Labels extractedLabels = Labels.of("aa", "bb"); + BaggageMetricsLabelsExtractor extractor = ctx -> extractedLabels; + BaggageLabelsProcessor labelsProcessor = new BaggageLabelsProcessor(extractor); + Labels originalLabels = Labels.of("a", "b"); + Labels newLabels = labelsProcessor.onLabelsBound(Context.current(), originalLabels); + + LabelsBuilder mergedLabels = newLabels.toBuilder(); + extractedLabels.asMap().forEach((k, v) -> newLabels.toBuilder().put(k, v)); + assertThat(newLabels).isEqualTo(mergedLabels.build()); + } +}