Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -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, true),
builtTelemetryItemExporter);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@ public class MetricDataMapper {
private static final Set<String> OTEL_PRE_AGGREGATED_STANDARD_METRIC_NAMES = new HashSet<>(4);
public static final AttributeKey<String> APPLICATIONINSIGHTS_INTERNAL_METRIC_NAME
= AttributeKey.stringKey("applicationinsights.internal.metric_name");
public static final String MS_SENT_TO_AMW = "_MS.SentToAMW";

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

private final boolean otlpExporterEnabledForAKS;
private final boolean metricsToLAEnabled;

static {
// HTTP unstable metrics to be excluded via Otel auto instrumentation
OTEL_UNSTABLE_METRICS_TO_EXCLUDE.add("rpc.client.duration");
Expand All @@ -70,17 +74,19 @@ public class MetricDataMapper {
}

public MetricDataMapper(BiConsumer<AbstractTelemetryBuilder, Resource> telemetryInitializer,
boolean captureHttpServer4xxAsError) {
boolean captureHttpServer4xxAsError, boolean otlpExporterEnabledForAKS, boolean metricsToLAEnabled) {
this.telemetryInitializer = telemetryInitializer;
this.captureHttpServer4xxAsError = captureHttpServer4xxAsError;
this.otlpExporterEnabledForAKS = otlpExporterEnabledForAKS;
this.metricsToLAEnabled = metricsToLAEnabled;
}

public void map(MetricData metricData, Consumer<TelemetryItem> consumer) {
MetricDataType type = metricData.getType();
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<TelemetryItem> preAggregatedStandardMetrics
= convertOtelMetricToAzureMonitorMetric(metricData, true);
preAggregatedStandardMetrics.forEach(consumer::accept);
Expand All @@ -92,8 +98,11 @@ public void map(MetricData metricData, Consumer<TelemetryItem> consumer) {
&& metricData.getInstrumentationScopeInfo().getName().startsWith(OTEL_INSTRUMENTATION_NAME_PREFIX)) {
return;
}
List<TelemetryItem> stableOtelMetrics = convertOtelMetricToAzureMonitorMetric(metricData, false);
stableOtelMetrics.forEach(consumer::accept);

if (metricsToLAEnabled && !isPreAggregatedStandardMetric) {
List<TelemetryItem> stableOtelMetrics = convertOtelMetricToAzureMonitorMetric(metricData, false);
stableOtelMetrics.forEach(consumer::accept);
}
} else {
logger.warning("metric data type {} is not supported yet.", metricData.getType());
}
Expand All @@ -109,7 +118,7 @@ private List<TelemetryItem> convertOtelMetricToAzureMonitorMetric(MetricData met

builder.setTime(FormattedTime.offSetDateTimeFromEpochNanos(pointData.getEpochNanos()));
updateMetricPointBuilder(builder, metricData, pointData, captureHttpServer4xxAsError,
isPreAggregatedStandardMetric);
isPreAggregatedStandardMetric, this.otlpExporterEnabledForAKS);

telemetryItems.add(builder.build());
}
Expand All @@ -118,7 +127,8 @@ private List<TelemetryItem> 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();
Expand Down Expand Up @@ -176,6 +186,7 @@ public static void updateMetricPointBuilder(MetricTelemetryBuilder metricTelemet
}

metricTelemetryBuilder.setMetricPoint(pointBuilder);
metricTelemetryBuilder.addProperty(MS_SENT_TO_AMW, Boolean.toString(otlpExporterEnabled));

Attributes attributes = pointData.getAttributes();
if (isPreAggregatedStandardMetric) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -90,12 +90,13 @@ 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);
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);
Expand Down Expand Up @@ -123,15 +124,16 @@ 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);
Map<String, String> 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
Expand All @@ -157,18 +159,19 @@ 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);
Map<String, String> 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
Expand Down Expand Up @@ -220,40 +223,43 @@ 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);
assertThat(metricDataPoint.getValue()).isEqualTo(2);

Map<String, String> 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);
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);
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);
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);
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");
Expand Down Expand Up @@ -283,12 +289,13 @@ 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);
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);
Expand Down Expand Up @@ -319,12 +326,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);
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);
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);

Expand Down Expand Up @@ -357,12 +364,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);
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();
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);
Expand Down
Loading