diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategy.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategy.java index 3ff063c45..b8ffe7d09 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategy.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategy.java @@ -1,9 +1,23 @@ +/* + * Copyright 2013-2016 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 + * + * 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 org.springframework.cloud.sleuth.instrument.hystrix; import java.util.concurrent.Callable; -import javax.annotation.PreDestroy; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.cloud.sleuth.Span; @@ -12,6 +26,10 @@ import org.springframework.cloud.sleuth.Tracer; import com.netflix.hystrix.strategy.HystrixPlugins; import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; +import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; +import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; +import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher; +import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy; /** * A {@link HystrixConcurrencyStrategy} that wraps a {@link Callable} in a @@ -28,31 +46,53 @@ public class SleuthHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy private final Tracer tracer; private final TraceKeys traceKeys; + private HystrixConcurrencyStrategy delegate; public SleuthHystrixConcurrencyStrategy(Tracer tracer, TraceKeys traceKeys) { this.tracer = tracer; this.traceKeys = traceKeys; try { + this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy(); + HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins + .getInstance().getCommandExecutionHook(); + HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance() + .getEventNotifier(); + HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance() + .getMetricsPublisher(); + HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance() + .getPropertiesStrategy(); + logCurrentStateOfHysrixPlugins(eventNotifier, metricsPublisher, + propertiesStrategy); + HystrixPlugins.reset(); HystrixPlugins.getInstance().registerConcurrencyStrategy(this); + HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook); + HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); + HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher); + HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); } catch (Exception e) { - HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance() - .getConcurrencyStrategy(); - log.debug( - "Failed to register Sleuth Hystrix Concurrency Strategy. Will use the current one which is [" - + concurrencyStrategy + "]", - e); + log.error( + "Failed to register Sleuth Hystrix Concurrency Strategy", e); } } - @PreDestroy - public void close() { - HystrixPlugins.reset(); + private void logCurrentStateOfHysrixPlugins(HystrixEventNotifier eventNotifier, + HystrixMetricsPublisher metricsPublisher, + HystrixPropertiesStrategy propertiesStrategy) { + log.info("Current Hystrix plugins configuration is [" + + "concurrencyStrategy [" + this.delegate + "]," + + "eventNotifier [" + eventNotifier + "]," + + "metricPublisher [" + metricsPublisher + "]," + + "propertiesStrategy [" + propertiesStrategy + "]," + + "]"); + log.info("Resetting Hystrix custom strategies and registering Sleuth Hystrix Concurrency Strategy."); } @Override public Callable wrapCallable(Callable callable) { - return new HystrixTraceCallable(this.tracer, this.traceKeys, callable); + Callable wrappedCallable = this.delegate != null ? + this.delegate.wrapCallable(callable) : callable; + return new HystrixTraceCallable<>(this.tracer, this.traceKeys, wrappedCallable); } private static class HystrixTraceCallable implements Callable { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/HystrixAnnotationsIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/HystrixAnnotationsIntegrationTests.java index e60a2518a..d0e56b138 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/HystrixAnnotationsIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/HystrixAnnotationsIntegrationTests.java @@ -1,13 +1,24 @@ +/* + * Copyright 2013-2016 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 + * + * 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 org.springframework.cloud.sleuth.instrument.hystrix; import java.util.concurrent.atomic.AtomicReference; -import com.jayway.awaitility.Awaitility; -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import com.netflix.hystrix.strategy.HystrixPlugins; import org.junit.After; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -24,6 +35,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import com.jayway.awaitility.Awaitility; +import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; + import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; @@ -33,16 +47,8 @@ import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; @DirtiesContext public class HystrixAnnotationsIntegrationTests { - @Autowired - HystrixCommandInvocationSpanCatcher catcher; - @Autowired - Tracer tracer; - - @BeforeClass - @AfterClass - public static void reset() { - HystrixPlugins.reset(); - } + @Autowired HystrixCommandInvocationSpanCatcher catcher; + @Autowired Tracer tracer; @After public void cleanTrace() { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java index 909b61d81..02b89ae97 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2013-2016 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 + * + * 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 org.springframework.cloud.sleuth.instrument.hystrix; import java.util.Random; @@ -20,7 +36,6 @@ import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.HystrixThreadPoolProperties; -import com.netflix.hystrix.strategy.HystrixPlugins; import static com.netflix.hystrix.HystrixCommand.Setter.withGroupKey; import static com.netflix.hystrix.HystrixCommandGroupKey.Factory.asKey; @@ -35,7 +50,6 @@ public class TraceCommandTests { @Before public void setup() { - HystrixPlugins.reset(); TestSpanContextHolder.removeCurrentSpan(); }