Skip to content

Commit 34de18c

Browse files
harsimarxiang17
andauthored
Add de-duping flag for standard/otel metrics & support for conditionally sending otel metrics to Breeze (#46680)
* add the dual emit flag to otel metrics * add enable env var * fixing compiler issues * fixing style issue * minor change & alter existing tests accordingly * remove extra constructor params from data mapper, add internal env vars * read from system prop instead of env var for amw flag * Pass by one Boolean variable instead of envvar * remove unused variable. fix typo. --------- Co-authored-by: Sean Li <[email protected]>
1 parent 2dada92 commit 34de18c

File tree

2 files changed

+65
-21
lines changed

2 files changed

+65
-21
lines changed

sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/MetricDataMapper.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,18 @@ public class MetricDataMapper {
5353
private static final Set<String> OTEL_PRE_AGGREGATED_STANDARD_METRIC_NAMES = new HashSet<>(4);
5454
public static final AttributeKey<String> APPLICATIONINSIGHTS_INTERNAL_METRIC_NAME
5555
= AttributeKey.stringKey("applicationinsights.internal.metric_name");
56+
public static final String MS_SENT_TO_AMW_ATTR = "_MS.SentToAMW";
57+
private static final String METRICS_TO_LOG_ANALYTICS_ENABLED
58+
= "APPLICATIONINSIGHTS_METRICS_TO_LOGANALYTICS_ENABLED";
5659

5760
private final BiConsumer<AbstractTelemetryBuilder, Resource> telemetryInitializer;
5861
private final boolean captureHttpServer4xxAsError;
5962

63+
private final Boolean otlpExporterEnabled;
64+
private final boolean metricsToLAEnabled;
65+
6066
static {
61-
// HTTP unstable metrics to be excluded via Otel auto instrumentation
67+
// HTTP unstable metrics to be excluded via OTel auto instrumentation
6268
OTEL_UNSTABLE_METRICS_TO_EXCLUDE.add("rpc.client.duration");
6369
OTEL_UNSTABLE_METRICS_TO_EXCLUDE.add("rpc.server.duration");
6470

@@ -71,16 +77,25 @@ public class MetricDataMapper {
7177

7278
public MetricDataMapper(BiConsumer<AbstractTelemetryBuilder, Resource> telemetryInitializer,
7379
boolean captureHttpServer4xxAsError) {
80+
this(telemetryInitializer, captureHttpServer4xxAsError, null);
81+
}
82+
83+
public MetricDataMapper(BiConsumer<AbstractTelemetryBuilder, Resource> telemetryInitializer,
84+
boolean captureHttpServer4xxAsError, Boolean otlpExporterEnabled) {
7485
this.telemetryInitializer = telemetryInitializer;
7586
this.captureHttpServer4xxAsError = captureHttpServer4xxAsError;
87+
this.otlpExporterEnabled = otlpExporterEnabled;
88+
89+
String metricsToLaEnvVar = System.getenv(METRICS_TO_LOG_ANALYTICS_ENABLED);
90+
this.metricsToLAEnabled = metricsToLaEnvVar == null || "true".equalsIgnoreCase(metricsToLaEnvVar);
7691
}
7792

7893
public void map(MetricData metricData, Consumer<TelemetryItem> consumer) {
7994
MetricDataType type = metricData.getType();
8095
if (type == DOUBLE_SUM || type == DOUBLE_GAUGE || type == LONG_SUM || type == LONG_GAUGE || type == HISTOGRAM) {
8196
boolean isPreAggregatedStandardMetric
8297
= OTEL_PRE_AGGREGATED_STANDARD_METRIC_NAMES.contains(metricData.getName());
83-
if (isPreAggregatedStandardMetric) {
98+
if (isPreAggregatedStandardMetric) { // we want standard metrics to always be sent to Breeze
8499
List<TelemetryItem> preAggregatedStandardMetrics
85100
= convertOtelMetricToAzureMonitorMetric(metricData, true);
86101
preAggregatedStandardMetrics.forEach(consumer::accept);
@@ -92,8 +107,11 @@ public void map(MetricData metricData, Consumer<TelemetryItem> consumer) {
92107
&& metricData.getInstrumentationScopeInfo().getName().startsWith(OTEL_INSTRUMENTATION_NAME_PREFIX)) {
93108
return;
94109
}
95-
List<TelemetryItem> stableOtelMetrics = convertOtelMetricToAzureMonitorMetric(metricData, false);
96-
stableOtelMetrics.forEach(consumer::accept);
110+
111+
if (metricsToLAEnabled && !isPreAggregatedStandardMetric) {
112+
List<TelemetryItem> stableOtelMetrics = convertOtelMetricToAzureMonitorMetric(metricData, false);
113+
stableOtelMetrics.forEach(consumer::accept);
114+
}
97115
} else {
98116
logger.warning("metric data type {} is not supported yet.", metricData.getType());
99117
}
@@ -109,7 +127,7 @@ private List<TelemetryItem> convertOtelMetricToAzureMonitorMetric(MetricData met
109127

110128
builder.setTime(FormattedTime.offSetDateTimeFromEpochNanos(pointData.getEpochNanos()));
111129
updateMetricPointBuilder(builder, metricData, pointData, captureHttpServer4xxAsError,
112-
isPreAggregatedStandardMetric);
130+
isPreAggregatedStandardMetric, this.otlpExporterEnabled);
113131

114132
telemetryItems.add(builder.build());
115133
}
@@ -118,7 +136,8 @@ private List<TelemetryItem> convertOtelMetricToAzureMonitorMetric(MetricData met
118136

119137
// visible for testing
120138
public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemetryBuilder, MetricData metricData,
121-
PointData pointData, boolean captureHttpServer4xxAsError, boolean isPreAggregatedStandardMetric) {
139+
PointData pointData, boolean captureHttpServer4xxAsError, boolean isPreAggregatedStandardMetric,
140+
Boolean otlpExporterEnabled) {
122141
checkArgument(metricData != null, "MetricData cannot be null.");
123142

124143
MetricPointBuilder pointBuilder = new MetricPointBuilder();
@@ -176,6 +195,9 @@ public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemet
176195
}
177196

178197
metricTelemetryBuilder.setMetricPoint(pointBuilder);
198+
if (otlpExporterEnabled != null) {
199+
metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW_ATTR, otlpExporterEnabled ? "True" : "False");
200+
}
179201

180202
Attributes attributes = pointData.getAttributes();
181203
if (isPreAggregatedStandardMetric) {

sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorMetricExporterTest.java

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@
2020
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
2121
import io.opentelemetry.sdk.testing.exporter.InMemoryMetricExporter;
2222
import org.junit.jupiter.api.Test;
23+
import org.junit.jupiter.params.ParameterizedTest;
24+
import org.junit.jupiter.params.provider.MethodSource;
2325

2426
import java.util.Collection;
2527
import java.util.Comparator;
2628
import java.util.Iterator;
2729
import java.util.List;
2830
import java.util.Map;
2931
import java.util.stream.Collectors;
32+
import java.util.stream.Stream;
3033

3134
import static com.azure.monitor.opentelemetry.autoconfigure.implementation.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE;
3235
import static com.azure.monitor.opentelemetry.autoconfigure.implementation.semconv.ServerAttributes.SERVER_ADDRESS;
@@ -40,8 +43,13 @@
4043

4144
public class AzureMonitorMetricExporterTest {
4245

43-
@Test
44-
public void testDoubleCounter() {
46+
static Stream<Boolean> enablementOptions() {
47+
return Stream.of(true, false, null);
48+
}
49+
50+
@ParameterizedTest
51+
@MethodSource("enablementOptions")
52+
public void testDoubleCounter(Boolean otlpExporterEnabled) {
4553
InMemoryMetricExporter inMemoryMetricExporter = InMemoryMetricExporter.create();
4654
SdkMeterProvider meterProvider = SdkMeterProvider.builder()
4755
.registerMetricReader(PeriodicMetricReader.builder(inMemoryMetricExporter).build())
@@ -59,18 +67,28 @@ public void testDoubleCounter() {
5967
MetricData metricData = metricDataList.get(0);
6068
for (PointData pointData : metricData.getData().getPoints()) {
6169
MetricTelemetryBuilder builder = MetricTelemetryBuilder.create();
62-
MetricDataMapper.updateMetricPointBuilder(builder, metricDataList.get(0), pointData, true, false);
70+
MetricDataMapper.updateMetricPointBuilder(builder, metricDataList.get(0), pointData, true, false,
71+
otlpExporterEnabled);
6372
MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData();
6473
assertThat(metricsData.getMetrics().size()).isEqualTo(1);
6574
assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(3.1415);
75+
76+
if (otlpExporterEnabled != null) {
77+
assertThat(metricsData.getProperties().size()).isEqualTo(1);
78+
assertThat(metricsData.getProperties()).containsEntry("_MS.SentToAMW",
79+
otlpExporterEnabled ? "True" : "False");
80+
} else {
81+
assertThat(metricsData.getProperties()).isNull();
82+
}
6683
}
6784

6885
assertThat(metricData.getType()).isEqualTo(DOUBLE_SUM);
6986
assertThat(metricData.getName()).isEqualTo("testDoubleCounter");
7087
}
7188

72-
@Test
73-
public void testDoubleGauge() {
89+
@ParameterizedTest
90+
@MethodSource("enablementOptions")
91+
public void testDoubleGauge(Boolean otlpExporterEnabled) {
7492
InMemoryMetricExporter inMemoryMetricExporter = InMemoryMetricExporter.create();
7593
SdkMeterProvider meterProvider = SdkMeterProvider.builder()
7694
.registerMetricReader(PeriodicMetricReader.builder(inMemoryMetricExporter).build())
@@ -90,12 +108,16 @@ public void testDoubleGauge() {
90108
MetricData metricData = metricDataList.get(0);
91109
for (PointData pointData : metricData.getData().getPoints()) {
92110
MetricTelemetryBuilder builder = MetricTelemetryBuilder.create();
93-
MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false);
111+
MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, otlpExporterEnabled);
94112
MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData();
95113
assertThat(metricsData.getMetrics().size()).isEqualTo(1);
96114
assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(20.0);
97-
assertThat(metricsData.getProperties().size()).isEqualTo(1);
115+
assertThat(metricsData.getProperties().size()).isEqualTo(otlpExporterEnabled == null ? 1 : 2);
98116
assertThat(metricsData.getProperties()).containsEntry("thing", "engine");
117+
if (otlpExporterEnabled != null) {
118+
assertThat(metricsData.getProperties()).containsEntry("_MS.SentToAMW",
119+
otlpExporterEnabled ? "True" : "False");
120+
}
99121
}
100122

101123
assertThat(metricData.getType()).isEqualTo(DOUBLE_GAUGE);
@@ -123,7 +145,7 @@ public void testAttributesOnCustomMetric() {
123145
MetricData metric = metricDatas.get(0);
124146
PointData pointData = metric.getData().getPoints().stream().findFirst().get();
125147
MetricTelemetryBuilder builder = MetricTelemetryBuilder.create();
126-
MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, false);
148+
MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, false, null);
127149

128150
MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData();
129151
assertThat(metricsData.getMetrics().size()).isEqualTo(1);
@@ -157,7 +179,7 @@ public void testAttributesOnStandardMetric() {
157179
MetricData metric = metricDatas.get(0);
158180
PointData pointData = metric.getData().getPoints().stream().findFirst().get();
159181
MetricTelemetryBuilder builder = MetricTelemetryBuilder.create();
160-
MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, true);
182+
MetricDataMapper.updateMetricPointBuilder(builder, metric, pointData, true, true, null);
161183

162184
MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData();
163185
assertThat(metricsData.getMetrics().size()).isEqualTo(1);
@@ -220,7 +242,7 @@ public void testLongCounter() {
220242
assertThat(longPointData3.getAttributes().get(AttributeKey.stringKey("color"))).isEqualTo("yellow");
221243

222244
MetricTelemetryBuilder builder = MetricTelemetryBuilder.create();
223-
MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData1, true, false);
245+
MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData1, true, false, null);
224246
MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData();
225247
assertThat(metricsData.getMetrics().size()).isEqualTo(1);
226248
MetricDataPoint metricDataPoint = metricsData.getMetrics().get(0);
@@ -232,7 +254,7 @@ public void testLongCounter() {
232254
assertThat(properties).containsEntry("color", "green");
233255

234256
builder = MetricTelemetryBuilder.create();
235-
MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData2, true, false);
257+
MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData2, true, false, null);
236258
metricsData = (MetricsData) builder.build().getData().getBaseData();
237259
assertThat(metricsData.getMetrics().size()).isEqualTo(1);
238260
metricDataPoint = metricsData.getMetrics().get(0);
@@ -244,7 +266,7 @@ public void testLongCounter() {
244266
assertThat(properties).containsEntry("color", "red");
245267

246268
builder = MetricTelemetryBuilder.create();
247-
MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData3, true, false);
269+
MetricDataMapper.updateMetricPointBuilder(builder, metricData, longPointData3, true, false, null);
248270
metricsData = (MetricsData) builder.build().getData().getBaseData();
249271
assertThat(metricsData.getMetrics().size()).isEqualTo(1);
250272
metricDataPoint = metricsData.getMetrics().get(0);
@@ -283,7 +305,7 @@ public void testLongGauge() {
283305
MetricData metricData = metricDataList.get(0);
284306
for (PointData pointData : metricData.getData().getPoints()) {
285307
MetricTelemetryBuilder builder = MetricTelemetryBuilder.create();
286-
MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false);
308+
MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, null);
287309
MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData();
288310
assertThat(metricsData.getMetrics().size()).isEqualTo(1);
289311
assertThat(metricsData.getMetrics().get(0).getValue()).isEqualTo(20);
@@ -319,7 +341,7 @@ public void testDoubleHistogram() {
319341
assertThat(metricData.getData().getPoints().size()).isEqualTo(1);
320342
PointData pointData = metricData.getData().getPoints().iterator().next();
321343
MetricTelemetryBuilder builder = MetricTelemetryBuilder.create();
322-
MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false);
344+
MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, null);
323345
MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData();
324346
assertThat(metricsData.getMetrics().size()).isEqualTo(1);
325347
assertThat(metricsData.getMetrics().get(0).getCount()).isEqualTo(1);
@@ -357,7 +379,7 @@ public void testNoAttributeWithPrefixApplicationInsightsInternal() {
357379
assertThat(metricData.getData().getPoints().size()).isEqualTo(1);
358380
PointData pointData = metricData.getData().getPoints().iterator().next();
359381
MetricTelemetryBuilder builder = MetricTelemetryBuilder.create();
360-
MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false);
382+
MetricDataMapper.updateMetricPointBuilder(builder, metricData, pointData, true, false, null);
361383
MetricsData metricsData = (MetricsData) builder.build().getData().getBaseData();
362384
assertThat(metricsData.getMetrics().size()).isEqualTo(1);
363385
assertThat(metricsData.getProperties()).isNotNull();

0 commit comments

Comments
 (0)