Add spring-autoconfigure project
ADD
instrumentation-core/spring/spring-boot-autoconfigure/spring-boot-autoconfigure.gradle
+plugins {
+ id 'org.springframework.boot' version '2.3.0.RELEASE'
+ id 'io.spring.dependency-management' version '1.0.9.RELEASE'
+}
+
+ext {
+ minJavaVersionForTests = JavaVersion.VERSION_1_8
+}
+
+group = 'io.opentelemetry.instrumentation'
+
+apply from: "$rootDir/gradle/java.gradle"
+
+sourceCompatibility = '8'
+
+bootJar {
+ enabled = false
+}
+
+dependencies {
+ annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
+
+ testImplementation('org.springframework.boot:spring-boot-starter-test') {
+ exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
+ }
+
+ implementation 'org.springframework.boot:spring-boot-starter-web'
+ implementation project(':instrumentation-core:spring:spring-webmvc-3.1')
+ implementation project(':instrumentation-core:spring:spring-web-3.1')
+
+ implementation 'org.springframework.boot:spring-boot-starter-webflux'
+ implementation project(':instrumentation-core:spring:spring-webflux-5.0')
+
+ api deps.opentelemetryApi
+ api "io.opentelemetry:opentelemetry-exporters-logging:0.5.0"
+}
+
+test {
+ useJUnitPlatform()
+}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/EnableOpenTelemetryTracing.java
+/*
+ * 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;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+/** Auto-configures OpenTelemetry. Enables OpenTelementry Tracing in Spring applications */
+@Configuration
+@ComponentScan(basePackages = "io.opentelemetry.instrumentation.spring.autoconfigure")
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EnableOpenTelemetryTracing {}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/TracerAutoConfiguration.java
+/*
+ * 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;
+
+import io.opentelemetry.OpenTelemetry;
+import io.opentelemetry.exporters.logging.LoggingSpanExporter;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.sdk.trace.SpanProcessor;
+import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
+import io.opentelemetry.trace.Tracer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Create an {@link io.opentelemetry.trace.Tracer}.
+ *
+ * <p>If {@code TracerProperties.loggingExporterIsEnabled=True}: Create a simple span processor
+ * using the LoggingSpanExporter
+ */
+@Configuration
+@EnableConfigurationProperties(TracerProperties.class)
+public class TracerAutoConfiguration {
+
+ @Autowired TracerProperties tracerProperties;
+
+ @Bean
+ @ConditionalOnMissingBean
+ public Tracer otelTracer() throws Exception {
+ Tracer tracer = OpenTelemetry.getTracer(tracerProperties.getName());
+ setLoggingExporter();
+ return tracer;
+ }
+
+ private void setLoggingExporter() {
+ if (!tracerProperties.isLoggingExporterEnabled()) {
+ return;
+ }
+
+ SpanProcessor logProcessor = SimpleSpanProcessor.newBuilder(new LoggingSpanExporter()).build();
+ OpenTelemetrySdk.getTracerProvider().addSpanProcessor(logProcessor);
+ }
+}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/TracerProperties.java
+/*
+ * 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;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration for OpenTelemetry Tracer
+ *
+ * <p>Configures LoggingExporter and sets default tracer name
+ */
+@ConfigurationProperties(prefix = "opentelemetry.trace.tracer")
+public final class TracerProperties {
+
+ private String name = "otel-spring-tracer";
+ private boolean loggingExporterEnabled = true;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isLoggingExporterEnabled() {
+ return loggingExporterEnabled;
+ }
+
+ public void setLoggingExporterEnabled(boolean loggingExporterEnabled) {
+ this.loggingExporterEnabled = loggingExporterEnabled;
+ }
+}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/httpclients/HttpClientsProperties.java
+/*
+ * 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.httpclients;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration for the tracing instrumentation of HTTP clients.
+ *
+ * <p>Sets default value of opentelemetry.trace.httpclients.enabled to true if the configuration
+ * does not exist in application context.
+ */
+@ConfigurationProperties(prefix = "opentelemetry.trace.httpclients")
+public final class HttpClientsProperties {
+ private boolean enabled = true;
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/httpclients/resttemplate/RestTemplateAutoConfiguration.java
+/*
+ * 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.httpclients.resttemplate;
+
+import io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.HttpClientsProperties;
+import io.opentelemetry.trace.Tracer;
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * Configures {@link RestTemplate} for tracing.
+ *
+ * <p>Adds Open Telemetry instrumentation to {@link RestTemplate} upon initialization.
+ */
+@Configuration
+@ConditionalOnClass(RestTemplate.class)
+@EnableConfigurationProperties(HttpClientsProperties.class)
+@ConditionalOnProperty(
+ prefix = "opentelemetry.trace.httpclients",
+ name = "enabled",
+ matchIfMissing = true)
+public class RestTemplateAutoConfiguration {
+
+ @Bean
+ @Autowired
+ public RestTemplateBeanPostProcessor otelRestTemplateBeanPostProcessor(final Tracer tracer) {
+ return new RestTemplateBeanPostProcessor(tracer);
+ }
+}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/httpclients/resttemplate/RestTemplateBeanPostProcessor.java
+/*
+ * 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.httpclients.resttemplate;
+
+import io.opentelemetry.instrumentation.spring.httpclients.RestTemplateInterceptor;
+import io.opentelemetry.trace.Tracer;
+import java.util.List;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.web.client.RestTemplate;
+
+final class RestTemplateBeanPostProcessor implements BeanPostProcessor {
+
+ private final Tracer tracer;
+
+ public RestTemplateBeanPostProcessor(Tracer tracer) {
+ this.tracer = tracer;
+ }
+
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) {
+ if (!(bean instanceof RestTemplate)) {
+ return bean;
+ }
+
+ RestTemplate restTemplate = (RestTemplate) bean;
+ addRestTemplateInterceptorIfNotPresent(restTemplate);
+ return restTemplate;
+ }
+
+ private void addRestTemplateInterceptorIfNotPresent(RestTemplate restTemplate) {
+
+ List<ClientHttpRequestInterceptor> restTemplateInterceptors = restTemplate.getInterceptors();
+ if (restTemplateInterceptors.stream()
+ .noneMatch(inteceptor -> inteceptor instanceof RestTemplateInterceptor)) {
+ restTemplateInterceptors.add(0, new RestTemplateInterceptor(tracer));
+ }
+ }
+}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/httpclients/webclient/WebClientAutoConfiguration.java
+/*
+ * 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.httpclients.webclient;
+
+import io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.HttpClientsProperties;
+import io.opentelemetry.trace.Tracer;
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+import org.springframework.web.reactive.function.client.WebClient;
+
+/**
+ * Configures {@link WebClient} for tracing.
+ *
+ * <p>Adds Open Telemetry instrumentation to WebClient beans after initialization
+ */
+@Configuration
+@ConditionalOnClass(WebClient.class)
+@EnableConfigurationProperties(HttpClientsProperties.class)
+@ConditionalOnProperty(
+ prefix = "opentelemetry.trace.httpclients",
+ name = "enabled",
+ matchIfMissing = true)
+public class WebClientAutoConfiguration {
+
+ @Bean
+ @Autowired
+ public WebClientBeanPostProcessor otelWebClientBeanPostProcessor(final Tracer tracer) {
+ return new WebClientBeanPostProcessor(tracer);
+ }
+}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/httpclients/webclient/WebClientBeanPostProcessor.java
+/*
+ * 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.httpclients.webclient;
+
+import io.opentelemetry.instrumentation.springwebflux.client.WebClientTracingFilter;
+import io.opentelemetry.trace.Tracer;
+import java.util.List;
+import java.util.function.Consumer;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
+import org.springframework.web.reactive.function.client.WebClient;
+
+/**
+ * Inspired by: <a
+ * href="https://github.com/spring-cloud/spring-cloud-sleuth/blob/master/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java">Spring
+ * Cloud Sleuth</a>
+ */
+final class WebClientBeanPostProcessor implements BeanPostProcessor {
+
+ private final Tracer tracer;
+
+ WebClientBeanPostProcessor(Tracer tracer) {
+ this.tracer = tracer;
+ }
+
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) {
+ if (bean instanceof WebClient) {
+ WebClient webClient = (WebClient) bean;
+ return wrapBuilder(webClient.mutate()).build();
+ } else if (bean instanceof WebClient.Builder) {
+ WebClient.Builder webClientBuilder = (WebClient.Builder) bean;
+ return wrapBuilder(webClientBuilder);
+ }
+ return bean;
+ }
+
+ private WebClient.Builder wrapBuilder(WebClient.Builder webClientBuilder) {
+ return webClientBuilder.filters(webClientFilterFunctionConsumer());
+ }
+
+ private Consumer<List<ExchangeFilterFunction>> webClientFilterFunctionConsumer() {
+ return functions -> {
+ if (functions.stream().noneMatch(filter -> filter instanceof WebClientTracingFilter)) {
+ WebClientTracingFilter.addFilter(functions, tracer);
+ }
+ };
+ }
+}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/webmvc/WebMVCFilterAutoConfiguration.java
+/*
+ * 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.webmvc;
+
+import io.opentelemetry.instrumentation.springwebmvc.WebMVCTracingFilter;
+import io.opentelemetry.trace.Tracer;
+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 WebMVCFilter} for tracing. */
+@Configuration
+@EnableConfigurationProperties(WebMVCProperties.class)
+@ConditionalOnProperty(prefix = "opentelemetry.trace.web", name = "enabled", matchIfMissing = true)
+public class WebMVCFilterAutoConfiguration {
+
+ @Bean
+ public WebMVCTracingFilter otelWebMVCTracingFilter(final Tracer tracer) {
+ return new WebMVCTracingFilter(tracer);
+ }
+}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/webmvc/WebMVCProperties.java
+/*
+ * 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.webmvc;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration for the tracing instrumentation of Spring WebMVC
+ *
+ * <p>Sets default value of opentelemetry.trace.web.enabled to true if the configuration does not
+ * exist in application context
+ */
+@ConfigurationProperties(prefix = "opentelemetry.trace.web")
+public final class WebMVCProperties {
+ private boolean enabled = true;
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+}

ADD
instrumentation-core/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+io.opentelemetry.instrumentation.spring.autoconfigure.TracerAutoConfiguration,\
+io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.resttemplate.RestTemplateAutoConfiguration,\
+io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.webclient.WebClientAutoConfiguration,\
+io.opentelemetry.instrumentation.spring.autoconfigure.webmvc.WebMVCFilterAutoConfiguration

MODIFY
settings.gradle
settings.gradle
@@ -154,6 +154,7 @@ include ':instrumentation-core:apache-httpclient-4.0'
include ':instrumentation-core:aws-sdk:aws-sdk-2.2'
include ':instrumentation-core:reactor-3.1'
include ':instrumentation-core:servlet'
+include ':instrumentation-core:spring:spring-boot-autoconfigure'
include ':instrumentation-core:spring:spring-web-3.1'
include ':instrumentation-core:spring:spring-webflux-5.0'
include ':instrumentation-core:spring:spring-webmvc-3.1'

Add spring-autoconfigure project (#661)