Use spring.application.name for OTel service.name when not set
Closes gh-37285
This commit is contained in:
@@ -32,6 +32,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to OTLP.
|
||||
@@ -49,20 +50,11 @@ import org.springframework.context.annotation.Bean;
|
||||
@EnableConfigurationProperties({ OtlpProperties.class, OpenTelemetryProperties.class })
|
||||
public class OtlpMetricsExportAutoConfiguration {
|
||||
|
||||
private final OtlpProperties properties;
|
||||
|
||||
private final OpenTelemetryProperties openTelemetryProperties;
|
||||
|
||||
public OtlpMetricsExportAutoConfiguration(OtlpProperties properties,
|
||||
OpenTelemetryProperties openTelemetryProperties) {
|
||||
this.properties = properties;
|
||||
this.openTelemetryProperties = openTelemetryProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public OtlpConfig otlpConfig() {
|
||||
return new OtlpPropertiesConfigAdapter(this.properties, this.openTelemetryProperties);
|
||||
OtlpConfig otlpConfig(OtlpProperties properties, OpenTelemetryProperties openTelemetryProperties,
|
||||
Environment environment) {
|
||||
return new OtlpPropertiesConfigAdapter(properties, openTelemetryProperties, environment);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -24,6 +26,7 @@ import io.micrometer.registry.otlp.OtlpConfig;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter;
|
||||
import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryProperties;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
@@ -35,11 +38,20 @@ import org.springframework.util.CollectionUtils;
|
||||
*/
|
||||
class OtlpPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter<OtlpProperties> implements OtlpConfig {
|
||||
|
||||
/**
|
||||
* Default value for application name if {@code spring.application.name} is not set.
|
||||
*/
|
||||
private static final String DEFAULT_APPLICATION_NAME = "application";
|
||||
|
||||
private final OpenTelemetryProperties openTelemetryProperties;
|
||||
|
||||
OtlpPropertiesConfigAdapter(OtlpProperties properties, OpenTelemetryProperties openTelemetryProperties) {
|
||||
private final Environment environment;
|
||||
|
||||
OtlpPropertiesConfigAdapter(OtlpProperties properties, OpenTelemetryProperties openTelemetryProperties,
|
||||
Environment environment) {
|
||||
super(properties);
|
||||
this.openTelemetryProperties = openTelemetryProperties;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,10 +72,16 @@ class OtlpPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter<Ot
|
||||
@Override
|
||||
@SuppressWarnings("removal")
|
||||
public Map<String, String> resourceAttributes() {
|
||||
Map<String, String> result;
|
||||
if (!CollectionUtils.isEmpty(this.openTelemetryProperties.getResourceAttributes())) {
|
||||
return this.openTelemetryProperties.getResourceAttributes();
|
||||
result = new HashMap<>(this.openTelemetryProperties.getResourceAttributes());
|
||||
}
|
||||
return get(OtlpProperties::getResourceAttributes, OtlpConfig.super::resourceAttributes);
|
||||
else {
|
||||
result = new HashMap<>(get(OtlpProperties::getResourceAttributes, OtlpConfig.super::resourceAttributes));
|
||||
}
|
||||
result.computeIfAbsent("service.name",
|
||||
(ignore) -> this.environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME));
|
||||
return Collections.unmodifiableMap(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryProperties;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
@@ -41,10 +42,13 @@ class OtlpPropertiesConfigAdapterTests {
|
||||
|
||||
private OpenTelemetryProperties openTelemetryProperties;
|
||||
|
||||
private MockEnvironment environment;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.properties = new OtlpProperties();
|
||||
this.openTelemetryProperties = new OpenTelemetryProperties();
|
||||
this.environment = new MockEnvironment();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,7 +97,8 @@ class OtlpPropertiesConfigAdapterTests {
|
||||
void openTelemetryPropertiesShouldOverrideOtlpPropertiesIfNotEmpty() {
|
||||
this.properties.setResourceAttributes(Map.of("a", "alpha"));
|
||||
this.openTelemetryProperties.setResourceAttributes(Map.of("b", "beta"));
|
||||
assertThat(createAdapter().resourceAttributes()).containsExactly(entry("b", "beta"));
|
||||
assertThat(createAdapter().resourceAttributes()).contains(entry("b", "beta"));
|
||||
assertThat(createAdapter().resourceAttributes()).doesNotContain(entry("a", "alpha"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -101,11 +106,37 @@ class OtlpPropertiesConfigAdapterTests {
|
||||
void openTelemetryPropertiesShouldNotOverrideOtlpPropertiesIfEmpty() {
|
||||
this.properties.setResourceAttributes(Map.of("a", "alpha"));
|
||||
this.openTelemetryProperties.setResourceAttributes(Collections.emptyMap());
|
||||
assertThat(createAdapter().resourceAttributes()).containsExactly(entry("a", "alpha"));
|
||||
assertThat(createAdapter().resourceAttributes()).contains(entry("a", "alpha"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("removal")
|
||||
void serviceNameOverridesApplicationName() {
|
||||
this.environment.setProperty("spring.application.name", "alpha");
|
||||
this.properties.setResourceAttributes(Map.of("service.name", "beta"));
|
||||
assertThat(createAdapter().resourceAttributes()).containsEntry("service.name", "beta");
|
||||
}
|
||||
|
||||
@Test
|
||||
void serviceNameOverridesApplicationNameWhenUsingOtelProperties() {
|
||||
this.environment.setProperty("spring.application.name", "alpha");
|
||||
this.openTelemetryProperties.setResourceAttributes(Map.of("service.name", "beta"));
|
||||
assertThat(createAdapter().resourceAttributes()).containsEntry("service.name", "beta");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUseApplicationNameIfServiceNameIsNotSet() {
|
||||
this.environment.setProperty("spring.application.name", "alpha");
|
||||
assertThat(createAdapter().resourceAttributes()).containsEntry("service.name", "alpha");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUseDefaultApplicationNameIfApplicationNameIsNotSet() {
|
||||
assertThat(createAdapter().resourceAttributes()).containsEntry("service.name", "application");
|
||||
}
|
||||
|
||||
private OtlpPropertiesConfigAdapter createAdapter() {
|
||||
return new OtlpPropertiesConfigAdapter(this.properties, this.openTelemetryProperties);
|
||||
return new OtlpPropertiesConfigAdapter(this.properties, this.openTelemetryProperties, this.environment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user