diff --git a/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameGuesser.java b/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameGuesser.java index 8947e1bb12a3..1f26b2c85e99 100644 --- a/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameGuesser.java +++ b/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameGuesser.java @@ -8,6 +8,7 @@ import com.google.auto.service.AutoService; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.semconv.resource.attributes.ResourceAttributes; import java.io.IOException; @@ -47,7 +48,7 @@ * */ @AutoService(ResourceProvider.class) -public class SpringBootServiceNameGuesser implements ResourceProvider { +public class SpringBootServiceNameGuesser implements ConditionalResourceProvider { private static final Logger logger = Logger.getLogger(SpringBootServiceNameGuesser.class.getName()); @@ -95,6 +96,23 @@ public Resource createResource(ConfigProperties config) { .orElseGet(Resource::empty); } + @Override + public boolean shouldApply(ConfigProperties config, Resource resource) { + // we're skipping this provider if the service name was manually set by the user -- no need to + // waste time trying to compute the service name if it's going to be overridden anyway + String serviceName = config.getString("otel.service.name"); + Map resourceAttributes = config.getMap("otel.resource.attributes"); + return serviceName == null + && !resourceAttributes.containsKey(ResourceAttributes.SERVICE_NAME.getKey()) + && "unknown_service:java".equals(resource.getAttribute(ResourceAttributes.SERVICE_NAME)); + } + + @Override + public int order() { + // make it run later than the default set of providers + return 100; + } + @Nullable private String findByEnvironmentVariable() { String result = system.getenv("SPRING_APPLICATION_NAME"); diff --git a/instrumentation/spring/spring-boot-resources/library/src/test/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameGuesserTest.java b/instrumentation/spring/spring-boot-resources/library/src/test/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameGuesserTest.java index 241af2fb532e..e91485579330 100644 --- a/instrumentation/spring/spring-boot-resources/library/src/test/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameGuesserTest.java +++ b/instrumentation/spring/spring-boot-resources/library/src/test/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameGuesserTest.java @@ -7,9 +7,11 @@ import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.SERVICE_NAME; import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.resources.Resource; import java.io.OutputStream; @@ -111,6 +113,35 @@ void getFromCommandlineArgsWithSystemProperty() throws Exception { expectServiceName(result, "bullpen"); } + @Test + void shouldApply() { + SpringBootServiceNameGuesser guesser = new SpringBootServiceNameGuesser(system); + assertThat(guesser.shouldApply(config, Resource.getDefault())).isTrue(); + } + + @Test + void shouldNotApplyWhenResourceHasServiceName() { + SpringBootServiceNameGuesser guesser = new SpringBootServiceNameGuesser(system); + Resource resource = + Resource.getDefault().merge(Resource.create(Attributes.of(SERVICE_NAME, "test-service"))); + assertThat(guesser.shouldApply(config, resource)).isFalse(); + } + + @Test + void shouldNotApplyIfConfigHasServiceName() { + SpringBootServiceNameGuesser guesser = new SpringBootServiceNameGuesser(system); + when(config.getString("otel.service.name")).thenReturn("test-service"); + assertThat(guesser.shouldApply(config, Resource.getDefault())).isFalse(); + } + + @Test + void shouldNotApplyIfConfigHasServiceNameResourceAttribute() { + SpringBootServiceNameGuesser guesser = new SpringBootServiceNameGuesser(system); + when(config.getMap("otel.resource.attributes")) + .thenReturn(singletonMap(SERVICE_NAME.getKey(), "test-service")); + assertThat(guesser.shouldApply(config, Resource.getDefault())).isFalse(); + } + private static void expectServiceName(Resource result, String expected) { assertThat(result.getAttribute(SERVICE_NAME)).isEqualTo(expected); }