Spring Boot Starter service-name is constant (#5359)
* Spring Boot Starter service-name is constant Pattern-based resource configuration * Add ResourceProvider beans for spring with ConfigProperties
This commit is contained in:
parent
b85696b1a3
commit
c5f677e962
|
@ -392,6 +392,26 @@ If an exporter is present in the classpath during runtime and a spring bean of t
|
||||||
|
|
||||||
<!-- Slf4j Log Correlation otel.springboot.loggers.slf4j.enabled true org.slf4j.MDC -->
|
<!-- Slf4j Log Correlation otel.springboot.loggers.slf4j.enabled true org.slf4j.MDC -->
|
||||||
|
|
||||||
|
##### Resource Properties
|
||||||
|
|
||||||
|
| Feature | Property | Default Value |
|
||||||
|
|----------|--------------------------------------------------|------------------------|
|
||||||
|
| Resource | otel.springboot.resource.enabled | `true` |
|
||||||
|
| | otel.springboot.resource.attributes.service.name | `unknown_service:java` |
|
||||||
|
| | otel.springboot.resource.attributes | `empty map` |
|
||||||
|
|
||||||
|
`unknown_service:java` will be used as the service-name if no value has been specified to the
|
||||||
|
property `spring.application.name` or `otel.springboot.resource.attributes.service.name` (which has
|
||||||
|
the highest priority)
|
||||||
|
|
||||||
|
`otel.springboot.resource.attributes` supports a pattern-based resource configuration in the
|
||||||
|
application.properties like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
otel.springboot.resource.attributes.environment=dev
|
||||||
|
otel.springboot.resource.attributes.xyz=foo
|
||||||
|
```
|
||||||
|
|
||||||
##### Exporter Properties
|
##### Exporter Properties
|
||||||
|
|
||||||
| Feature | Property | Default Value |
|
| Feature | Property | Default Value |
|
||||||
|
|
|
@ -22,9 +22,11 @@ dependencies {
|
||||||
compileOnly("org.springframework.boot:spring-boot-starter-web:${versions["org.springframework.boot"]}")
|
compileOnly("org.springframework.boot:spring-boot-starter-web:${versions["org.springframework.boot"]}")
|
||||||
compileOnly("org.springframework.boot:spring-boot-starter-webflux:${versions["org.springframework.boot"]}")
|
compileOnly("org.springframework.boot:spring-boot-starter-webflux:${versions["org.springframework.boot"]}")
|
||||||
|
|
||||||
|
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi")
|
||||||
compileOnly("io.opentelemetry:opentelemetry-extension-annotations")
|
compileOnly("io.opentelemetry:opentelemetry-extension-annotations")
|
||||||
compileOnly("io.opentelemetry:opentelemetry-extension-trace-propagators")
|
compileOnly("io.opentelemetry:opentelemetry-extension-trace-propagators")
|
||||||
compileOnly("io.opentelemetry:opentelemetry-extension-aws")
|
compileOnly("io.opentelemetry:opentelemetry-extension-aws")
|
||||||
|
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-resources")
|
||||||
compileOnly("io.opentelemetry:opentelemetry-exporter-logging")
|
compileOnly("io.opentelemetry:opentelemetry-exporter-logging")
|
||||||
compileOnly("io.opentelemetry:opentelemetry-exporter-jaeger")
|
compileOnly("io.opentelemetry:opentelemetry-exporter-jaeger")
|
||||||
compileOnly("io.opentelemetry:opentelemetry-exporter-otlp")
|
compileOnly("io.opentelemetry:opentelemetry-exporter-otlp")
|
||||||
|
@ -40,6 +42,8 @@ dependencies {
|
||||||
testImplementation(project(":testing-common"))
|
testImplementation(project(":testing-common"))
|
||||||
testImplementation("io.opentelemetry:opentelemetry-sdk")
|
testImplementation("io.opentelemetry:opentelemetry-sdk")
|
||||||
testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
|
testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
|
||||||
|
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-resources")
|
||||||
|
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi")
|
||||||
testImplementation("io.opentelemetry:opentelemetry-extension-annotations")
|
testImplementation("io.opentelemetry:opentelemetry-extension-annotations")
|
||||||
testImplementation("io.opentelemetry:opentelemetry-extension-trace-propagators")
|
testImplementation("io.opentelemetry:opentelemetry-extension-trace-propagators")
|
||||||
testImplementation("io.opentelemetry:opentelemetry-extension-aws")
|
testImplementation("io.opentelemetry:opentelemetry-extension-aws")
|
||||||
|
|
|
@ -8,7 +8,11 @@ package io.opentelemetry.instrumentation.spring.autoconfigure;
|
||||||
import io.opentelemetry.api.OpenTelemetry;
|
import io.opentelemetry.api.OpenTelemetry;
|
||||||
import io.opentelemetry.api.trace.TracerProvider;
|
import io.opentelemetry.api.trace.TracerProvider;
|
||||||
import io.opentelemetry.context.propagation.ContextPropagators;
|
import io.opentelemetry.context.propagation.ContextPropagators;
|
||||||
|
import io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringResourceConfigProperties;
|
||||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||||
|
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||||
|
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
|
||||||
|
import io.opentelemetry.sdk.resources.Resource;
|
||||||
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
||||||
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
|
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
|
||||||
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
|
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
|
||||||
|
@ -21,6 +25,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create {@link io.opentelemetry.api.trace.Tracer} bean if bean is missing.
|
* Create {@link io.opentelemetry.api.trace.Tracer} bean if bean is missing.
|
||||||
|
@ -41,7 +47,8 @@ public class OpenTelemetryAutoConfiguration {
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public SdkTracerProvider sdkTracerProvider(
|
public SdkTracerProvider sdkTracerProvider(
|
||||||
SamplerProperties samplerProperties,
|
SamplerProperties samplerProperties,
|
||||||
ObjectProvider<List<SpanExporter>> spanExportersProvider) {
|
ObjectProvider<List<SpanExporter>> spanExportersProvider,
|
||||||
|
Resource otelResource) {
|
||||||
SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder();
|
SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder();
|
||||||
|
|
||||||
spanExportersProvider.getIfAvailable(Collections::emptyList).stream()
|
spanExportersProvider.getIfAvailable(Collections::emptyList).stream()
|
||||||
|
@ -49,10 +56,24 @@ public class OpenTelemetryAutoConfiguration {
|
||||||
.forEach(tracerProviderBuilder::addSpanProcessor);
|
.forEach(tracerProviderBuilder::addSpanProcessor);
|
||||||
|
|
||||||
return tracerProviderBuilder
|
return tracerProviderBuilder
|
||||||
|
.setResource(otelResource)
|
||||||
.setSampler(Sampler.traceIdRatioBased(samplerProperties.getProbability()))
|
.setSampler(Sampler.traceIdRatioBased(samplerProperties.getProbability()))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public Resource otelResource(
|
||||||
|
Environment env, ObjectProvider<List<ResourceProvider>> resourceProviders) {
|
||||||
|
ConfigProperties config = new SpringResourceConfigProperties(env, new SpelExpressionParser());
|
||||||
|
Resource resource = Resource.getDefault();
|
||||||
|
for (ResourceProvider resourceProvider :
|
||||||
|
resourceProviders.getIfAvailable(Collections::emptyList)) {
|
||||||
|
resource = resource.merge(resourceProvider.createResource(config));
|
||||||
|
}
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public OpenTelemetry openTelemetry(
|
public OpenTelemetry openTelemetry(
|
||||||
ObjectProvider<ContextPropagators> propagatorsProvider, SdkTracerProvider tracerProvider) {
|
ObjectProvider<ContextPropagators> propagatorsProvider, SdkTracerProvider tracerProvider) {
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.resources;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
|
||||||
|
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
|
||||||
|
import io.opentelemetry.sdk.extension.resources.ContainerResource;
|
||||||
|
import io.opentelemetry.sdk.extension.resources.ContainerResourceProvider;
|
||||||
|
import io.opentelemetry.sdk.extension.resources.HostResource;
|
||||||
|
import io.opentelemetry.sdk.extension.resources.HostResourceProvider;
|
||||||
|
import io.opentelemetry.sdk.extension.resources.OsResource;
|
||||||
|
import io.opentelemetry.sdk.extension.resources.OsResourceProvider;
|
||||||
|
import io.opentelemetry.sdk.extension.resources.ProcessResource;
|
||||||
|
import io.opentelemetry.sdk.extension.resources.ProcessResourceProvider;
|
||||||
|
import io.opentelemetry.sdk.extension.resources.ProcessRuntimeResource;
|
||||||
|
import io.opentelemetry.sdk.extension.resources.ProcessRuntimeResourceProvider;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableConfigurationProperties(OtelResourceProperties.class)
|
||||||
|
@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class)
|
||||||
|
@ConditionalOnProperty(prefix = "otel.springboot.resource", name = "enabled", matchIfMissing = true)
|
||||||
|
public class OtelResourceAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ResourceProvider otelResourceProvider(OtelResourceProperties otelResourceProperties) {
|
||||||
|
return new SpringResourceProvider(otelResourceProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnClass(OsResource.class)
|
||||||
|
public ResourceProvider otelOsResourceProvider() {
|
||||||
|
return new OsResourceProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnClass(ProcessResource.class)
|
||||||
|
public ResourceProvider otelProcessResourceProvider() {
|
||||||
|
return new ProcessResourceProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnClass(ProcessRuntimeResource.class)
|
||||||
|
public ResourceProvider otelProcessRuntimeResourceProvider() {
|
||||||
|
return new ProcessRuntimeResourceProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnClass(HostResource.class)
|
||||||
|
public ResourceProvider otelHostResourceProvider() {
|
||||||
|
return new HostResourceProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnClass(ContainerResource.class)
|
||||||
|
public ResourceProvider otelContainerResourceProvider() {
|
||||||
|
return new ContainerResourceProvider();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.resources;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "otel.springboot.resource")
|
||||||
|
public class OtelResourceProperties {
|
||||||
|
private Map<String, String> attributes = Collections.emptyMap();
|
||||||
|
|
||||||
|
public Map<String, String> getAttributes() {
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttributes(Map<String, String> attributes) {
|
||||||
|
this.attributes = attributes;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.resources;
|
||||||
|
|
||||||
|
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.expression.ExpressionParser;
|
||||||
|
|
||||||
|
public class SpringResourceConfigProperties implements ConfigProperties {
|
||||||
|
private final Environment environment;
|
||||||
|
|
||||||
|
private final ExpressionParser parser;
|
||||||
|
|
||||||
|
public SpringResourceConfigProperties(Environment environment, ExpressionParser parser) {
|
||||||
|
this.environment = environment;
|
||||||
|
this.parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getString(String name) {
|
||||||
|
return environment.getProperty(name, String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Boolean getBoolean(String name) {
|
||||||
|
return environment.getProperty(name, Boolean.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Integer getInt(String name) {
|
||||||
|
return environment.getProperty(name, Integer.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Long getLong(String name) {
|
||||||
|
return environment.getProperty(name, Long.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Double getDouble(String name) {
|
||||||
|
return environment.getProperty(name, Double.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Duration getDuration(String name) {
|
||||||
|
return environment.getProperty(name, Duration.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public List<String> getList(String name) {
|
||||||
|
return (List<String>) environment.getProperty(name, List.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getMap(String name) {
|
||||||
|
String value = environment.getProperty(name);
|
||||||
|
return (Map<String, String>) parser.parseExpression(Objects.requireNonNull(value)).getValue();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.resources;
|
||||||
|
|
||||||
|
import io.opentelemetry.api.common.Attributes;
|
||||||
|
import io.opentelemetry.api.common.AttributesBuilder;
|
||||||
|
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||||
|
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
|
||||||
|
import io.opentelemetry.sdk.resources.Resource;
|
||||||
|
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SpringResourceProvider implements ResourceProvider {
|
||||||
|
|
||||||
|
private final OtelResourceProperties otelResourceProperties;
|
||||||
|
|
||||||
|
public SpringResourceProvider(OtelResourceProperties otelResourceProperties) {
|
||||||
|
this.otelResourceProperties = otelResourceProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Resource createResource(ConfigProperties configProperties) {
|
||||||
|
String applicationName = configProperties.getString("spring.application.name");
|
||||||
|
Map<String, String> attributes = otelResourceProperties.getAttributes();
|
||||||
|
AttributesBuilder attributesBuilder = Attributes.builder();
|
||||||
|
attributes.forEach(attributesBuilder::put);
|
||||||
|
return defaultResource(applicationName).merge(Resource.create(attributesBuilder.build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Resource defaultResource(String applicationName) {
|
||||||
|
if (applicationName == null) {
|
||||||
|
return Resource.getDefault();
|
||||||
|
}
|
||||||
|
return Resource.getDefault()
|
||||||
|
.merge(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,4 +8,5 @@ io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfigura
|
||||||
io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.resttemplate.RestTemplateAutoConfiguration,\
|
io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.resttemplate.RestTemplateAutoConfiguration,\
|
||||||
io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.webclient.WebClientAutoConfiguration,\
|
io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.webclient.WebClientAutoConfiguration,\
|
||||||
io.opentelemetry.instrumentation.spring.autoconfigure.webmvc.WebMvcFilterAutoConfiguration,\
|
io.opentelemetry.instrumentation.spring.autoconfigure.webmvc.WebMvcFilterAutoConfiguration,\
|
||||||
io.opentelemetry.instrumentation.spring.autoconfigure.aspects.TraceAspectAutoConfiguration
|
io.opentelemetry.instrumentation.spring.autoconfigure.aspects.TraceAspectAutoConfiguration,\
|
||||||
|
io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration
|
||||||
|
|
|
@ -5,9 +5,13 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.spring.autoconfigure;
|
package io.opentelemetry.instrumentation.spring.autoconfigure;
|
||||||
|
|
||||||
|
import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.SERVICE_NAME;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
import io.opentelemetry.api.OpenTelemetry;
|
import io.opentelemetry.api.OpenTelemetry;
|
||||||
|
import io.opentelemetry.api.common.AttributeKey;
|
||||||
|
import io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration;
|
||||||
|
import io.opentelemetry.sdk.resources.Resource;
|
||||||
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -69,4 +73,76 @@ class OpenTelemetryAutoConfigurationTest {
|
||||||
.hasBean("customTracerProvider")
|
.hasBean("customTracerProvider")
|
||||||
.doesNotHaveBean("sdkTracerProvider"));
|
.doesNotHaveBean("sdkTracerProvider"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName(
|
||||||
|
"when spring.application.name is set value should be passed to service name attribute")
|
||||||
|
void shouldDetermineServiceNameBySpringApplicationName() {
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues("spring.application.name=myapp-backend")
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(
|
||||||
|
OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class))
|
||||||
|
.run(
|
||||||
|
context -> {
|
||||||
|
Resource otelResource = context.getBean("otelResource", Resource.class);
|
||||||
|
|
||||||
|
assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("myapp-backend");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName(
|
||||||
|
"when spring application name and otel service name are not set service name should be default")
|
||||||
|
void hasDefaultServiceName() {
|
||||||
|
this.contextRunner
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(
|
||||||
|
OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class))
|
||||||
|
.run(
|
||||||
|
context -> {
|
||||||
|
Resource otelResource = context.getBean("otelResource", Resource.class);
|
||||||
|
|
||||||
|
assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("unknown_service:java");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("when otel service name is set it should be set as service name attribute")
|
||||||
|
void shouldDetermineServiceNameByOtelServiceName() {
|
||||||
|
this.contextRunner
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(
|
||||||
|
OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class))
|
||||||
|
.withPropertyValues("otel.springboot.resource.attributes.service.name=otel-name-backend")
|
||||||
|
.run(
|
||||||
|
context -> {
|
||||||
|
Resource otelResource = context.getBean("otelResource", Resource.class);
|
||||||
|
|
||||||
|
assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("otel-name-backend");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("when otel attributes are set in properties they should be put in resource")
|
||||||
|
void shouldInitializeAttributes() {
|
||||||
|
this.contextRunner
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(
|
||||||
|
OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class))
|
||||||
|
.withPropertyValues(
|
||||||
|
"otel.springboot.resource.attributes.xyz=foo",
|
||||||
|
"otel.springboot.resource.attributes.environment=dev",
|
||||||
|
"otel.springboot.resource.attributes.service.instance.id=id-example")
|
||||||
|
.run(
|
||||||
|
context -> {
|
||||||
|
Resource otelResource = context.getBean("otelResource", Resource.class);
|
||||||
|
|
||||||
|
assertThat(otelResource.getAttribute(AttributeKey.stringKey("environment")))
|
||||||
|
.isEqualTo("dev");
|
||||||
|
assertThat(otelResource.getAttribute(AttributeKey.stringKey("xyz"))).isEqualTo("foo");
|
||||||
|
assertThat(otelResource.getAttribute(AttributeKey.stringKey("service.instance.id")))
|
||||||
|
.isEqualTo("id-example");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.resources;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
|
||||||
|
public class OtelResourceAutoConfigurationTest {
|
||||||
|
private final ApplicationContextRunner contextRunner =
|
||||||
|
new ApplicationContextRunner()
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(
|
||||||
|
OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName(
|
||||||
|
"when otel.springboot.resource.enabled is set to true configuration should be initialized")
|
||||||
|
void shouldDetermineServiceNameByOtelServiceName() {
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues("otel.springboot.resource.enabled=true")
|
||||||
|
.run(context -> assertThat(context.containsBean("otelResourceProvider")).isTrue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName(
|
||||||
|
"when otel.springboot.resource.enabled is not specified configuration should be initialized")
|
||||||
|
void shouldInitAutoConfigurationByDefault() {
|
||||||
|
this.contextRunner.run(
|
||||||
|
context -> assertThat(context.containsBean("otelResourceProvider")).isTrue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName(
|
||||||
|
"when otel.springboot.resource.enabled is set to false configuration should NOT be initialized")
|
||||||
|
void shouldNotInitAutoConfiguration() {
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues("otel.springboot.resource.enabled=false")
|
||||||
|
.run(context -> assertThat(context.containsBean("otelResourceProvider")).isFalse());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.resources;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.entry;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
|
||||||
|
public class OtelResourcePropertiesTest {
|
||||||
|
private final ApplicationContextRunner contextRunner =
|
||||||
|
new ApplicationContextRunner()
|
||||||
|
.withPropertyValues("otel.springboot.resource.enabled=true")
|
||||||
|
.withConfiguration(AutoConfigurations.of(OtelResourceAutoConfiguration.class));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("when attributes are SET should set OtelResourceProperties with given attributes")
|
||||||
|
void hasAttributes() {
|
||||||
|
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues(
|
||||||
|
"otel.springboot.resource.attributes.environment=dev",
|
||||||
|
"otel.springboot.resource.attributes.xyz=foo",
|
||||||
|
"otel.springboot.resource.attributes.service.name=backend-name",
|
||||||
|
"otel.springboot.resource.attributes.service.instance.id=id-example")
|
||||||
|
.run(
|
||||||
|
context -> {
|
||||||
|
OtelResourceProperties propertiesBean = context.getBean(OtelResourceProperties.class);
|
||||||
|
|
||||||
|
assertThat(propertiesBean.getAttributes())
|
||||||
|
.contains(
|
||||||
|
entry("environment", "dev"),
|
||||||
|
entry("xyz", "foo"),
|
||||||
|
entry("service.name", "backend-name"),
|
||||||
|
entry("service.instance.id", "id-example"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("when attributes are DEFAULT should set OtelResourceProperties to default values")
|
||||||
|
void hasDefaultTypes() {
|
||||||
|
|
||||||
|
this.contextRunner.run(
|
||||||
|
context ->
|
||||||
|
assertThat(context.getBean(OtelResourceProperties.class).getAttributes()).isEmpty());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.resources;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.entry;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
|
|
||||||
|
class SpringResourceConfigPropertiesTest {
|
||||||
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("when map is set in properties in a row it should be available in config")
|
||||||
|
void shouldInitializeAttributesByMapInArow() {
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues(
|
||||||
|
"otel.springboot.test.map={'environment':'dev','xyz':'foo','service.instance.id':'id-example'}")
|
||||||
|
.run(
|
||||||
|
context -> {
|
||||||
|
Environment env = context.getBean("environment", Environment.class);
|
||||||
|
SpringResourceConfigProperties config =
|
||||||
|
new SpringResourceConfigProperties(env, new SpelExpressionParser());
|
||||||
|
|
||||||
|
assertThat(config.getMap("otel.springboot.test.map"))
|
||||||
|
.contains(
|
||||||
|
entry("environment", "dev"),
|
||||||
|
entry("xyz", "foo"),
|
||||||
|
entry("service.instance.id", "id-example"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue