Skip to content

Commit fef5bb5

Browse files
committed
Merge pull request #44499 from thecooldrop
* pr/44499: Polish "Add support for OpenTelemetry's service.namespace" Add support for OpenTelemetry's service.namespace Closes gh-44499
2 parents d5f8008 + 7fd29cf commit fef5bb5

File tree

3 files changed

+74
-9
lines changed

3 files changed

+74
-9
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryResourceAttributes.java

+14-3
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public OpenTelemetryResourceAttributes(Environment environment, Map<String, Stri
8686
* <p>
8787
* Additionally, {@code spring.application.name} or {@code unknown_service} will be
8888
* used as the default for {@code service.name}, and {@code spring.application.group}
89-
* will serve as the default for {@code service.group}.
89+
* will serve as the default for {@code service.group} and {@code service.namespace}.
9090
* @param consumer the {@link BiConsumer} to apply
9191
*/
9292
public void applyTo(BiConsumer<String, String> consumer) {
@@ -97,20 +97,31 @@ public void applyTo(BiConsumer<String, String> consumer) {
9797
attributes.put(name, value);
9898
}
9999
});
100-
attributes.computeIfAbsent("service.name", (k) -> getApplicationName());
101-
attributes.computeIfAbsent("service.group", (k) -> getApplicationGroup());
100+
attributes.computeIfAbsent("service.name", (key) -> getApplicationName());
101+
attributes.computeIfAbsent("service.group", (key) -> getApplicationGroup());
102+
attributes.computeIfAbsent("service.namespace", (key) -> getServiceNamespace());
102103
attributes.forEach(consumer);
103104
}
104105

105106
private String getApplicationName() {
106107
return this.environment.getProperty("spring.application.name", DEFAULT_SERVICE_NAME);
107108
}
108109

110+
/**
111+
* Returns the application group.
112+
* @return the application group
113+
* @deprecated since 3.5.0 for removal in 3.7.0
114+
*/
115+
@Deprecated(since = "3.5.0", forRemoval = true)
109116
private String getApplicationGroup() {
110117
String applicationGroup = this.environment.getProperty("spring.application.group");
111118
return (StringUtils.hasLength(applicationGroup)) ? applicationGroup : null;
112119
}
113120

121+
private String getServiceNamespace() {
122+
return this.environment.getProperty("spring.application.group");
123+
}
124+
114125
/**
115126
* Parses resource attributes from the {@link System#getenv()}. This method fetches
116127
* attributes defined in the {@code OTEL_RESOURCE_ATTRIBUTES} and

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfigurationTests.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,23 @@ void shouldNotApplySpringApplicationGroupIfNotSet() {
106106
});
107107
}
108108

109+
@Test
110+
void shouldApplyServiceNamespaceIfApplicationGroupIsSet() {
111+
this.runner.withPropertyValues("spring.application.group=my-group").run((context) -> {
112+
Resource resource = context.getBean(Resource.class);
113+
assertThat(resource.getAttributes().asMap()).containsEntry(AttributeKey.stringKey("service.namespace"),
114+
"my-group");
115+
});
116+
}
117+
118+
@Test
119+
void shouldNotApplyServiceNamespaceIfApplicationGroupIsNotSet() {
120+
this.runner.run(((context) -> {
121+
Resource resource = context.getBean(Resource.class);
122+
assertThat(resource.getAttributes().asMap()).doesNotContainKey(AttributeKey.stringKey("service.namespace"));
123+
}));
124+
}
125+
109126
@Test
110127
void shouldFallbackToDefaultApplicationNameIfSpringApplicationNameIsNotSet() {
111128
this.runner.run((context) -> {
@@ -156,7 +173,7 @@ void shouldRegisterSdkMeterProviderIfAvailable() {
156173
}
157174

158175
@Configuration(proxyBeanMethods = false)
159-
private static final class UserConfiguration {
176+
static class UserConfiguration {
160177

161178
@Bean
162179
OpenTelemetry customOpenTelemetry() {

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryResourceAttributesTests.java

+42-5
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,10 @@ void unknownServiceShouldBeUsedAsDefaultServiceName() {
156156
@Test
157157
void springApplicationGroupNameShouldBeUsedAsDefaultServiceGroup() {
158158
this.environment.setProperty("spring.application.group", "spring-boot");
159-
assertThat(getAttributes()).hasSize(2)
159+
assertThat(getAttributes()).hasSize(3)
160160
.containsEntry("service.name", "unknown_service")
161-
.containsEntry("service.group", "spring-boot");
161+
.containsEntry("service.group", "spring-boot")
162+
.containsEntry("service.namespace", "spring-boot");
162163
}
163164

164165
@Test
@@ -167,6 +168,11 @@ void springApplicationNameShouldBeUsedAsDefaultServiceName() {
167168
assertThat(getAttributes()).hasSize(1).containsEntry("service.name", "spring-boot-app");
168169
}
169170

171+
@Test
172+
void serviceNamespaceShouldNotBePresentByDefault() {
173+
assertThat(getAttributes()).hasSize(1).doesNotContainKey("service.namespace");
174+
}
175+
170176
@Test
171177
void resourceAttributesShouldTakePrecedenceOverSpringApplicationName() {
172178
this.resourceAttributes.put("service.name", "spring-boot");
@@ -192,18 +198,49 @@ void otelServiceNameShouldTakePrecedenceOverSpringApplicationName() {
192198
void resourceAttributesShouldTakePrecedenceOverSpringApplicationGroupName() {
193199
this.resourceAttributes.put("service.group", "spring-boot-app");
194200
this.environment.setProperty("spring.application.group", "spring-boot");
195-
assertThat(getAttributes()).hasSize(2)
201+
assertThat(getAttributes()).hasSize(3)
196202
.containsEntry("service.name", "unknown_service")
197203
.containsEntry("service.group", "spring-boot-app");
198204
}
199205

206+
@Test
207+
void resourceAttributesShouldTakePrecedenceOverApplicationGroupNameForPopulatingServiceNamespace() {
208+
this.resourceAttributes.put("service.namespace", "spring-boot-app");
209+
this.environment.setProperty("spring.application.group", "overriden");
210+
assertThat(getAttributes()).hasSize(3)
211+
.containsEntry("service.name", "unknown_service")
212+
.containsEntry("service.group", "overriden")
213+
.containsEntry("service.namespace", "spring-boot-app");
214+
}
215+
200216
@Test
201217
void otelResourceAttributesShouldTakePrecedenceOverSpringApplicationGroupName() {
202218
this.environmentVariables.put("OTEL_RESOURCE_ATTRIBUTES", "service.group=spring-boot");
203219
this.environment.setProperty("spring.application.group", "spring-boot-app");
204-
assertThat(getAttributes()).hasSize(2)
220+
assertThat(getAttributes()).hasSize(3)
205221
.containsEntry("service.name", "unknown_service")
206-
.containsEntry("service.group", "spring-boot");
222+
.containsEntry("service.group", "spring-boot")
223+
.containsEntry("service.namespace", "spring-boot-app");
224+
}
225+
226+
@Test
227+
void otelResourceAttributesShouldTakePrecedenceOverSpringApplicationGroupNameForServiceNamespace() {
228+
this.environmentVariables.put("OTEL_RESOURCE_ATTRIBUTES", "service.namespace=spring-boot");
229+
this.environment.setProperty("spring.application.group", "overriden");
230+
assertThat(getAttributes()).hasSize(3)
231+
.containsEntry("service.group", "overriden")
232+
.containsEntry("service.namespace", "spring-boot");
233+
}
234+
235+
@Test
236+
void shouldUseServiceGroupForServiceNamespaceIfServiceGroupIsSet() {
237+
this.environment.setProperty("spring.application.group", "alpha");
238+
assertThat(getAttributes()).containsEntry("service.namespace", "alpha");
239+
}
240+
241+
@Test
242+
void shouldNotSetServiceNamespaceIfServiceGroupIsNotSet() {
243+
assertThat(getAttributes()).doesNotContainKey("service.namespace");
207244
}
208245

209246
private Map<String, String> getAttributes() {

0 commit comments

Comments
 (0)