Skip to content

Commit 40056cf

Browse files
committed
detect service.name based on build-info.properties
1 parent d0763d9 commit 40056cf

File tree

6 files changed

+49
-55
lines changed

6 files changed

+49
-55
lines changed

instrumentation/spring/spring-boot-autoconfigure/README.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -445,13 +445,23 @@ export OTEL_RESOURCE_ATTRIBUTES="key1=value1,key2=value2"
445445
The service name is determined by the following precedence, in accordance with the OpenTelemetry
446446
[specification](https://opentelemetry.io/docs/concepts/sdk-configuration/general-sdk-configuration/#otel_service_name):
447447

448-
1. `otel.service.name` spring property or `OTEL_SERVICE_NAME` environment variable (highest
448+
1. `otel.service.name` spring property or `OTEL_SERVICE_NAME` environment variable (highest
449449
precedence)
450450
2. `service.name` in `otel.resource.attributes` system/spring property or `OTEL_RESOURCE_ATTRIBUTES`
451451
environment variable
452452
3. `service.name` in `otel.springboot.resource.attributes` system/spring property
453453
4. `spring.application.name` spring property
454-
5. the default value `unknown_service:java` (lowest precedence)
454+
5. `build-info.properties`
455+
6. the default value `unknown_service:java` (lowest precedence)
456+
457+
Use the following snippet in your gradle file to generate the `build-info.properties` file:
458+
459+
```groovy
460+
springBoot {
461+
buildInfo {
462+
}
463+
}
464+
```
455465

456466
##### Exporter Properties
457467

instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameDetector.java

+1-13
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import com.google.auto.service.AutoService;
1212
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
1313
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
14-
import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider;
1514
import io.opentelemetry.sdk.resources.Resource;
1615
import io.opentelemetry.semconv.ResourceAttributes;
1716
import java.io.IOException;
@@ -47,7 +46,7 @@
4746
* </ul>
4847
*/
4948
@AutoService(ResourceProvider.class)
50-
public class SpringBootServiceNameDetector implements ConditionalResourceProvider {
49+
public class SpringBootServiceNameDetector implements ResourceProvider {
5150

5251
private static final Logger logger =
5352
Logger.getLogger(SpringBootServiceNameDetector.class.getName());
@@ -101,17 +100,6 @@ public Resource createResource(ConfigProperties config) {
101100
.orElseGet(Resource::empty);
102101
}
103102

104-
@Override
105-
public boolean shouldApply(ConfigProperties config, Resource resource) {
106-
// we're skipping this provider if the service name was manually set by the user -- no need to
107-
// waste time trying to compute the service name if it's going to be overridden anyway
108-
String serviceName = config.getString("otel.service.name");
109-
Map<String, String> resourceAttributes = config.getMap("otel.resource.attributes");
110-
return serviceName == null
111-
&& !resourceAttributes.containsKey(ResourceAttributes.SERVICE_NAME.getKey())
112-
&& "unknown_service:java".equals(resource.getAttribute(ResourceAttributes.SERVICE_NAME));
113-
}
114-
115103
@Override
116104
public int order() {
117105
// make it run later than the default set of providers

instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceVersionDetector.java

+34-8
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,27 @@
1111
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
1212
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
1313
import io.opentelemetry.sdk.resources.Resource;
14+
import io.opentelemetry.sdk.resources.ResourceBuilder;
1415
import io.opentelemetry.semconv.ResourceAttributes;
1516
import java.io.IOException;
1617
import java.io.InputStream;
1718
import java.util.Optional;
1819
import java.util.Properties;
1920
import java.util.logging.Logger;
2021

22+
/**
23+
* Detects <code>service.name</code> and <code>service.version</code> from Spring Boot's <code>
24+
* build-info.properties</code> file.
25+
*
26+
* <p>Use the following snippet in your gradle file to generate the build-info.properties file:
27+
*
28+
* <pre>{@code
29+
* springBoot {
30+
* buildInfo {
31+
* }
32+
* }
33+
* }</pre>
34+
*/
2135
@AutoService(ResourceProvider.class)
2236
public class SpringBootServiceVersionDetector implements ResourceProvider {
2337

@@ -37,29 +51,41 @@ public SpringBootServiceVersionDetector() {
3751

3852
@Override
3953
public Resource createResource(ConfigProperties config) {
40-
return getServiceVersionFromBuildInfo()
54+
return getPropertiesFromBuildInfo()
4155
.map(
42-
version -> {
43-
logger.log(FINE, "Auto-detected Spring Boot service version: {0}", version);
44-
return Resource.builder().put(ResourceAttributes.SERVICE_VERSION, version).build();
56+
properties -> {
57+
logger.log(FINE, "Auto-detected Spring Boot service version: {0}", properties);
58+
ResourceBuilder builder = Resource.builder();
59+
60+
String version = properties.getProperty("build.version");
61+
if (version != null) {
62+
builder.put(ResourceAttributes.SERVICE_VERSION, version);
63+
}
64+
65+
String name = properties.getProperty("build.name");
66+
if (name != null) {
67+
builder.put(ResourceAttributes.SERVICE_NAME, name);
68+
}
69+
70+
return builder.build();
4571
})
4672
.orElseGet(Resource::empty);
4773
}
4874

49-
private Optional<String> getServiceVersionFromBuildInfo() {
75+
private Optional<Properties> getPropertiesFromBuildInfo() {
5076
try (InputStream in = system.openClasspathResource("META-INF", "build-info.properties")) {
51-
return in != null ? getServiceVersionPropertyFromStream(in) : Optional.empty();
77+
return in != null ? getPropertiesFromStream(in) : Optional.empty();
5278
} catch (Exception e) {
5379
return Optional.empty();
5480
}
5581
}
5682

57-
private static Optional<String> getServiceVersionPropertyFromStream(InputStream in) {
83+
private static Optional<Properties> getPropertiesFromStream(InputStream in) {
5884
Properties properties = new Properties();
5985
try {
6086
// Note: load() uses ISO 8859-1 encoding, same as spring uses by default for property files
6187
properties.load(in);
62-
return Optional.ofNullable(properties.getProperty("build.version"));
88+
return Optional.of(properties);
6389
} catch (IOException e) {
6490
return Optional.empty();
6591
}

instrumentation/spring/spring-boot-resources/library/src/test/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameDetectorTest.java

-31
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77

88
import static io.opentelemetry.semconv.ResourceAttributes.SERVICE_NAME;
99
import static java.nio.charset.StandardCharsets.UTF_8;
10-
import static java.util.Collections.singletonMap;
1110
import static org.assertj.core.api.Assertions.assertThat;
1211
import static org.mockito.Mockito.when;
1312

14-
import io.opentelemetry.api.common.Attributes;
1513
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
1614
import io.opentelemetry.sdk.resources.Resource;
1715
import java.io.InputStream;
@@ -163,35 +161,6 @@ void getFromCommandlineArgsWithSystemProperty() {
163161
expectServiceName(result, "bullpen");
164162
}
165163

166-
@Test
167-
void shouldApply() {
168-
SpringBootServiceNameDetector guesser = new SpringBootServiceNameDetector(system);
169-
assertThat(guesser.shouldApply(config, Resource.getDefault())).isTrue();
170-
}
171-
172-
@Test
173-
void shouldNotApplyWhenResourceHasServiceName() {
174-
SpringBootServiceNameDetector guesser = new SpringBootServiceNameDetector(system);
175-
Resource resource =
176-
Resource.getDefault().merge(Resource.create(Attributes.of(SERVICE_NAME, "test-service")));
177-
assertThat(guesser.shouldApply(config, resource)).isFalse();
178-
}
179-
180-
@Test
181-
void shouldNotApplyIfConfigHasServiceName() {
182-
SpringBootServiceNameDetector guesser = new SpringBootServiceNameDetector(system);
183-
when(config.getString("otel.service.name")).thenReturn("test-service");
184-
assertThat(guesser.shouldApply(config, Resource.getDefault())).isFalse();
185-
}
186-
187-
@Test
188-
void shouldNotApplyIfConfigHasServiceNameResourceAttribute() {
189-
SpringBootServiceNameDetector guesser = new SpringBootServiceNameDetector(system);
190-
when(config.getMap("otel.resource.attributes"))
191-
.thenReturn(singletonMap(SERVICE_NAME.getKey(), "test-service"));
192-
assertThat(guesser.shouldApply(config, Resource.getDefault())).isFalse();
193-
}
194-
195164
private static void expectServiceName(Resource result, String expected) {
196165
assertThat(result.getAttribute(SERVICE_NAME)).isEqualTo(expected);
197166
}

instrumentation/spring/spring-boot-resources/library/src/test/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceVersionDetectorTest.java

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.instrumentation.spring.resources;
77

8+
import static io.opentelemetry.semconv.ResourceAttributes.SERVICE_NAME;
89
import static io.opentelemetry.semconv.ResourceAttributes.SERVICE_VERSION;
910
import static org.assertj.core.api.Assertions.assertThat;
1011
import static org.mockito.Mockito.when;
@@ -34,6 +35,7 @@ void givenBuildVersionIsPresentInBuildInfProperties_thenReturnBuildVersion() {
3435
SpringBootServiceVersionDetector guesser = new SpringBootServiceVersionDetector(system);
3536
Resource result = guesser.createResource(config);
3637
assertThat(result.getAttribute(SERVICE_VERSION)).isEqualTo("0.0.2");
38+
assertThat(result.getAttribute(SERVICE_NAME)).isEqualTo("some-name");
3739
}
3840

3941
@Test
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
build.artifact=something
2-
build.name=some-name

0 commit comments

Comments
 (0)