Skip to content

Commit 5457391

Browse files
add spring starter span logging (#14594)
Co-authored-by: otelbot <[email protected]>
1 parent 9375daf commit 5457391

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.logging;
7+
8+
import static java.util.Collections.emptyList;
9+
10+
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
11+
import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled;
12+
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
13+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
14+
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
15+
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
16+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
17+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
18+
import org.springframework.context.annotation.Bean;
19+
import org.springframework.context.annotation.Conditional;
20+
import org.springframework.context.annotation.Configuration;
21+
22+
/**
23+
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
24+
* any time.
25+
*/
26+
@Conditional(SdkEnabled.class)
27+
// to match "otel.javaagent.debug" system property
28+
@ConditionalOnProperty(name = "otel.spring-starter.debug", havingValue = "true")
29+
@ConditionalOnClass(LoggingSpanExporter.class)
30+
@Configuration
31+
public class LoggingExporterAutoConfiguration {
32+
33+
@Bean
34+
public AutoConfigurationCustomizerProvider loggingOtelCustomizer() {
35+
return p ->
36+
p.addTracerProviderCustomizer(
37+
(builder, config) -> {
38+
enableLoggingExporter(builder, config);
39+
return builder;
40+
});
41+
}
42+
43+
public static void enableLoggingExporter(
44+
SdkTracerProviderBuilder builder, ConfigProperties config) {
45+
// don't install another instance if the user has already explicitly requested it.
46+
if (loggingExporterIsNotAlreadyConfigured(config)) {
47+
builder.addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create()));
48+
}
49+
}
50+
51+
private static boolean loggingExporterIsNotAlreadyConfigured(ConfigProperties config) {
52+
return !config.getList("otel.traces.exporter", emptyList()).contains("logging");
53+
}
54+
}

instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,12 @@
295295
"type": "java.util.Map<java.lang.String, java.lang.String>",
296296
"description": "Used to specify a mapping from host names or IP addresses to peer services, as a comma-separated list of <code>host_or_ip=user_assigned_name</code> pairs. The peer service is added as an attribute to a span whose host or IP address match the mapping. See https://opentelemetry.io/docs/zero-code/java/agent/configuration/#peer-service-name."
297297
},
298+
{
299+
"name": "otel.instrumentation.common.thread-details.enabled",
300+
"type": "java.lang.Boolean",
301+
"description": "Enable the capture of thread details (thread id and thread name) as span attributes.",
302+
"defaultValue": false
303+
},
298304
{
299305
"name": "otel.instrumentation.http.client.capture-request-headers",
300306
"type": "java.util.List<java.lang.String>",
@@ -627,6 +633,12 @@
627633
"description": "The maximum number of links per span.",
628634
"defaultValue": 128
629635
},
636+
{
637+
"name": "otel.spring-starter.debug",
638+
"type": "java.lang.Boolean",
639+
"description": "Print spans to console for debugging purposes.",
640+
"defaultValue": false
641+
},
630642
{
631643
"name": "otel.traces.exporter",
632644
"type": "java.util.List<java.lang.String>",
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.logging;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
10+
import io.opentelemetry.api.OpenTelemetry;
11+
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
12+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
13+
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
14+
import java.util.Collections;
15+
import org.junit.jupiter.api.Test;
16+
import org.springframework.boot.autoconfigure.AutoConfigurations;
17+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
18+
19+
class LoggingExporterAutoConfigurationTest {
20+
private final ApplicationContextRunner runner =
21+
new ApplicationContextRunner()
22+
.withBean(
23+
ConfigProperties.class,
24+
() -> DefaultConfigProperties.createFromMap(Collections.emptyMap()))
25+
.withConfiguration(
26+
AutoConfigurations.of(
27+
LoggingExporterAutoConfiguration.class, OpenTelemetryAutoConfiguration.class));
28+
29+
@Test
30+
void debugEnabled() {
31+
runner
32+
.withPropertyValues("otel.spring-starter.debug=true", "otel.traces.exporter=none")
33+
.run(
34+
context ->
35+
assertThat(context.getBean(OpenTelemetry.class).toString())
36+
.containsOnlyOnce("LoggingSpanExporter"));
37+
}
38+
39+
@Test
40+
void alreadyAdded() {
41+
runner
42+
.withPropertyValues("otel.spring-starter.debug=true", "otel.traces.exporter=logging")
43+
.run(
44+
context ->
45+
assertThat(context.getBean(OpenTelemetry.class).toString())
46+
.containsOnlyOnce("LoggingSpanExporter"));
47+
}
48+
49+
@Test
50+
void debugUnset() {
51+
runner.run(
52+
context ->
53+
assertThat(context.getBean(OpenTelemetry.class).toString())
54+
.doesNotContain("LoggingSpanExporter"));
55+
}
56+
57+
@Test
58+
void debugDisabled() {
59+
runner
60+
.withPropertyValues("otel.spring-starter.debug=false", "otel.traces.exporter=none")
61+
.run(
62+
context ->
63+
assertThat(context.getBean(OpenTelemetry.class).toString())
64+
.doesNotContain("LoggingSpanExporter"));
65+
}
66+
}

0 commit comments

Comments
 (0)