Merge pull request #36155 from jonatan-ivanov

* pr/36155:
  Add missing OTel Span attributes

Closes gh-36155
This commit is contained in:
Stephane Nicoll 2023-07-17 15:04:24 +02:00
commit bbaac07d64
2 changed files with 82 additions and 1 deletions

View File

@ -97,9 +97,10 @@ public class OpenTelemetryAutoConfiguration {
SdkTracerProvider otelSdkTracerProvider(Environment environment, ObjectProvider<SpanProcessor> spanProcessors,
Sampler sampler) {
String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
Resource springResource = Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName));
SdkTracerProviderBuilder builder = SdkTracerProvider.builder()
.setSampler(sampler)
.setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName)));
.setResource(Resource.getDefault().merge(springResource));
spanProcessors.orderedStream().forEach(builder::addSpanProcessor);
return builder.build();
}

View File

@ -16,8 +16,14 @@
package org.springframework.boot.actuate.autoconfigure.tracing;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Stream;
import io.micrometer.tracing.SpanCustomizer;
@ -30,18 +36,26 @@ import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener;
import io.micrometer.tracing.otel.bridge.Slf4JEventListener;
import io.micrometer.tracing.otel.propagation.BaggageTextMapPropagator;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.extension.trace.propagation.B3Propagator;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.SpanProcessor;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@ -143,6 +157,26 @@ class OpenTelemetryAutoConfigurationTests {
});
}
@Test
void shouldSetupDefaultResourceAttributes() {
this.contextRunner
.withConfiguration(
AutoConfigurations.of(ObservationAutoConfiguration.class, MicrometerTracingAutoConfiguration.class))
.withUserConfiguration(InMemoryRecordingSpanExporterConfiguration.class)
.withPropertyValues("management.tracing.sampling.probability=1.0")
.run((context) -> {
context.getBean(io.micrometer.tracing.Tracer.class).nextSpan().name("test").end();
InMemoryRecordingSpanExporter exporter = context.getBean(InMemoryRecordingSpanExporter.class);
exporter.await(Duration.ofSeconds(10));
SpanData spanData = exporter.getExportedSpans().get(0);
Map<AttributeKey<?>, Object> expectedAttributes = Resource.getDefault()
.merge(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, "application")))
.getAttributes()
.asMap();
assertThat(spanData.getResource().getAttributes().asMap()).isEqualTo(expectedAttributes);
});
}
@Test
void shouldAllowMultipleSpanProcessors() {
this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
@ -297,4 +331,50 @@ class OpenTelemetryAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
private static class InMemoryRecordingSpanExporterConfiguration {
@Bean
InMemoryRecordingSpanExporter spanExporter() {
return new InMemoryRecordingSpanExporter();
}
}
private static class InMemoryRecordingSpanExporter implements SpanExporter {
private final List<SpanData> exportedSpans = new ArrayList<>();
private final CountDownLatch latch = new CountDownLatch(1);
@Override
public CompletableResultCode export(Collection<SpanData> spans) {
this.exportedSpans.addAll(spans);
this.latch.countDown();
return CompletableResultCode.ofSuccess();
}
@Override
public CompletableResultCode flush() {
return CompletableResultCode.ofSuccess();
}
@Override
public CompletableResultCode shutdown() {
this.exportedSpans.clear();
return CompletableResultCode.ofSuccess();
}
List<SpanData> getExportedSpans() {
return this.exportedSpans;
}
void await(Duration timeout) throws InterruptedException, TimeoutException {
if (!this.latch.await(timeout.toMillis(), TimeUnit.MILLISECONDS)) {
throw new TimeoutException("Waiting for exporting spans timed out (%s)".formatted(timeout));
}
}
}
}