Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import static java.util.concurrent.TimeUnit.SECONDS;

import com.azure.monitor.opentelemetry.autoconfigure.implementation.AzureMonitorExporterProviderKeys;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.utils.Strings;
import com.microsoft.applicationinsights.agent.internal.configuration.Configuration;
import com.microsoft.applicationinsights.agent.internal.legacyheaders.DelegatingPropagatorProvider;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
Expand Down Expand Up @@ -115,7 +117,14 @@ public Map<String, String> apply(ConfigProperties otelConfig) {
}

String metricsExporter = otelConfig.getString("otel.metrics.exporter");
if (metricsExporter == null) {
String aksNamespaceId = System.getenv("AKS_ARM_NAMESPACE_ID");
String metricsToLogAnalyticsEnabled =
otelConfig.getString("applicationinsights.metrics.to.loganalytics.enabled");
if (isAksAttach(aksNamespaceId)) {
properties.put(
"otel.metrics.exporter",
updateMetricsExporter(metricsExporter, metricsToLogAnalyticsEnabled));
} else if (metricsExporter == null) {
// this overrides the default "otlp" so the exporter can be configured later
properties.put("otel.metrics.exporter", "none");
}
Expand Down Expand Up @@ -343,4 +352,55 @@ private static <T> String join(List<T> values, char separator) {
}
return sb.toString();
}

// visible for tests
static boolean isAksAttach(String aksNamespaceId) {
return !Strings.isNullOrEmpty(aksNamespaceId);
}

static String updateMetricsExporter(String metricsExporter, String metricsToLogAnalyticsEnabled) {
String azureMonitorName = AzureMonitorExporterProviderKeys.EXPORTER_NAME;
// If AMLE is true, configure both otlp and azure monitor exporters
if (Boolean.parseBoolean(metricsToLogAnalyticsEnabled)) {
// 1. Set default to "azure_monitor,otlp"
// 2. If exporter is "none", change to "azure_monitor,otlp" (AMLE true has higher priority
// than none)
if (metricsExporter == null
|| metricsExporter.isEmpty()
|| metricsExporter.equalsIgnoreCase("none")) {
return azureMonitorName + ",otlp";
}
// 3. If either azure monitor or otlp is missing, add them
if (!metricsExporter.contains(azureMonitorName)) {
metricsExporter += "," + azureMonitorName;
}
if (!metricsExporter.contains("otlp")) {
metricsExporter += ",otlp";
}
return metricsExporter;
}

// If AMLE is unset:
if (metricsToLogAnalyticsEnabled == null || metricsToLogAnalyticsEnabled.isEmpty()) {
if (metricsExporter == null || metricsExporter.isEmpty()) {
// Set default to "azure_monitor,otlp"
return azureMonitorName + ",otlp";
} else if (metricsExporter.contains(azureMonitorName) && !metricsExporter.contains("otlp")) {
// if azure monitor is already present and otlp is not, add otlp
metricsExporter += ",otlp";
Comment on lines +389 to +390
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't understand why adding otlp here?

}
return metricsExporter;
}

// If AMLE is false, configure only azure monitor exporter.
// 1. Default is azure monitor
// 2. If otlp is set, cancel it and replace with azure monitor (AMLE false has higher priority
// than otlp setting)
if (metricsExporter == null
|| metricsExporter.isEmpty()
|| metricsExporter.contains(azureMonitorName)) {
return azureMonitorName;
}
return metricsExporter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.applicationinsights.agent.internal.init;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

class AiConfigCustomizerTest {

@Test
void isAksAttach() {
assertThat(AiConfigCustomizer.isAksAttach("dummy-aks-namespace")).isTrue();

assertThat(AiConfigCustomizer.isAksAttach(null)).isFalse();
assertThat(AiConfigCustomizer.isAksAttach("")).isFalse();
}

@Test
void updateMetricsExporter_ExporterUnset() {

assertThat(AiConfigCustomizer.updateMetricsExporter(null, null))
.isEqualTo("azure_monitor,otlp");

assertThat(AiConfigCustomizer.updateMetricsExporter("", null)).isEqualTo("azure_monitor,otlp");

assertThat(AiConfigCustomizer.updateMetricsExporter(null, "true"))
.isEqualTo("azure_monitor,otlp");

assertThat(AiConfigCustomizer.updateMetricsExporter(null, "True"))
.isEqualTo("azure_monitor,otlp");
}

static Stream<Arguments> stringPairs() {
return Stream.of(
Arguments.of("none", "none"),
Arguments.of("azure_monitor", "azure_monitor,otlp"),
Arguments.of("azure_monitor,otlp", "azure_monitor,otlp"),
Arguments.of("otlp", "otlp"));
}

@ParameterizedTest
@MethodSource("stringPairs")
void updateMetricsExporter_ExporterSet_AMLE_Unset(
String metricsExporter, String expectAzureMonitor) {
assertThat(AiConfigCustomizer.updateMetricsExporter(metricsExporter, null))
.isEqualTo(expectAzureMonitor);
assertThat(AiConfigCustomizer.updateMetricsExporter(metricsExporter, ""))
.isEqualTo(expectAzureMonitor);
}

static Stream<Arguments> stringPairs2() {
return Stream.of(
Arguments.of("none", "azure_monitor,otlp"),
Arguments.of("azure_monitor", "azure_monitor,otlp"),
Arguments.of("azure_monitor,otlp", "azure_monitor,otlp"),
Arguments.of("otlp", "otlp,azure_monitor"));
}

@ParameterizedTest
@MethodSource("stringPairs2")
void updateMetricsExporter_ExporterSet_AMLE_True(
String metricsExporter, String expectAzureMonitor) {
assertThat(AiConfigCustomizer.updateMetricsExporter(metricsExporter, "true"))
.isEqualTo(expectAzureMonitor);
assertThat(AiConfigCustomizer.updateMetricsExporter(metricsExporter, "True"))
.isEqualTo(expectAzureMonitor);
}

static Stream<Arguments> stringPairs3() {
return Stream.of(
Arguments.of("none", "none"),
Arguments.of("azure_monitor", "azure_monitor"),
Arguments.of("azure_monitor,otlp", "azure_monitor"),
Arguments.of("otlp", "otlp"));
}

@ParameterizedTest
@MethodSource("stringPairs3")
void updateMetricsExporter_ExporterSet_AMLE_False(
String metricsExporter, String expectAzureMonitor) {
assertThat(AiConfigCustomizer.updateMetricsExporter(metricsExporter, "false"))
.isEqualTo(expectAzureMonitor);
assertThat(AiConfigCustomizer.updateMetricsExporter(metricsExporter, "False"))
.isEqualTo(expectAzureMonitor);
}
}
Loading