Add @Withspan functionality using spring-aop (#902)
This commit is contained in:
parent
bbd63f7485
commit
1d80e19812
|
@ -13,19 +13,22 @@ dependencies {
|
||||||
implementation group: 'org.springframework.boot', name: 'spring-boot-autoconfigure', version: versions.springboot
|
implementation group: 'org.springframework.boot', name: 'spring-boot-autoconfigure', version: versions.springboot
|
||||||
annotationProcessor group: 'org.springframework.boot', name: 'spring-boot-autoconfigure-processor', version: versions.springboot
|
annotationProcessor group: 'org.springframework.boot', name: 'spring-boot-autoconfigure-processor', version: versions.springboot
|
||||||
implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
|
implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
|
||||||
|
|
||||||
|
compileOnly group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: versions.springboot
|
||||||
compileOnly group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: versions.springboot
|
compileOnly group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: versions.springboot
|
||||||
compileOnly group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: versions.springboot
|
compileOnly group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: versions.springboot
|
||||||
implementation project(':instrumentation-core:spring:spring-webmvc-3.1')
|
implementation project(':instrumentation-core:spring:spring-webmvc-3.1')
|
||||||
implementation project(':instrumentation-core:spring:spring-web-3.1')
|
implementation project(':instrumentation-core:spring:spring-web-3.1')
|
||||||
implementation project(':instrumentation-core:spring:spring-webflux-5.0')
|
implementation project(':instrumentation-core:spring:spring-webflux-5.0')
|
||||||
|
|
||||||
|
compileOnly deps.opentelemetryApiAutoAnnotations
|
||||||
compileOnly group: 'io.grpc', name: 'grpc-api', version: '1.30.2'
|
compileOnly group: 'io.grpc', name: 'grpc-api', version: '1.30.2'
|
||||||
compileOnly deps.opentelemetryLogging
|
compileOnly deps.opentelemetryLogging
|
||||||
compileOnly deps.opentelemetryJaeger
|
compileOnly deps.opentelemetryJaeger
|
||||||
compileOnly deps.opentelemetryOtlp
|
compileOnly deps.opentelemetryOtlp
|
||||||
compileOnly deps.opentelemetryZipkin
|
compileOnly deps.opentelemetryZipkin
|
||||||
|
|
||||||
|
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: versions.springboot
|
||||||
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: versions.springboot
|
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: versions.springboot
|
||||||
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: versions.springboot
|
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: versions.springboot
|
||||||
testImplementation(group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: versions.springboot) {
|
testImplementation(group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: versions.springboot) {
|
||||||
|
@ -33,6 +36,7 @@ dependencies {
|
||||||
}
|
}
|
||||||
|
|
||||||
testImplementation deps.opentelemetrySdk
|
testImplementation deps.opentelemetrySdk
|
||||||
|
testImplementation deps.opentelemetryApiAutoAnnotations
|
||||||
testImplementation group: 'io.grpc', name: 'grpc-api', version: '1.30.2'
|
testImplementation group: 'io.grpc', name: 'grpc-api', version: '1.30.2'
|
||||||
testImplementation group: 'io.grpc', name: 'grpc-netty-shaded', version: '1.30.2'
|
testImplementation group: 'io.grpc', name: 'grpc-netty-shaded', version: '1.30.2'
|
||||||
testImplementation deps.opentelemetryLogging
|
testImplementation deps.opentelemetryLogging
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.aspects;
|
||||||
|
|
||||||
|
import io.opentelemetry.extensions.auto.annotations.WithSpan;
|
||||||
|
import io.opentelemetry.trace.Tracer;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/** Configures {@link WithSpanAspect} to trace bean methods annotated with {@link WithSpan}. */
|
||||||
|
@Configuration
|
||||||
|
@EnableConfigurationProperties(TraceAspectProperties.class)
|
||||||
|
@ConditionalOnProperty(
|
||||||
|
prefix = "opentelemetry.trace.aspects",
|
||||||
|
name = "enabled",
|
||||||
|
matchIfMissing = true)
|
||||||
|
@ConditionalOnClass({Aspect.class, WithSpan.class})
|
||||||
|
public class TraceAspectAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public WithSpanAspect withSpanAspect(Tracer tracer) {
|
||||||
|
return new WithSpanAspect(tracer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.aspects;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/** Configuration for enabling tracing aspects. */
|
||||||
|
@ConfigurationProperties(prefix = "opentelemetry.trace.aspects")
|
||||||
|
public final class TraceAspectProperties {
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.aspects;
|
||||||
|
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
|
import io.opentelemetry.extensions.auto.annotations.WithSpan;
|
||||||
|
import io.opentelemetry.trace.Span;
|
||||||
|
import io.opentelemetry.trace.Status;
|
||||||
|
import io.opentelemetry.trace.Tracer;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses Spring-AOP to wrap methods marked by {@link WithSpan} in a {@link
|
||||||
|
* io.opentelemetry.trace.Span}.
|
||||||
|
*
|
||||||
|
* <p>Ensure methods annotated with {@link WithSpan} are implemented on beans managed by the Spring
|
||||||
|
* container.
|
||||||
|
*
|
||||||
|
* <p>Note: This Aspect uses spring-aop to proxy beans. Therefore the {@link WithSpan} annotation
|
||||||
|
* can not be applied to constructors.
|
||||||
|
*/
|
||||||
|
@Aspect
|
||||||
|
public class WithSpanAspect {
|
||||||
|
|
||||||
|
private final Tracer tracer;
|
||||||
|
|
||||||
|
public WithSpanAspect(Tracer tracer) {
|
||||||
|
this.tracer = tracer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Around("@annotation(io.opentelemetry.extensions.auto.annotations.WithSpan)")
|
||||||
|
public Object traceMethod(ProceedingJoinPoint pjp) throws Throwable {
|
||||||
|
MethodSignature signature = (MethodSignature) pjp.getSignature();
|
||||||
|
Method method = signature.getMethod();
|
||||||
|
WithSpan withSpan = method.getAnnotation(WithSpan.class);
|
||||||
|
|
||||||
|
Span span =
|
||||||
|
tracer.spanBuilder(getSpanName(withSpan, method)).setSpanKind(withSpan.kind()).startSpan();
|
||||||
|
try (Scope scope = tracer.withSpan(span)) {
|
||||||
|
return pjp.proceed();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
span.setStatus(Status.INTERNAL);
|
||||||
|
span.recordException(t);
|
||||||
|
throw t;
|
||||||
|
} finally {
|
||||||
|
span.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSpanName(WithSpan withSpan, Method method) {
|
||||||
|
String spanName = withSpan.value();
|
||||||
|
if (spanName.isEmpty()) {
|
||||||
|
return method.getDeclaringClass().getSimpleName() + "." + method.getName();
|
||||||
|
}
|
||||||
|
return spanName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,4 +6,5 @@ io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingS
|
||||||
io.opentelemetry.instrumentation.spring.autoconfigure.TracerAutoConfiguration,\
|
io.opentelemetry.instrumentation.spring.autoconfigure.TracerAutoConfiguration,\
|
||||||
io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.resttemplate.RestTemplateAutoConfiguration,\
|
io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.resttemplate.RestTemplateAutoConfiguration,\
|
||||||
io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.webclient.WebClientAutoConfiguration,\
|
io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.webclient.WebClientAutoConfiguration,\
|
||||||
io.opentelemetry.instrumentation.spring.autoconfigure.webmvc.WebMVCFilterAutoConfiguration
|
io.opentelemetry.instrumentation.spring.autoconfigure.webmvc.WebMVCFilterAutoConfiguration,\
|
||||||
|
io.opentelemetry.instrumentation.spring.autoconfigure.aspects.TraceAspectAutoConfiguration
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.aspects;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.spring.autoconfigure.TracerAutoConfiguration;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
|
||||||
|
/** Spring Boot auto configuration test for {@link TraceAspectAutoConfiguration} */
|
||||||
|
public class TraceAspectAutoConfigurationTest {
|
||||||
|
|
||||||
|
private final ApplicationContextRunner contextRunner =
|
||||||
|
new ApplicationContextRunner()
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(
|
||||||
|
TracerAutoConfiguration.class, TraceAspectAutoConfiguration.class));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("when aspects are ENABLED should initialize WithSpanAspect bean")
|
||||||
|
void aspectsEnabled() {
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues("opentelemetry.trace.aspects.enabled=true")
|
||||||
|
.run(
|
||||||
|
(context) -> {
|
||||||
|
assertThat(context.getBean("withSpanAspect", WithSpanAspect.class)).isNotNull();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("when aspects are DISABLED should NOT initialize WithSpanAspect bean")
|
||||||
|
void disabledProperty() {
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues("opentelemetry.trace.aspects.enabled=false")
|
||||||
|
.run(
|
||||||
|
(context) -> {
|
||||||
|
assertThat(context.containsBean("withSpanAspect")).isFalse();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("when aspects enabled property is MISSING should initialize WithSpanAspect bean")
|
||||||
|
void noProperty() {
|
||||||
|
this.contextRunner.run(
|
||||||
|
(context) -> {
|
||||||
|
assertThat(context.getBean("withSpanAspect", WithSpanAspect.class)).isNotNull();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.spring.autoconfigure.aspects;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.mockito.Mockito.any;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
|
import io.opentelemetry.extensions.auto.annotations.WithSpan;
|
||||||
|
import io.opentelemetry.trace.Span;
|
||||||
|
import io.opentelemetry.trace.Span.Kind;
|
||||||
|
import io.opentelemetry.trace.Tracer;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
|
||||||
|
|
||||||
|
/** Spring AOP Test for {@link WithSpanAspect} */
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class WithSpanAspectTest {
|
||||||
|
static class WithSpanTester {
|
||||||
|
@WithSpan
|
||||||
|
public String testWithSpan() {
|
||||||
|
return "Span with name testWithSpan was created";
|
||||||
|
}
|
||||||
|
|
||||||
|
@WithSpan("greatestSpanEver")
|
||||||
|
public String testWithSpanWithValue() {
|
||||||
|
return "Span with name greatestSpanEver was created";
|
||||||
|
}
|
||||||
|
|
||||||
|
@WithSpan(kind = Kind.CLIENT)
|
||||||
|
public String testWithSpanWithKind() {
|
||||||
|
return "Span with name testWithSpanWithKind and Kind.CLIENT was created";
|
||||||
|
}
|
||||||
|
|
||||||
|
@WithSpan
|
||||||
|
public String testWithSpanWithException() throws Exception {
|
||||||
|
throw new Exception("Test @WithSpan With Exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mock private Tracer tracer;
|
||||||
|
@Mock private Span span;
|
||||||
|
@Mock private Span.Builder spanBuilder;
|
||||||
|
@Mock private Scope scope;
|
||||||
|
@Mock private ProceedingJoinPoint pjp;
|
||||||
|
@Mock private MethodSignature signature;
|
||||||
|
|
||||||
|
private WithSpanTester withSpanTester;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
when(tracer.spanBuilder(any())).thenReturn(spanBuilder);
|
||||||
|
when(spanBuilder.setSpanKind(any())).thenReturn(spanBuilder);
|
||||||
|
when(spanBuilder.startSpan()).thenReturn(span);
|
||||||
|
when(tracer.withSpan(span)).thenReturn(scope);
|
||||||
|
|
||||||
|
AspectJProxyFactory factory = new AspectJProxyFactory(new WithSpanTester());
|
||||||
|
WithSpanAspect aspect = new WithSpanAspect(tracer);
|
||||||
|
factory.addAspect(aspect);
|
||||||
|
|
||||||
|
withSpanTester = factory.getProxy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("when method is annotated with @WithSpan should wrap method execution in a Span")
|
||||||
|
void withSpan() throws Throwable {
|
||||||
|
|
||||||
|
withSpanTester.testWithSpan();
|
||||||
|
|
||||||
|
verify(tracer, times(1)).spanBuilder("WithSpanTester.testWithSpan");
|
||||||
|
verify(spanBuilder, times(1)).startSpan();
|
||||||
|
verify(span, times(1)).end();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName(
|
||||||
|
"when @WithSpan value is set should wrap method execution in a Span with custom name")
|
||||||
|
void withSpanName() throws Throwable {
|
||||||
|
|
||||||
|
withSpanTester.testWithSpanWithValue();
|
||||||
|
|
||||||
|
verify(tracer, times(1)).spanBuilder("greatestSpanEver");
|
||||||
|
verify(spanBuilder, times(1)).startSpan();
|
||||||
|
verify(span, times(1)).end();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName(
|
||||||
|
"when method is annotated with @WithSpan AND an exception is thrown span should record the exception")
|
||||||
|
void withSpanError() throws Throwable {
|
||||||
|
|
||||||
|
assertThatThrownBy(
|
||||||
|
() -> {
|
||||||
|
withSpanTester.testWithSpanWithException();
|
||||||
|
})
|
||||||
|
.isInstanceOf(Exception.class);
|
||||||
|
|
||||||
|
verify(spanBuilder, times(1)).startSpan();
|
||||||
|
verify(span, times(1)).recordException(any(Exception.class));
|
||||||
|
verify(span, times(1)).end();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName(
|
||||||
|
"when method is annotated with @WithSpan AND Span.Kind is missing should set default Kind")
|
||||||
|
void withSpanDefaultKind() throws Throwable {
|
||||||
|
|
||||||
|
withSpanTester.testWithSpan();
|
||||||
|
|
||||||
|
verify(spanBuilder, times(1)).setSpanKind(Kind.INTERNAL);
|
||||||
|
verify(spanBuilder, times(1)).startSpan();
|
||||||
|
verify(span, times(1)).end();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName(
|
||||||
|
"when method is annotated with @WithSpan AND WithSpan.kind is set should build span with the declared Kind")
|
||||||
|
void withSpanClientKind() throws Throwable {
|
||||||
|
|
||||||
|
withSpanTester.testWithSpanWithKind();
|
||||||
|
|
||||||
|
verify(spanBuilder, times(1)).setSpanKind(Kind.CLIENT);
|
||||||
|
verify(spanBuilder, times(1)).startSpan();
|
||||||
|
verify(span, times(1)).end();
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,9 @@ sourceCompatibility = '8'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api group: "org.springframework.boot", name: "spring-boot-starter", version: versions.springboot
|
api group: "org.springframework.boot", name: "spring-boot-starter", version: versions.springboot
|
||||||
|
api group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: versions.springboot
|
||||||
api project(':instrumentation-core:spring:spring-boot-autoconfigure')
|
api project(':instrumentation-core:spring:spring-boot-autoconfigure')
|
||||||
|
api deps.opentelemetryApiAutoAnnotations
|
||||||
api deps.opentelemetryApi
|
api deps.opentelemetryApi
|
||||||
api deps.opentelemetryLogging
|
api deps.opentelemetryLogging
|
||||||
api deps.opentelemetrySdk
|
api deps.opentelemetrySdk
|
||||||
|
|
Loading…
Reference in New Issue