From 8f3c25ed8cc4ebf69eb9b066cfd94da9b9d06eb5 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Thu, 11 Sep 2025 14:55:37 -0700 Subject: [PATCH 1/9] add the dual emit flag to otel metrics --- .../autoconfigure/AzureMonitorExporterBuilder.java | 2 +- .../implementation/MetricDataMapper.java | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java index 2218794d2e2a..5f721156fe64 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java @@ -121,7 +121,7 @@ LogRecordExporter buildLogRecordExporter() { MetricExporter buildMetricExporter() { HeartbeatExporter.start(MINUTES.toSeconds(15), createDefaultsPopulator(), builtTelemetryItemExporter::send); - return new AzureMonitorMetricExporter(new MetricDataMapper(createDefaultsPopulator(), true), + return new AzureMonitorMetricExporter(new MetricDataMapper(createDefaultsPopulator(), true, false), builtTelemetryItemExporter); } diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java index 3773e88b8bdf..f8984824d84e 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java @@ -46,17 +46,20 @@ public class MetricDataMapper { - private static final ClientLogger logger = new ClientLogger(MetricDataMapper.class); + private static final ClientLogger logger = new ClientLogger(MetricDataMapper.class); private static final Set OTEL_UNSTABLE_METRICS_TO_EXCLUDE = new HashSet<>(); private static final String OTEL_INSTRUMENTATION_NAME_PREFIX = "io.opentelemetry"; private static final Set OTEL_PRE_AGGREGATED_STANDARD_METRIC_NAMES = new HashSet<>(4); public static final AttributeKey APPLICATIONINSIGHTS_INTERNAL_METRIC_NAME = AttributeKey.stringKey("applicationinsights.internal.metric_name"); + public static final String MS_SENT_TO_AMW = "_MS.SentToAMW"; private final BiConsumer telemetryInitializer; private final boolean captureHttpServer4xxAsError; + private final boolean otlpExporterEnabledForAKS; + static { // HTTP unstable metrics to be excluded via Otel auto instrumentation OTEL_UNSTABLE_METRICS_TO_EXCLUDE.add("rpc.client.duration"); @@ -70,9 +73,10 @@ public class MetricDataMapper { } public MetricDataMapper(BiConsumer telemetryInitializer, - boolean captureHttpServer4xxAsError) { + boolean captureHttpServer4xxAsError, boolean otlpExporterEnabledForAKS) { this.telemetryInitializer = telemetryInitializer; this.captureHttpServer4xxAsError = captureHttpServer4xxAsError; + this.otlpExporterEnabledForAKS = otlpExporterEnabledForAKS; } public void map(MetricData metricData, Consumer consumer) { @@ -176,6 +180,9 @@ public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemet } metricTelemetryBuilder.setMetricPoint(pointBuilder); + if (otlpExporterEnabledForAKS) { + metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW, Boolean.toString(otlpExporterEnabledForAKS)); + } Attributes attributes = pointData.getAttributes(); if (isPreAggregatedStandardMetric) { From b3c69c2acbad3c4e99eaba01f3afe756c529e90a Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Thu, 11 Sep 2025 16:52:11 -0700 Subject: [PATCH 2/9] add enable env var --- .../implementation/MetricDataMapper.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java index f8984824d84e..6012f814b081 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java @@ -59,6 +59,7 @@ public class MetricDataMapper { private final boolean captureHttpServer4xxAsError; private final boolean otlpExporterEnabledForAKS; + private final boolean metricsToLAEnabled; static { // HTTP unstable metrics to be excluded via Otel auto instrumentation @@ -77,6 +78,9 @@ public MetricDataMapper(BiConsumer telemetry this.telemetryInitializer = telemetryInitializer; this.captureHttpServer4xxAsError = captureHttpServer4xxAsError; this.otlpExporterEnabledForAKS = otlpExporterEnabledForAKS; + + String metricsToLAEnvVar = System.getenv("APPLICATIONINSIGHTS_METRICS_TO_LOGANALYTICS_ENABLED"); + this.metricsToLAEnabled = metricsToLAEnvVar == null || "true".equalsIgnoreCase(metricsToLAEnvVar); } public void map(MetricData metricData, Consumer consumer) { @@ -84,7 +88,7 @@ public void map(MetricData metricData, Consumer consumer) { if (type == DOUBLE_SUM || type == DOUBLE_GAUGE || type == LONG_SUM || type == LONG_GAUGE || type == HISTOGRAM) { boolean isPreAggregatedStandardMetric = OTEL_PRE_AGGREGATED_STANDARD_METRIC_NAMES.contains(metricData.getName()); - if (isPreAggregatedStandardMetric) { + if (isPreAggregatedStandardMetric) { // we want standard metrics to always be sent to Breeze List preAggregatedStandardMetrics = convertOtelMetricToAzureMonitorMetric(metricData, true); preAggregatedStandardMetrics.forEach(consumer::accept); @@ -96,8 +100,11 @@ public void map(MetricData metricData, Consumer consumer) { && metricData.getInstrumentationScopeInfo().getName().startsWith(OTEL_INSTRUMENTATION_NAME_PREFIX)) { return; } - List stableOtelMetrics = convertOtelMetricToAzureMonitorMetric(metricData, false); - stableOtelMetrics.forEach(consumer::accept); + + if (metricsToLAEnabled && !isPreAggregatedStandardMetric) { + List stableOtelMetrics = convertOtelMetricToAzureMonitorMetric(metricData, false); + stableOtelMetrics.forEach(consumer::accept); + } } else { logger.warning("metric data type {} is not supported yet.", metricData.getType()); } From b26b482c01eea484df70784c3c01d08159efdb10 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Fri, 12 Sep 2025 14:39:51 -0700 Subject: [PATCH 3/9] fixing compiler issues --- .../AzureMonitorExporterBuilder.java | 2 +- .../implementation/MetricDataMapper.java | 23 ++++++++++--------- .../AzureMonitorMetricExporterTest.java | 20 ++++++++-------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java index 5f721156fe64..5d352e471a1a 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java @@ -121,7 +121,7 @@ LogRecordExporter buildLogRecordExporter() { MetricExporter buildMetricExporter() { HeartbeatExporter.start(MINUTES.toSeconds(15), createDefaultsPopulator(), builtTelemetryItemExporter::send); - return new AzureMonitorMetricExporter(new MetricDataMapper(createDefaultsPopulator(), true, false), + return new AzureMonitorMetricExporter(new MetricDataMapper(createDefaultsPopulator(), true, false, true), builtTelemetryItemExporter); } diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java index 6012f814b081..e6c421231370 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java @@ -46,7 +46,7 @@ public class MetricDataMapper { - private static final ClientLogger logger = new ClientLogger(MetricDataMapper.class); + private static final ClientLogger logger = new ClientLogger(MetricDataMapper.class); private static final Set OTEL_UNSTABLE_METRICS_TO_EXCLUDE = new HashSet<>(); private static final String OTEL_INSTRUMENTATION_NAME_PREFIX = "io.opentelemetry"; @@ -58,8 +58,8 @@ public class MetricDataMapper { private final BiConsumer telemetryInitializer; private final boolean captureHttpServer4xxAsError; - private final boolean otlpExporterEnabledForAKS; - private final boolean metricsToLAEnabled; + private boolean otlpExporterEnabledForAKS; + private boolean metricsToLAEnabled; static { // HTTP unstable metrics to be excluded via Otel auto instrumentation @@ -74,16 +74,15 @@ public class MetricDataMapper { } public MetricDataMapper(BiConsumer telemetryInitializer, - boolean captureHttpServer4xxAsError, boolean otlpExporterEnabledForAKS) { + boolean captureHttpServer4xxAsError, boolean otlpExporterEnabledForAKS, boolean metricsToLAEnabled) { this.telemetryInitializer = telemetryInitializer; this.captureHttpServer4xxAsError = captureHttpServer4xxAsError; this.otlpExporterEnabledForAKS = otlpExporterEnabledForAKS; - - String metricsToLAEnvVar = System.getenv("APPLICATIONINSIGHTS_METRICS_TO_LOGANALYTICS_ENABLED"); - this.metricsToLAEnabled = metricsToLAEnvVar == null || "true".equalsIgnoreCase(metricsToLAEnvVar); + this.metricsToLAEnabled = metricsToLAEnabled; } public void map(MetricData metricData, Consumer consumer) { + logger.verbose("Mapping metric data: {}", metricData.getName()); MetricDataType type = metricData.getType(); if (type == DOUBLE_SUM || type == DOUBLE_GAUGE || type == LONG_SUM || type == LONG_GAUGE || type == HISTOGRAM) { boolean isPreAggregatedStandardMetric @@ -102,6 +101,7 @@ public void map(MetricData metricData, Consumer consumer) { } if (metricsToLAEnabled && !isPreAggregatedStandardMetric) { + logger.verbose("Mapping stable metric to Breeze: {}", metricData.getName()); List stableOtelMetrics = convertOtelMetricToAzureMonitorMetric(metricData, false); stableOtelMetrics.forEach(consumer::accept); } @@ -120,7 +120,7 @@ private List convertOtelMetricToAzureMonitorMetric(MetricData met builder.setTime(FormattedTime.offSetDateTimeFromEpochNanos(pointData.getEpochNanos())); updateMetricPointBuilder(builder, metricData, pointData, captureHttpServer4xxAsError, - isPreAggregatedStandardMetric); + isPreAggregatedStandardMetric, this.otlpExporterEnabledForAKS); telemetryItems.add(builder.build()); } @@ -129,7 +129,8 @@ private List convertOtelMetricToAzureMonitorMetric(MetricData met // visible for testing public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemetryBuilder, MetricData metricData, - PointData pointData, boolean captureHttpServer4xxAsError, boolean isPreAggregatedStandardMetric) { + PointData pointData, boolean captureHttpServer4xxAsError, boolean isPreAggregatedStandardMetric, + boolean otlpExporterEnabled) { checkArgument(metricData != null, "MetricData cannot be null."); MetricPointBuilder pointBuilder = new MetricPointBuilder(); @@ -187,8 +188,8 @@ public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemet } metricTelemetryBuilder.setMetricPoint(pointBuilder); - if (otlpExporterEnabledForAKS) { - metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW, Boolean.toString(otlpExporterEnabledForAKS)); + if (otlpExporterEnabled) { + metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW, Boolean.toString(otlpExporterEnabled)); } Attributes attributes = pointData.getAttributes(); diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java index 1081cc7dd118..7dbbb69ddb03 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java @@ -59,7 +59,7 @@ public void testDoubleCounter() { MetricData metricData = metricDataList.get(0); for (PointData pointData : metricData.getData().getPoints()) { MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricDataList.get(0), pointData, true, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricDataList.get(0), pointData, true, false, false); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(3.1415); @@ -90,7 +90,7 @@ public void testDoubleGauge() { MetricData metricData = metricDataList.get(0); for (PointData pointData : metricData.getData().getPoints()) { MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, false); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(20.0); @@ -123,7 +123,7 @@ public void testAttributesOnCustomMetric() { MetricData metric = metricDatas.get(0); PointData pointData = metric.getData().getPoints().stream().findFirst().get(); MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, false); + MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, false, false); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); @@ -157,7 +157,7 @@ public void testAttributesOnStandardMetric() { MetricData metric = metricDatas.get(0); PointData pointData = metric.getData().getPoints().stream().findFirst().get(); MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, true); + MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, true, false); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); @@ -220,7 +220,7 @@ public void testLongCounter() { assertThat(longPointData3.getAttributes().get(AttributeKey.stringKey("color"))).isEqualTo("yellow"); MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData1, true, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData1, true, false, false); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); MetricDataPoint metricDataPoint = metricsData.getMetrics().get(0); @@ -232,7 +232,7 @@ public void testLongCounter() { assertThat(properties).containsEntry("color", "green"); builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData2, true, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData2, true, false, false); metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); metricDataPoint = metricsData.getMetrics().get(0); @@ -244,7 +244,7 @@ public void testLongCounter() { assertThat(properties).containsEntry("color", "red"); builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData3, true, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData3, true, false, false); metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); metricDataPoint = metricsData.getMetrics().get(0); @@ -283,7 +283,7 @@ public void testLongGauge() { MetricData metricData = metricDataList.get(0); for (PointData pointData : metricData.getData().getPoints()) { MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, false); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(20); @@ -319,7 +319,7 @@ public void testDoubleHistogram() { assertThat(metricData.getData().getPoints().size()).isEqualTo(1); PointData pointData = metricData.getData().getPoints().iterator().next(); MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, false); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getCount()).isEqualTo(1); @@ -357,7 +357,7 @@ public void testNoAttributeWithPrefixApplicationInsightsInternal() { assertThat(metricData.getData().getPoints().size()).isEqualTo(1); PointData pointData = metricData.getData().getPoints().iterator().next(); MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, false); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getProperties()).isNotNull(); From f8c97cfdde05a94475ef529b2c7d8e002bee1b62 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Mon, 15 Sep 2025 10:53:38 -0700 Subject: [PATCH 4/9] fixing style issue --- .../autoconfigure/implementation/MetricDataMapper.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java index e6c421231370..8eb995472b8b 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java @@ -58,8 +58,8 @@ public class MetricDataMapper { private final BiConsumer telemetryInitializer; private final boolean captureHttpServer4xxAsError; - private boolean otlpExporterEnabledForAKS; - private boolean metricsToLAEnabled; + private final boolean otlpExporterEnabledForAKS; + private final boolean metricsToLAEnabled; static { // HTTP unstable metrics to be excluded via Otel auto instrumentation @@ -82,7 +82,6 @@ public MetricDataMapper(BiConsumer telemetry } public void map(MetricData metricData, Consumer consumer) { - logger.verbose("Mapping metric data: {}", metricData.getName()); MetricDataType type = metricData.getType(); if (type == DOUBLE_SUM || type == DOUBLE_GAUGE || type == LONG_SUM || type == LONG_GAUGE || type == HISTOGRAM) { boolean isPreAggregatedStandardMetric @@ -101,7 +100,6 @@ public void map(MetricData metricData, Consumer consumer) { } if (metricsToLAEnabled && !isPreAggregatedStandardMetric) { - logger.verbose("Mapping stable metric to Breeze: {}", metricData.getName()); List stableOtelMetrics = convertOtelMetricToAzureMonitorMetric(metricData, false); stableOtelMetrics.forEach(consumer::accept); } From a54a544b6a67580fde36ca8e90ff122bc7e69324 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Mon, 15 Sep 2025 12:01:38 -0700 Subject: [PATCH 5/9] minor change & alter existing tests accordingly --- .../implementation/MetricDataMapper.java | 4 +-- .../AzureMonitorExportersEndToEndTest.java | 3 ++- .../AzureMonitorMetricExporterTest.java | 27 ++++++++++++------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java index 8eb995472b8b..97db8eb8a32c 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java @@ -186,9 +186,7 @@ public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemet } metricTelemetryBuilder.setMetricPoint(pointBuilder); - if (otlpExporterEnabled) { - metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW, Boolean.toString(otlpExporterEnabled)); - } + metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW, Boolean.toString(otlpExporterEnabled)); Attributes attributes = pointData.getAttributes(); if (isPreAggregatedStandardMetric) { diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExportersEndToEndTest.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExportersEndToEndTest.java index e08a7814955a..de8809f79371 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExportersEndToEndTest.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExportersEndToEndTest.java @@ -272,7 +272,8 @@ private static void validateMetric(TelemetryItem telemetryItem) { assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getName()).isEqualTo("test"); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(1.0); - assertThat(metricsData.getProperties()).containsExactly(entry("color", "red"), entry("name", "apple")); + assertThat(metricsData.getProperties()).containsExactly(entry("_MS.SentToAMW", "false"), entry("color", "red"), + entry("name", "apple")); } private static void validateLog(TelemetryItem telemetryItem) { diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java index 7dbbb69ddb03..b77624ca5d60 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java @@ -94,8 +94,9 @@ public void testDoubleGauge() { MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(20.0); - assertThat(metricsData.getProperties().size()).isEqualTo(1); + assertThat(metricsData.getProperties().size()).isEqualTo(2); assertThat(metricsData.getProperties()).containsEntry("thing", "engine"); + assertThat(metricsData.getProperties()).containsEntry("_MS.SentToAMW", "false"); } assertThat(metricData.getType()).isEqualTo(DOUBLE_GAUGE); @@ -129,9 +130,10 @@ public void testAttributesOnCustomMetric() { assertThat(metricsData.getMetrics().size()).isEqualTo(1); Map properties = metricsData.getProperties(); - assertThat(properties.size()).isEqualTo(2); + assertThat(properties.size()).isEqualTo(3); assertThat(properties.get(SERVER_ADDRESS.getKey())).isEqualTo("example.io"); assertThat(properties.get("foo")).isEqualTo("bar"); + assertThat(properties.get("_MS.SentToAMW")).isEqualTo("false"); } @Test @@ -163,12 +165,13 @@ public void testAttributesOnStandardMetric() { assertThat(metricsData.getMetrics().size()).isEqualTo(1); Map properties = metricsData.getProperties(); - assertThat(properties.size()).isEqualTo(5); + assertThat(properties.size()).isEqualTo(6); assertThat(properties.get("operation/synthetic")).isEqualTo("False"); assertThat(properties.get("Request.Success")).isEqualTo("True"); assertThat(properties.get("request/resultCode")).isEqualTo("200"); assertThat(properties.get("_MS.IsAutocollected")).isEqualTo("True"); assertThat(properties.get("_MS.MetricId")).isEqualTo("requests/duration"); + assertThat(properties.get("_MS.SentToAMW")).isEqualTo("false"); } @Test @@ -227,9 +230,10 @@ public void testLongCounter() { assertThat(metricDataPoint.getValue()).isEqualTo(2); Map properties = metricsData.getProperties(); - assertThat(properties.size()).isEqualTo(2); + assertThat(properties.size()).isEqualTo(3); assertThat(properties).containsEntry("name", "apple"); assertThat(properties).containsEntry("color", "green"); + assertThat(properties.get("_MS.SentToAMW")).isEqualTo("false"); builder = MetricTelemetryBuilder.create(); MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData2, true, false, false); @@ -239,9 +243,10 @@ public void testLongCounter() { assertThat(metricDataPoint.getValue()).isEqualTo(6); properties = metricsData.getProperties(); - assertThat(properties.size()).isEqualTo(2); + assertThat(properties.size()).isEqualTo(3); assertThat(properties).containsEntry("name", "apple"); assertThat(properties).containsEntry("color", "red"); + assertThat(properties.get("_MS.SentToAMW")).isEqualTo("false"); builder = MetricTelemetryBuilder.create(); MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData3, true, false, false); @@ -251,9 +256,10 @@ public void testLongCounter() { assertThat(metricDataPoint.getValue()).isEqualTo(7); properties = metricsData.getProperties(); - assertThat(properties.size()).isEqualTo(2); + assertThat(properties.size()).isEqualTo(3); assertThat(properties).containsEntry("name", "lemon"); assertThat(properties).containsEntry("color", "yellow"); + assertThat(properties.get("_MS.SentToAMW")).isEqualTo("false"); assertThat(metricData.getType()).isEqualTo(LONG_SUM); assertThat(metricData.getName()).isEqualTo("testLongCounter"); @@ -287,8 +293,9 @@ public void testLongGauge() { MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(20); - assertThat(metricsData.getProperties().size()).isEqualTo(1); + assertThat(metricsData.getProperties().size()).isEqualTo(2); assertThat(metricsData.getProperties()).containsEntry("thing", "engine"); + assertThat(metricsData.getProperties()).containsEntry("_MS.SentToAMW", "false"); } assertThat(metricData.getType()).isEqualTo(LONG_GAUGE); @@ -324,7 +331,7 @@ public void testDoubleHistogram() { assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getCount()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(25.45); - assertThat(metricsData.getProperties()).isNull(); + assertThat(metricsData.getProperties().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getMax()).isEqualTo(25.45); assertThat(metricsData.getMetrics().get(0).getMin()).isEqualTo(25.45); @@ -361,8 +368,8 @@ public void testNoAttributeWithPrefixApplicationInsightsInternal() { MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getProperties()).isNotNull(); - assertThat(metricsData.getProperties().size()).isEqualTo(1); - assertThat(metricsData.getProperties()).containsExactly(entry("foo", "bar")); + assertThat(metricsData.getProperties().size()).isEqualTo(2); + assertThat(metricsData.getProperties()).containsExactly(entry("_MS.SentToAMW", "false"), entry("foo", "bar")); assertThat(metricsData.getProperties().get("applicationinsights.internal.test")).isNull(); assertThat(metricData.getType()).isEqualTo(LONG_SUM); From 3f9fe210c69397593dd2768ca1e20292e7ed73e7 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Mon, 15 Sep 2025 15:14:50 -0700 Subject: [PATCH 6/9] remove extra constructor params from data mapper, add internal env vars --- .../AzureMonitorExporterBuilder.java | 2 +- .../implementation/MetricDataMapper.java | 30 ++++++++---- .../AzureMonitorExportersEndToEndTest.java | 3 +- .../AzureMonitorMetricExporterTest.java | 47 ++++++++----------- 4 files changed, 44 insertions(+), 38 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java index 5d352e471a1a..2218794d2e2a 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java @@ -121,7 +121,7 @@ LogRecordExporter buildLogRecordExporter() { MetricExporter buildMetricExporter() { HeartbeatExporter.start(MINUTES.toSeconds(15), createDefaultsPopulator(), builtTelemetryItemExporter::send); - return new AzureMonitorMetricExporter(new MetricDataMapper(createDefaultsPopulator(), true, false, true), + return new AzureMonitorMetricExporter(new MetricDataMapper(createDefaultsPopulator(), true), builtTelemetryItemExporter); } diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java index 97db8eb8a32c..f6478cfce5b2 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java @@ -53,12 +53,15 @@ public class MetricDataMapper { private static final Set OTEL_PRE_AGGREGATED_STANDARD_METRIC_NAMES = new HashSet<>(4); public static final AttributeKey APPLICATIONINSIGHTS_INTERNAL_METRIC_NAME = AttributeKey.stringKey("applicationinsights.internal.metric_name"); - public static final String MS_SENT_TO_AMW = "_MS.SentToAMW"; + public static final String MS_SENT_TO_AMW_ATTR = "_MS.SentToAMW"; + private static final String METRICS_TO_LOG_ANALYTICS_ENABLED + = "APPLICATIONINSIGHTS_METRICS_TO_LOGANALYTICS_ENABLED"; + private static final String SENT_TO_AMW = "SENT_TO_AMW"; private final BiConsumer telemetryInitializer; private final boolean captureHttpServer4xxAsError; - private final boolean otlpExporterEnabledForAKS; + private final String sentToAMW; private final boolean metricsToLAEnabled; static { @@ -74,11 +77,20 @@ public class MetricDataMapper { } public MetricDataMapper(BiConsumer telemetryInitializer, - boolean captureHttpServer4xxAsError, boolean otlpExporterEnabledForAKS, boolean metricsToLAEnabled) { + boolean captureHttpServer4xxAsError) { this.telemetryInitializer = telemetryInitializer; this.captureHttpServer4xxAsError = captureHttpServer4xxAsError; - this.otlpExporterEnabledForAKS = otlpExporterEnabledForAKS; - this.metricsToLAEnabled = metricsToLAEnabled; + String sentToAmwEnvVar = System.getenv(SENT_TO_AMW); + if (sentToAmwEnvVar != null && "true".equalsIgnoreCase(sentToAmwEnvVar)) { + this.sentToAMW = "true"; + } else if (sentToAmwEnvVar != null) { + this.sentToAMW = "false"; + } else { + this.sentToAMW = null; + } + + String metricsToLaEnvVar = System.getenv(METRICS_TO_LOG_ANALYTICS_ENABLED); + this.metricsToLAEnabled = metricsToLaEnvVar == null || "true".equalsIgnoreCase(metricsToLaEnvVar); } public void map(MetricData metricData, Consumer consumer) { @@ -118,7 +130,7 @@ private List convertOtelMetricToAzureMonitorMetric(MetricData met builder.setTime(FormattedTime.offSetDateTimeFromEpochNanos(pointData.getEpochNanos())); updateMetricPointBuilder(builder, metricData, pointData, captureHttpServer4xxAsError, - isPreAggregatedStandardMetric, this.otlpExporterEnabledForAKS); + isPreAggregatedStandardMetric, this.sentToAMW); telemetryItems.add(builder.build()); } @@ -128,7 +140,7 @@ private List convertOtelMetricToAzureMonitorMetric(MetricData met // visible for testing public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemetryBuilder, MetricData metricData, PointData pointData, boolean captureHttpServer4xxAsError, boolean isPreAggregatedStandardMetric, - boolean otlpExporterEnabled) { + String sentToAMW) { checkArgument(metricData != null, "MetricData cannot be null."); MetricPointBuilder pointBuilder = new MetricPointBuilder(); @@ -186,7 +198,9 @@ public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemet } metricTelemetryBuilder.setMetricPoint(pointBuilder); - metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW, Boolean.toString(otlpExporterEnabled)); + if (sentToAMW != null) { + metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW_ATTR, sentToAMW); + } Attributes attributes = pointData.getAttributes(); if (isPreAggregatedStandardMetric) { diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExportersEndToEndTest.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExportersEndToEndTest.java index de8809f79371..e08a7814955a 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExportersEndToEndTest.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExportersEndToEndTest.java @@ -272,8 +272,7 @@ private static void validateMetric(TelemetryItem telemetryItem) { assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getName()).isEqualTo("test"); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(1.0); - assertThat(metricsData.getProperties()).containsExactly(entry("_MS.SentToAMW", "false"), entry("color", "red"), - entry("name", "apple")); + assertThat(metricsData.getProperties()).containsExactly(entry("color", "red"), entry("name", "apple")); } private static void validateLog(TelemetryItem telemetryItem) { diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java index b77624ca5d60..4e6b5099f7ed 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java @@ -59,7 +59,7 @@ public void testDoubleCounter() { MetricData metricData = metricDataList.get(0); for (PointData pointData : metricData.getData().getPoints()) { MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricDataList.get(0), pointData, true, false, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricDataList.get(0), pointData, true, false, null); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(3.1415); @@ -90,13 +90,12 @@ public void testDoubleGauge() { MetricData metricData = metricDataList.get(0); for (PointData pointData : metricData.getData().getPoints()) { MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, null); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(20.0); - assertThat(metricsData.getProperties().size()).isEqualTo(2); + assertThat(metricsData.getProperties().size()).isEqualTo(1); assertThat(metricsData.getProperties()).containsEntry("thing", "engine"); - assertThat(metricsData.getProperties()).containsEntry("_MS.SentToAMW", "false"); } assertThat(metricData.getType()).isEqualTo(DOUBLE_GAUGE); @@ -124,16 +123,15 @@ public void testAttributesOnCustomMetric() { MetricData metric = metricDatas.get(0); PointData pointData = metric.getData().getPoints().stream().findFirst().get(); MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, false, false); + MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, false, null); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); Map properties = metricsData.getProperties(); - assertThat(properties.size()).isEqualTo(3); + assertThat(properties.size()).isEqualTo(2); assertThat(properties.get(SERVER_ADDRESS.getKey())).isEqualTo("example.io"); assertThat(properties.get("foo")).isEqualTo("bar"); - assertThat(properties.get("_MS.SentToAMW")).isEqualTo("false"); } @Test @@ -159,19 +157,18 @@ public void testAttributesOnStandardMetric() { MetricData metric = metricDatas.get(0); PointData pointData = metric.getData().getPoints().stream().findFirst().get(); MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, true, false); + MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, true, null); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); Map properties = metricsData.getProperties(); - assertThat(properties.size()).isEqualTo(6); + assertThat(properties.size()).isEqualTo(5); assertThat(properties.get("operation/synthetic")).isEqualTo("False"); assertThat(properties.get("Request.Success")).isEqualTo("True"); assertThat(properties.get("request/resultCode")).isEqualTo("200"); assertThat(properties.get("_MS.IsAutocollected")).isEqualTo("True"); assertThat(properties.get("_MS.MetricId")).isEqualTo("requests/duration"); - assertThat(properties.get("_MS.SentToAMW")).isEqualTo("false"); } @Test @@ -223,43 +220,40 @@ public void testLongCounter() { assertThat(longPointData3.getAttributes().get(AttributeKey.stringKey("color"))).isEqualTo("yellow"); MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData1, true, false, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData1, true, false, null); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); MetricDataPoint metricDataPoint = metricsData.getMetrics().get(0); assertThat(metricDataPoint.getValue()).isEqualTo(2); Map properties = metricsData.getProperties(); - assertThat(properties.size()).isEqualTo(3); + assertThat(properties.size()).isEqualTo(2); assertThat(properties).containsEntry("name", "apple"); assertThat(properties).containsEntry("color", "green"); - assertThat(properties.get("_MS.SentToAMW")).isEqualTo("false"); builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData2, true, false, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData2, true, false, null); metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); metricDataPoint = metricsData.getMetrics().get(0); assertThat(metricDataPoint.getValue()).isEqualTo(6); properties = metricsData.getProperties(); - assertThat(properties.size()).isEqualTo(3); + assertThat(properties.size()).isEqualTo(2); assertThat(properties).containsEntry("name", "apple"); assertThat(properties).containsEntry("color", "red"); - assertThat(properties.get("_MS.SentToAMW")).isEqualTo("false"); builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData3, true, false, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData3, true, false, null); metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); metricDataPoint = metricsData.getMetrics().get(0); assertThat(metricDataPoint.getValue()).isEqualTo(7); properties = metricsData.getProperties(); - assertThat(properties.size()).isEqualTo(3); + assertThat(properties.size()).isEqualTo(2); assertThat(properties).containsEntry("name", "lemon"); assertThat(properties).containsEntry("color", "yellow"); - assertThat(properties.get("_MS.SentToAMW")).isEqualTo("false"); assertThat(metricData.getType()).isEqualTo(LONG_SUM); assertThat(metricData.getName()).isEqualTo("testLongCounter"); @@ -289,13 +283,12 @@ public void testLongGauge() { MetricData metricData = metricDataList.get(0); for (PointData pointData : metricData.getData().getPoints()) { MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, null); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(20); - assertThat(metricsData.getProperties().size()).isEqualTo(2); + assertThat(metricsData.getProperties().size()).isEqualTo(1); assertThat(metricsData.getProperties()).containsEntry("thing", "engine"); - assertThat(metricsData.getProperties()).containsEntry("_MS.SentToAMW", "false"); } assertThat(metricData.getType()).isEqualTo(LONG_GAUGE); @@ -326,12 +319,12 @@ public void testDoubleHistogram() { assertThat(metricData.getData().getPoints().size()).isEqualTo(1); PointData pointData = metricData.getData().getPoints().iterator().next(); MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, null); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getCount()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(25.45); - assertThat(metricsData.getProperties().size()).isEqualTo(1); + assertThat(metricsData.getProperties()).isNull(); assertThat(metricsData.getMetrics().get(0).getMax()).isEqualTo(25.45); assertThat(metricsData.getMetrics().get(0).getMin()).isEqualTo(25.45); @@ -364,12 +357,12 @@ public void testNoAttributeWithPrefixApplicationInsightsInternal() { assertThat(metricData.getData().getPoints().size()).isEqualTo(1); PointData pointData = metricData.getData().getPoints().iterator().next(); MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, false); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, null); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getProperties()).isNotNull(); - assertThat(metricsData.getProperties().size()).isEqualTo(2); - assertThat(metricsData.getProperties()).containsExactly(entry("_MS.SentToAMW", "false"), entry("foo", "bar")); + assertThat(metricsData.getProperties().size()).isEqualTo(1); + assertThat(metricsData.getProperties()).containsExactly(entry("foo", "bar")); assertThat(metricsData.getProperties().get("applicationinsights.internal.test")).isNull(); assertThat(metricData.getType()).isEqualTo(LONG_SUM); From 66d5be16ac2a0ad3962a7733600065c997c9fd9b Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Mon, 15 Sep 2025 15:40:22 -0700 Subject: [PATCH 7/9] read from system prop instead of env var for amw flag --- .../autoconfigure/implementation/MetricDataMapper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java index f6478cfce5b2..0207c4f01ae1 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java @@ -80,10 +80,10 @@ public MetricDataMapper(BiConsumer telemetry boolean captureHttpServer4xxAsError) { this.telemetryInitializer = telemetryInitializer; this.captureHttpServer4xxAsError = captureHttpServer4xxAsError; - String sentToAmwEnvVar = System.getenv(SENT_TO_AMW); - if (sentToAmwEnvVar != null && "true".equalsIgnoreCase(sentToAmwEnvVar)) { + String sentToAmwProperty = System.getProperty(SENT_TO_AMW); + if (sentToAmwProperty != null && "true".equalsIgnoreCase(sentToAmwProperty)) { this.sentToAMW = "true"; - } else if (sentToAmwEnvVar != null) { + } else if (sentToAmwProperty != null) { this.sentToAMW = "false"; } else { this.sentToAMW = null; From 1531f15b44423afff0a6abddeea006328b49312c Mon Sep 17 00:00:00 2001 From: Sean Li Date: Thu, 18 Sep 2025 10:09:36 -0700 Subject: [PATCH 8/9] Pass by one Boolean variable instead of envvar --- .../implementation/MetricDataMapper.java | 24 ++++++------- .../AzureMonitorMetricExporterTest.java | 36 +++++++++++++++---- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java index 0207c4f01ae1..979eb55a1099 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java @@ -61,7 +61,7 @@ public class MetricDataMapper { private final BiConsumer telemetryInitializer; private final boolean captureHttpServer4xxAsError; - private final String sentToAMW; + private final Boolean otlpExporterEnabled; private final boolean metricsToLAEnabled; static { @@ -78,16 +78,14 @@ public class MetricDataMapper { public MetricDataMapper(BiConsumer telemetryInitializer, boolean captureHttpServer4xxAsError) { + this(telemetryInitializer, captureHttpServer4xxAsError, null); + } + + public MetricDataMapper(BiConsumer telemetryInitializer, + boolean captureHttpServer4xxAsError, Boolean otlpExporterEnabled) { this.telemetryInitializer = telemetryInitializer; this.captureHttpServer4xxAsError = captureHttpServer4xxAsError; - String sentToAmwProperty = System.getProperty(SENT_TO_AMW); - if (sentToAmwProperty != null && "true".equalsIgnoreCase(sentToAmwProperty)) { - this.sentToAMW = "true"; - } else if (sentToAmwProperty != null) { - this.sentToAMW = "false"; - } else { - this.sentToAMW = null; - } + this.otlpExporterEnabled = otlpExporterEnabled; String metricsToLaEnvVar = System.getenv(METRICS_TO_LOG_ANALYTICS_ENABLED); this.metricsToLAEnabled = metricsToLaEnvVar == null || "true".equalsIgnoreCase(metricsToLaEnvVar); @@ -130,7 +128,7 @@ private List convertOtelMetricToAzureMonitorMetric(MetricData met builder.setTime(FormattedTime.offSetDateTimeFromEpochNanos(pointData.getEpochNanos())); updateMetricPointBuilder(builder, metricData, pointData, captureHttpServer4xxAsError, - isPreAggregatedStandardMetric, this.sentToAMW); + isPreAggregatedStandardMetric, this.otlpExporterEnabled); telemetryItems.add(builder.build()); } @@ -140,7 +138,7 @@ private List convertOtelMetricToAzureMonitorMetric(MetricData met // visible for testing public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemetryBuilder, MetricData metricData, PointData pointData, boolean captureHttpServer4xxAsError, boolean isPreAggregatedStandardMetric, - String sentToAMW) { + Boolean otlpExporterEnabled) { checkArgument(metricData != null, "MetricData cannot be null."); MetricPointBuilder pointBuilder = new MetricPointBuilder(); @@ -198,8 +196,8 @@ public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemet } metricTelemetryBuilder.setMetricPoint(pointBuilder); - if (sentToAMW != null) { - metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW_ATTR, sentToAMW); + if (otlpExporterEnabled != null) { + metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW_ATTR, otlpExporterEnabled ? "True" : "False"); } Attributes attributes = pointData.getAttributes(); diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java index 4e6b5099f7ed..ce1ef30e4b46 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java @@ -20,6 +20,8 @@ import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricExporter; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import java.util.Collection; import java.util.Comparator; @@ -27,6 +29,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.azure.monitor.opentelemetry.autoconfigure.implementation.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE; import static com.azure.monitor.opentelemetry.autoconfigure.implementation.semconv.ServerAttributes.SERVER_ADDRESS; @@ -40,8 +43,13 @@ public class AzureMonitorMetricExporterTest { - @Test - public void testDoubleCounter() { + static Stream enablementOptions() { + return Stream.of(true, false, null); + } + + @ParameterizedTest + @MethodSource("enablementOptions") + public void testDoubleCounter(Boolean otlpExporterEnabled) { InMemoryMetricExporter inMemoryMetricExporter = InMemoryMetricExporter.create(); SdkMeterProvider meterProvider = SdkMeterProvider.builder() .registerMetricReader(PeriodicMetricReader.builder(inMemoryMetricExporter).build()) @@ -59,18 +67,28 @@ public void testDoubleCounter() { MetricData metricData = metricDataList.get(0); for (PointData pointData : metricData.getData().getPoints()) { MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricDataList.get(0), pointData, true, false, null); + MetricDataMapper.updateMetricPointBuilder(builder, metricDataList.get(0), pointData, true, false, + otlpExporterEnabled); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(3.1415); + + if (otlpExporterEnabled != null) { + assertThat(metricsData.getProperties().size()).isEqualTo(1); + assertThat(metricsData.getProperties()).containsEntry("_MS.SentToAMW", + otlpExporterEnabled ? "True" : "False"); + } else { + assertThat(metricsData.getProperties()).isNull(); + } } assertThat(metricData.getType()).isEqualTo(DOUBLE_SUM); assertThat(metricData.getName()).isEqualTo("testDoubleCounter"); } - @Test - public void testDoubleGauge() { + @ParameterizedTest + @MethodSource("enablementOptions") + public void testDoubleGauge(Boolean otlpExporterEnabled) { InMemoryMetricExporter inMemoryMetricExporter = InMemoryMetricExporter.create(); SdkMeterProvider meterProvider = SdkMeterProvider.builder() .registerMetricReader(PeriodicMetricReader.builder(inMemoryMetricExporter).build()) @@ -90,12 +108,16 @@ public void testDoubleGauge() { MetricData metricData = metricDataList.get(0); for (PointData pointData : metricData.getData().getPoints()) { MetricTelemetryBuilder builder = MetricTelemetryBuilder.create(); - MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, null); + MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, otlpExporterEnabled); MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData(); assertThat(metricsData.getMetrics().size()).isEqualTo(1); assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(20.0); - assertThat(metricsData.getProperties().size()).isEqualTo(1); + assertThat(metricsData.getProperties().size()).isEqualTo(otlpExporterEnabled == null ? 1 : 2); assertThat(metricsData.getProperties()).containsEntry("thing", "engine"); + if (otlpExporterEnabled != null) { + assertThat(metricsData.getProperties()).containsEntry("_MS.SentToAMW", + otlpExporterEnabled ? "True" : "False"); + } } assertThat(metricData.getType()).isEqualTo(DOUBLE_GAUGE); From aafc1fd69258456eb6dbd99a225f626598b8724b Mon Sep 17 00:00:00 2001 From: Sean Li Date: Thu, 18 Sep 2025 10:39:19 -0700 Subject: [PATCH 9/9] remove unused variable. fix typo. --- .../autoconfigure/implementation/MetricDataMapper.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java index 979eb55a1099..8dd8b957fc5b 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java @@ -56,7 +56,6 @@ public class MetricDataMapper { public static final String MS_SENT_TO_AMW_ATTR = "_MS.SentToAMW"; private static final String METRICS_TO_LOG_ANALYTICS_ENABLED = "APPLICATIONINSIGHTS_METRICS_TO_LOGANALYTICS_ENABLED"; - private static final String SENT_TO_AMW = "SENT_TO_AMW"; private final BiConsumer telemetryInitializer; private final boolean captureHttpServer4xxAsError; @@ -65,7 +64,7 @@ public class MetricDataMapper { private final boolean metricsToLAEnabled; static { - // HTTP unstable metrics to be excluded via Otel auto instrumentation + // HTTP unstable metrics to be excluded via OTel auto instrumentation OTEL_UNSTABLE_METRICS_TO_EXCLUDE.add("rpc.client.duration"); OTEL_UNSTABLE_METRICS_TO_EXCLUDE.add("rpc.server.duration");