Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Azure Application Insights connection string support #3715

Merged
merged 26 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
10507ad
[Azure] Migrate from Application Insights instrumentation keys to con…
cbismuth Mar 24, 2023
2af8d21
Revert formatting extra changes
cbismuth Mar 24, 2023
48f8deb
Revert duplicated test
cbismuth Mar 24, 2023
30a21bf
Use Objects#equals API
cbismuth Mar 24, 2023
cfc0362
YodaCondition: The non-constant portion of an equals check generally …
cbismuth Mar 24, 2023
f6cce8a
Trigger CircleCI build
cbismuth Mar 24, 2023
e7eb962
Remove instrumentation key extraction
cbismuth Mar 27, 2023
3a152a4
Merge branch 'micrometer-metrics:main' into 3710_azure_instrumentatio…
cbismuth Mar 27, 2023
48c5302
Merge branch 'main' into 3710_azure_instrumentation_key
cbismuth Mar 27, 2023
8e93d87
Merge remote-tracking branch 'origin/3710_azure_instrumentation_key' …
cbismuth Mar 27, 2023
c68c5ea
[Azure] Migrate from Application Insights instrumentation keys to con…
cbismuth Mar 24, 2023
65673e3
Revert formatting extra changes
cbismuth Mar 24, 2023
81faf16
Revert duplicated test
cbismuth Mar 24, 2023
c0261b2
Use Objects#equals API
cbismuth Mar 24, 2023
25ed5d5
YodaCondition: The non-constant portion of an equals check generally …
cbismuth Mar 24, 2023
d9f3c71
Trigger CircleCI build
cbismuth Mar 24, 2023
0ca32bd
Remove instrumentation key extraction
cbismuth Mar 27, 2023
60115bb
Add Javadoc since to new constructors in LoggingMeterRegistry (#3716)
izeye Mar 25, 2023
448baba
Polish compiler warnings
shakuzen Mar 27, 2023
5e37df4
Polish and update ModifiedClassPathClassLoader
shakuzen Mar 27, 2023
7d67cee
Add Azure documentation link
cbismuth Mar 27, 2023
1be6fcb
Merge remote-tracking branch 'origin/3710_azure_instrumentation_key' …
cbismuth Mar 27, 2023
534eb6d
Allow usage of instrumentation key for smooth upgrade
cbismuth Mar 27, 2023
43534dd
Remove extra diff
cbismuth Mar 27, 2023
303aa64
Move connection string logic out of class constructor
cbismuth Mar 28, 2023
48e388c
Suppress deprecation warning in test
shakuzen Mar 28, 2023
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 @@ -43,10 +43,19 @@ default String instrumentationKey() {
return getSecret(this, "instrumentationKey").get();
}

/**
* default implementation to get the connection string from the config
* @return Connection String
*/
cbismuth marked this conversation as resolved.
Show resolved Hide resolved
default String connectionString() {
return getSecret(this, "connectionString").get();
}

@Override
default Validated<?> validate() {
return checkAll(this, c -> StepRegistryConfig.validate(c),
check("instrumentationKey", AzureMonitorConfig::instrumentationKey));
check("instrumentationKey", AzureMonitorConfig::instrumentationKey),
check("connectionString", AzureMonitorConfig::connectionString));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,18 @@ private AzureMonitorMeterRegistry(AzureMonitorConfig config, Clock clock,
super(config, clock);

config().namingConvention(new AzureMonitorNamingConvention());

if (StringUtils.isEmpty(telemetryConfiguration.getInstrumentationKey())) {
checkRequired("instrumentationKey", AzureMonitorConfig::instrumentationKey).apply(config).orThrow();
cbismuth marked this conversation as resolved.
Show resolved Hide resolved
telemetryConfiguration.setInstrumentationKey(config.instrumentationKey());
}

// Connection string overrides instrumentation key when present
if (StringUtils.isEmpty(telemetryConfiguration.getConnectionString())) {
checkRequired("connectionString", AzureMonitorConfig::connectionString).apply(config).orThrow();
telemetryConfiguration.setConnectionString(config.connectionString());
}

client = new TelemetryClient(telemetryConfiguration);
client.getContext().getInternal().setSdkVersion(SDK_VERSION);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2018 VMware, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micrometer.azuremonitor;

import java.util.Arrays;
import java.util.Objects;

public final class AzureMonitorUtils {

public static String extractInstrumentationKeyFromConnectionString(final String connectionString) {
shakuzen marked this conversation as resolved.
Show resolved Hide resolved
return Arrays.stream(connectionString.split(";"))
.filter(s -> Objects.equals("InstrumentationKey", s.split("=")[0]))
cbismuth marked this conversation as resolved.
Show resolved Hide resolved
.map(s -> s.split("=")[1])
.findFirst()
.orElse("");
}

private AzureMonitorUtils() {
// Utility class
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class AzureMonitorConfigTest {
@Test
void valid() {
props.put("azuremonitor.instrumentationKey", "secret");
props.put("azuremonitor.connectionString", "secret");

assertThat(config.validate().isValid()).isTrue();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public String instrumentationKey() {
return "fakeKey";
}

@Override
public String connectionString() {
return "InstrumentationKey=fakeKey";
}

@Override
public String get(String key) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ public String get(String key) {
public String instrumentationKey() {
return "myInstrumentationKey";
}

@Override
public String connectionString() {
return "InstrumentationKey=myInstrumentationKey";
}
};

private final MockClock clock = new MockClock();
Expand All @@ -56,9 +61,17 @@ public String instrumentationKey() {
@Test
void useTelemetryConfigInstrumentationKeyWhenSet() {
TelemetryConfiguration telemetryConfiguration = TelemetryConfiguration.createDefault();
telemetryConfiguration.setInstrumentationKey("fake");
telemetryConfiguration.setInstrumentationKey("myInstrumentationKey");
AzureMonitorMeterRegistry.builder(config).telemetryConfiguration(telemetryConfiguration).build();
assertThat(telemetryConfiguration.getInstrumentationKey()).isEqualTo("myInstrumentationKey");
Copy link
Member

Choose a reason for hiding this comment

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

This test is no longer effective because telemetryConfiguration.setInstrumentationKey is being set to the same value as the AzureMonitorConfig.instrumentationKey so the assertion can't know whether the value came from AzureMonitorConfig or telemetryConfiguration.setInstrumentationKey.

Same issue for the test useTelemetryConfigConnectionStringWhenSet

}

@Test
void useTelemetryConfigConnectionStringWhenSet() {
TelemetryConfiguration telemetryConfiguration = TelemetryConfiguration.createDefault();
telemetryConfiguration.setConnectionString("InstrumentationKey=myInstrumentationKey");
AzureMonitorMeterRegistry.builder(config).telemetryConfiguration(telemetryConfiguration).build();
assertThat(telemetryConfiguration.getInstrumentationKey()).isEqualTo("fake");
assertThat(telemetryConfiguration.getConnectionString()).isEqualTo("InstrumentationKey=myInstrumentationKey");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2018 VMware, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micrometer.azuremonitor;

import org.junit.jupiter.api.Test;

import java.util.UUID;

import static io.micrometer.azuremonitor.AzureMonitorUtils.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

class AzureMonitorUtilsTest {

@Test
void testExtractInstrumentationKeyFromConnectionString() {
final String expectedInstrumentationKey = UUID.randomUUID().toString();

final String connectionString = String.format(
"InstrumentationKey=%s;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/",
expectedInstrumentationKey);

final String actualInstrumentationKey = extractInstrumentationKeyFromConnectionString(connectionString);

assertThat(actualInstrumentationKey).isEqualTo(expectedInstrumentationKey);
}

@Test
void testExtractInstrumentationKeyFromConnectionString_missing() {
final String expectedInstrumentationKey = "";

final String connectionString = "IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/";

final String actualInstrumentationKey = extractInstrumentationKeyFromConnectionString(connectionString);

assertThat(actualInstrumentationKey).isEqualTo(expectedInstrumentationKey);
}

@Test
void testExtractInstrumentationKeyFromConnectionString_empty() {
final String expectedInstrumentationKey = "";

final String connectionString = "";

final String actualInstrumentationKey = extractInstrumentationKeyFromConnectionString(connectionString);

assertThat(actualInstrumentationKey).isEqualTo(expectedInstrumentationKey);
}

@Test
void testExtractInstrumentationKeyFromConnectionString_null() {
final String connectionString = null;

assertThrows(NullPointerException.class, () -> extractInstrumentationKeyFromConnectionString(connectionString));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public static void main(String[] args) {

@Bean
AzureMonitorMeterRegistry azureMonitorMeterRegistry(Environment environment) {
// will need an application property `azure.instrumentationKey` to be set
// will need an application property `azure.instrumentationKey` or
// `azure.connectionString` to be set
return AzureMonitorMeterRegistry.builder(environment::getProperty).build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.micrometer.atlas.AtlasMeterRegistry;
import io.micrometer.azuremonitor.AzureMonitorConfig;
import io.micrometer.azuremonitor.AzureMonitorMeterRegistry;
import io.micrometer.azuremonitor.AzureMonitorUtils;
import io.micrometer.common.lang.Nullable;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.MeterRegistry;
Expand Down Expand Up @@ -414,6 +415,35 @@ public String instrumentationKey() {
return apiKey;
}

@Override
public String connectionString() {
return String.format("InstrumentationKey=%s", apiKey);
}

@Override
public String get(String key) {
return null;
}

@Override
public Duration step() {
return Duration.ofSeconds(10);
}
}, Clock.SYSTEM);
}

public static AzureMonitorMeterRegistry azureWithConnectionString(String connectionString) {
return new AzureMonitorMeterRegistry(new AzureMonitorConfig() {
@Override
public String instrumentationKey() {
return AzureMonitorUtils.extractInstrumentationKeyFromConnectionString(connectionString);
}

@Override
public String connectionString() {
return connectionString;
}

@Override
public String get(String key) {
return null;
Expand Down