diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java index e862877f13..b495e434bc 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java @@ -97,6 +97,10 @@ class OtlpJsonLoggingMetricExporterTest { + " \"key\": \"cat\"," + " \"value\": {\"stringValue\": \"meow\"}" + " }]," + + " \"labels\": [{" + + " \"key\": \"cat\"," + + " \"value\": \"meow\"" + + " }]," + " \"startTimeUnixNano\": \"1\"," + " \"timeUnixNano\": \"2\"," + " \"asDouble\": 4.0" @@ -120,6 +124,10 @@ class OtlpJsonLoggingMetricExporterTest { + " \"key\": \"cat\"," + " \"value\": {\"stringValue\": \"meow\"}" + " }]," + + " \"labels\": [{" + + " \"key\": \"cat\"," + + " \"value\": \"meow\"" + + " }]," + " \"startTimeUnixNano\": \"1\"," + " \"timeUnixNano\": \"2\"," + " \"asDouble\": 4.0" diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/otlp/internal/MetricAdapter.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/otlp/internal/MetricAdapter.java index a3ed717796..32c674f4cb 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/otlp/internal/MetricAdapter.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/otlp/internal/MetricAdapter.java @@ -9,6 +9,8 @@ import static io.opentelemetry.proto.metrics.v1.AggregationTemporality.AGGREGATI import static io.opentelemetry.proto.metrics.v1.AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA; import static io.opentelemetry.proto.metrics.v1.AggregationTemporality.AGGREGATION_TEMPORALITY_UNSPECIFIED; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.proto.common.v1.KeyValue; import io.opentelemetry.proto.metrics.v1.AggregationTemporality; import io.opentelemetry.proto.metrics.v1.Gauge; import io.opentelemetry.proto.metrics.v1.Histogram; @@ -39,6 +41,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; /** Converter from SDK {@link MetricData} to OTLP {@link ResourceMetrics}. */ public final class MetricAdapter { @@ -187,6 +190,8 @@ public final class MetricAdapter { return AGGREGATION_TEMPORALITY_UNSPECIFIED; } + // Fill labels too until Collector supports attributes and users have had a chance to update. + @SuppressWarnings("deprecation") static List toIntDataPoints(Collection points) { List result = new ArrayList<>(points.size()); for (LongPointData longPoint : points) { @@ -195,15 +200,14 @@ public final class MetricAdapter { .setStartTimeUnixNano(longPoint.getStartEpochNanos()) .setTimeUnixNano(longPoint.getEpochNanos()) .setAsInt(longPoint.getValue()); - longPoint - .getAttributes() - .forEach( - (key, value) -> builder.addAttributes(CommonAdapter.toProtoAttribute(key, value))); + fillAttributes(longPoint.getAttributes(), builder::addAttributes, builder::addLabels); result.add(builder.build()); } return result; } + // Fill labels too until Collector supports attributes and users have had a chance to update. + @SuppressWarnings("deprecation") static Collection toDoubleDataPoints(Collection points) { List result = new ArrayList<>(points.size()); for (DoublePointData doublePoint : points) { @@ -212,15 +216,14 @@ public final class MetricAdapter { .setStartTimeUnixNano(doublePoint.getStartEpochNanos()) .setTimeUnixNano(doublePoint.getEpochNanos()) .setAsDouble(doublePoint.getValue()); - doublePoint - .getAttributes() - .forEach( - (key, value) -> builder.addAttributes(CommonAdapter.toProtoAttribute(key, value))); + fillAttributes(doublePoint.getAttributes(), builder::addAttributes, builder::addLabels); result.add(builder.build()); } return result; } + // Fill labels too until Collector supports attributes and users have had a chance to update. + @SuppressWarnings("deprecation") static List toSummaryDataPoints(Collection points) { List result = new ArrayList<>(points.size()); for (DoubleSummaryPointData doubleSummaryPoint : points) { @@ -230,10 +233,8 @@ public final class MetricAdapter { .setTimeUnixNano(doubleSummaryPoint.getEpochNanos()) .setCount(doubleSummaryPoint.getCount()) .setSum(doubleSummaryPoint.getSum()); - doubleSummaryPoint - .getAttributes() - .forEach( - (key, value) -> builder.addAttributes(CommonAdapter.toProtoAttribute(key, value))); + fillAttributes( + doubleSummaryPoint.getAttributes(), builder::addAttributes, builder::addLabels); // Not calling directly addAllQuantileValues because that generates couple of unnecessary // allocations if empty list. if (!doubleSummaryPoint.getPercentileValues().isEmpty()) { @@ -250,6 +251,8 @@ public final class MetricAdapter { return result; } + // Fill labels too until Collector supports attributes and users have had a chance to update. + @SuppressWarnings("deprecation") static Collection toHistogramDataPoints( Collection points) { List result = new ArrayList<>(points.size()); @@ -265,14 +268,29 @@ public final class MetricAdapter { if (!boundaries.isEmpty()) { builder.addAllExplicitBounds(boundaries); } - doubleHistogramPoint - .getAttributes() - .forEach( - (key, value) -> builder.addAttributes(CommonAdapter.toProtoAttribute(key, value))); + fillAttributes( + doubleHistogramPoint.getAttributes(), builder::addAttributes, builder::addLabels); result.add(builder.build()); } return result; } + // Fill labels too until Collector supports attributes and users have had a chance to update. + @SuppressWarnings("deprecation") + private static void fillAttributes( + Attributes attributes, + Consumer attributeSetter, + Consumer labelSetter) { + attributes.forEach( + (key, value) -> { + attributeSetter.accept(CommonAdapter.toProtoAttribute(key, value)); + labelSetter.accept( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey(key.getKey()) + .setValue(value.toString()) + .build()); + }); + } + private MetricAdapter() {} } diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/otlp/internal/MetricAdapterTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/otlp/internal/MetricAdapterTest.java index cc29b32f6b..5c9388bb19 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/otlp/internal/MetricAdapterTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/otlp/internal/MetricAdapterTest.java @@ -44,6 +44,8 @@ import io.opentelemetry.sdk.resources.Resource; import java.util.Collections; import org.junit.jupiter.api.Test; +// Fill deprecated APIs before removing them after users get a chance to migrate. +@SuppressWarnings("deprecation") class MetricAdapterTest { private static final Attributes KV_ATTR = Attributes.of(stringKey("k"), "v"); @@ -65,6 +67,11 @@ class MetricAdapterTest { .addAllAttributes( singletonList( KeyValue.newBuilder().setKey("k").setValue(stringValue("v")).build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsInt(5) .build()); assertThat( @@ -84,6 +91,11 @@ class MetricAdapterTest { .addAllAttributes( singletonList( KeyValue.newBuilder().setKey("k").setValue(stringValue("v")).build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsInt(7) .build()); } @@ -101,6 +113,11 @@ class MetricAdapterTest { .addAllAttributes( singletonList( KeyValue.newBuilder().setKey("k").setValue(stringValue("v")).build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsDouble(5.1) .build()); assertThat( @@ -120,6 +137,11 @@ class MetricAdapterTest { .addAllAttributes( singletonList( KeyValue.newBuilder().setKey("k").setValue(stringValue("v")).build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsDouble(7.1) .build()); } @@ -143,6 +165,11 @@ class MetricAdapterTest { .addAllAttributes( singletonList( KeyValue.newBuilder().setKey("k").setValue(stringValue("v")).build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setCount(5) .setSum(14.2) .addQuantileValues( @@ -178,6 +205,11 @@ class MetricAdapterTest { .addAllAttributes( singletonList( KeyValue.newBuilder().setKey("k").setValue(stringValue("v")).build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setCount(9) .setSum(18.3) .addQuantileValues( @@ -214,6 +246,11 @@ class MetricAdapterTest { .addAllAttributes( singletonList( KeyValue.newBuilder().setKey("k").setValue(stringValue("v")).build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setCount(6) .setSum(14.2) .addBucketCounts(1) @@ -262,6 +299,11 @@ class MetricAdapterTest { .setKey("k") .setValue(stringValue("v")) .build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsInt(5) .build()) .build()) @@ -297,6 +339,11 @@ class MetricAdapterTest { .setKey("k") .setValue(stringValue("v")) .build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsDouble(5.1) .build()) .build()) @@ -336,6 +383,11 @@ class MetricAdapterTest { .setKey("k") .setValue(stringValue("v")) .build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsInt(5) .build()) .build()) @@ -371,6 +423,11 @@ class MetricAdapterTest { .setKey("k") .setValue(stringValue("v")) .build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsDouble(5.1) .build()) .build()) @@ -406,6 +463,11 @@ class MetricAdapterTest { .setKey("k") .setValue(stringValue("v")) .build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsInt(5) .build()) .build()) @@ -437,6 +499,11 @@ class MetricAdapterTest { .setKey("k") .setValue(stringValue("v")) .build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsDouble(5.1) .build()) .build()) @@ -481,6 +548,11 @@ class MetricAdapterTest { .setKey("k") .setValue(stringValue("v")) .build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setCount(5) .setSum(33d) .addQuantileValues( @@ -536,6 +608,11 @@ class MetricAdapterTest { .setKey("k") .setValue(stringValue("v")) .build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setCount(33) .setSum(4.0) .addBucketCounts(33) @@ -581,6 +658,11 @@ class MetricAdapterTest { .setKey("k") .setValue(stringValue("v")) .build())) + .addLabels( + io.opentelemetry.proto.common.v1.StringKeyValue.newBuilder() + .setKey("k") + .setValue("v") + .build()) .setAsDouble(5.0) .build()) .build())