diff --git a/docs/src/main/asciidoc/integrations.adoc b/docs/src/main/asciidoc/integrations.adoc index 3cc5a4d1f..84537d5ba 100644 --- a/docs/src/main/asciidoc/integrations.adoc +++ b/docs/src/main/asciidoc/integrations.adoc @@ -680,7 +680,7 @@ In order to disable this instrumentation set `spring.sleuth.task.enabled` to `fa This feature is available for all tracer implementations. -If you have Spring Tx on the classpath we will instrument the `PlatformTransactionManager` and the `ReactiveTransactionManager` to create a span whenever a new transaction is created. +If you have Spring Tx on the classpath we will instrument the `PlatformTransactionManager` and the `ReactiveTransactionManager` to create a span whenever a new transaction is created. Due to technical constraints we will not instrument classes that extend Spring's `AbstractPlatformTransactionManager`. In order to disable this instrumentation set `spring.sleuth.tx.enabled` to `false`. [[sleuth-security-integration]] diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/tx/PlatformTransactionManagerInstrumenter.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/tx/PlatformTransactionManagerInstrumenter.java index 99501217e..9577c8db7 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/tx/PlatformTransactionManagerInstrumenter.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/tx/PlatformTransactionManagerInstrumenter.java @@ -19,6 +19,7 @@ package org.springframework.cloud.sleuth.autoconfig.instrument.tx; import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.sleuth.instrument.tx.TracePlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.support.AbstractPlatformTransactionManager; class PlatformTransactionManagerInstrumenter extends AbstractTransactionManagerInstrumenter { @@ -27,6 +28,11 @@ class PlatformTransactionManagerInstrumenter super(beanFactory, PlatformTransactionManager.class); } + @Override + boolean isApplicableForInstrumentation(Object bean) { + return super.isApplicableForInstrumentation(bean) && !(bean instanceof AbstractPlatformTransactionManager); + } + @Override Class tracedClass() { return TracePlatformTransactionManager.class; diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/tx/PlatformTransactionManagerInstrumenterTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/tx/PlatformTransactionManagerInstrumenterTests.java new file mode 100644 index 000000000..49d38af29 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/tx/PlatformTransactionManagerInstrumenterTests.java @@ -0,0 +1,100 @@ +/* + * Copyright 2013-2021 the original author or 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 + * + * https://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 org.springframework.cloud.sleuth.autoconfig.instrument.tx; + +import org.junit.jupiter.api.Test; + +import org.springframework.context.support.StaticApplicationContext; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionException; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.AbstractPlatformTransactionManager; +import org.springframework.transaction.support.DefaultTransactionStatus; + +import static org.assertj.core.api.BDDAssertions.then; + +class PlatformTransactionManagerInstrumenterTests { + + @Test + void should_return_true_when_instruments_platform_transaction_manager() { + PlatformTransactionManagerInstrumenter instrumenter = new PlatformTransactionManagerInstrumenter( + new StaticApplicationContext()); + + then(instrumenter.isApplicableForInstrumentation(platformTransactionManager())).isTrue(); + } + + @Test + void should_return_false_when_instruments_abstract_platform_transaction_manager() { + PlatformTransactionManagerInstrumenter instrumenter = new PlatformTransactionManagerInstrumenter( + new StaticApplicationContext()); + + then(instrumenter.isApplicableForInstrumentation(abstractPlatformTransactionManager())).isFalse(); + } + + @Test + void should_return_false_when_instruments_non_platform_transaction_manager() { + PlatformTransactionManagerInstrumenter instrumenter = new PlatformTransactionManagerInstrumenter( + new StaticApplicationContext()); + + then(instrumenter.isApplicableForInstrumentation("not platform transaction manager")).isFalse(); + } + + private PlatformTransactionManager platformTransactionManager() { + return new PlatformTransactionManager() { + @Override + public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { + return null; + } + + @Override + public void commit(TransactionStatus status) throws TransactionException { + + } + + @Override + public void rollback(TransactionStatus status) throws TransactionException { + + } + }; + } + + private PlatformTransactionManager abstractPlatformTransactionManager() { + return new AbstractPlatformTransactionManager() { + @Override + protected Object doGetTransaction() throws TransactionException { + return null; + } + + @Override + protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { + + } + + @Override + protected void doCommit(DefaultTransactionStatus status) throws TransactionException { + + } + + @Override + protected void doRollback(DefaultTransactionStatus status) throws TransactionException { + + } + }; + } + +}