Merge branch '2.1.x'

This commit is contained in:
Marcin Grzejszczak
2019-10-30 13:11:39 +01:00
6 changed files with 192 additions and 12 deletions

View File

@@ -24,7 +24,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @author Marcin Grzejszczak
* @since 2.0.2
*/
@ConfigurationProperties("spring.sleuth.reactor.enabled")
@ConfigurationProperties("spring.sleuth.reactor")
public class SleuthReactorProperties {
/**
@@ -32,6 +32,14 @@ public class SleuthReactorProperties {
*/
private boolean enabled = true;
/**
* When true decorates on each operator, will be less performing, but logging will
* always contain the tracing entries in each operator. When false decorates on last
* operator, will be more performing, but logging might not always contain the tracing
* entries.
*/
private boolean decorateOnEach = true;
public boolean isEnabled() {
return this.enabled;
}
@@ -40,4 +48,12 @@ public class SleuthReactorProperties {
this.enabled = enabled;
}
public boolean isDecorateOnEach() {
return this.decorateOnEach;
}
public void setDecorateOnEach(boolean decorateOnEach) {
this.decorateOnEach = decorateOnEach;
}
}

View File

@@ -27,6 +27,7 @@ import reactor.core.scheduler.Schedulers;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
@@ -35,11 +36,18 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.scope.refresh.RefreshScope;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.cloud.sleuth.instrument.async.TraceableScheduledExecutorService;
import org.springframework.cloud.sleuth.instrument.web.TraceWebFluxAutoConfiguration;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
import static org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfiguration.TraceReactorConfiguration.SLEUTH_TRACE_REACTOR_KEY;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
@@ -53,6 +61,7 @@ import org.springframework.context.annotation.Configuration;
@ConditionalOnProperty(value = "spring.sleuth.reactor.enabled", matchIfMissing = true)
@ConditionalOnClass(Mono.class)
@AutoConfigureAfter(TraceWebFluxAutoConfiguration.class)
@EnableConfigurationProperties(SleuthReactorProperties.class)
public class TraceReactorAutoConfiguration {
static final String SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY = "sleuth";
@@ -66,6 +75,32 @@ public class TraceReactorAutoConfiguration {
private static final Log log = LogFactory.getLog(TraceReactorConfiguration.class);
@Autowired
BeanFactory beanFactory;
@PreDestroy
public void cleanupHooks() {
if (log.isTraceEnabled()) {
log.trace("Cleaning up hooks");
}
SleuthReactorProperties reactorProperties = this.beanFactory
.getBean(SleuthReactorProperties.class);
if (reactorProperties.isDecorateOnEach()) {
if (log.isTraceEnabled()) {
log.trace("Resetting onEach operator instrumentation");
}
Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY);
}
else {
if (log.isTraceEnabled()) {
log.trace("Resetting onLast operator instrumentation");
}
Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY);
}
Schedulers
.removeExecutorServiceDecorator(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY);
}
@Bean
// for tests
@ConditionalOnMissingBean
@@ -79,23 +114,67 @@ public class TraceReactorAutoConfiguration {
return new HookRegisteringBeanDefinitionRegistryPostProcessor(context);
}
@PreDestroy
public void cleanupHooks() {
if (log.isTraceEnabled()) {
log.trace("Cleaning up hooks");
@Configuration
@ConditionalOnClass(RefreshScope.class)
static class HooksRefresherConfiguration {
@Bean
HooksRefresher hooksRefresher(SleuthReactorProperties reactorProperties,
ConfigurableApplicationContext context) {
return new HooksRefresher(reactorProperties, context);
}
Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY);
Schedulers
.removeExecutorServiceDecorator(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY);
}
}
}
class HooksRefresher implements ApplicationListener<RefreshScopeRefreshedEvent> {
private static final Log log = LogFactory.getLog(HooksRefresher.class);
private final SleuthReactorProperties reactorProperties;
private final ConfigurableApplicationContext context;
HooksRefresher(SleuthReactorProperties reactorProperties,
ConfigurableApplicationContext context) {
this.reactorProperties = reactorProperties;
this.context = context;
}
@Override
public void onApplicationEvent(RefreshScopeRefreshedEvent event) {
if (log.isDebugEnabled()) {
log.debug("Context refreshed, will reset hooks and then re-register them");
}
Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY);
Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY);
if (this.reactorProperties.isDecorateOnEach()) {
if (log.isTraceEnabled()) {
log.trace("Decorating onEach operator instrumentation");
}
Hooks.onEachOperator(SLEUTH_TRACE_REACTOR_KEY,
ReactorSleuth.scopePassingSpanOperator(this.context));
}
else {
if (log.isTraceEnabled()) {
log.trace("Decorating onLast operator instrumentation");
}
Hooks.onLastOperator(SLEUTH_TRACE_REACTOR_KEY,
ReactorSleuth.scopePassingSpanOperator(this.context));
}
}
}
class HookRegisteringBeanDefinitionRegistryPostProcessor
implements BeanDefinitionRegistryPostProcessor {
private static final Log log = LogFactory
.getLog(HookRegisteringBeanDefinitionRegistryPostProcessor.class);
private final ConfigurableApplicationContext context;
HookRegisteringBeanDefinitionRegistryPostProcessor(
@@ -115,9 +194,23 @@ class HookRegisteringBeanDefinitionRegistryPostProcessor
}
void setupHooks(BeanFactory beanFactory) {
Hooks.onEachOperator(
TraceReactorAutoConfiguration.TraceReactorConfiguration.SLEUTH_TRACE_REACTOR_KEY,
ReactorSleuth.scopePassingSpanOperator(this.context));
ConfigurableEnvironment environment = this.context.getEnvironment();
boolean decorateOnEach = environment.getProperty(
"spring.sleuth.reactor.decorate-on-each", Boolean.class, true);
if (decorateOnEach) {
if (log.isTraceEnabled()) {
log.trace("Decorating onEach operator instrumentation");
}
Hooks.onEachOperator(SLEUTH_TRACE_REACTOR_KEY,
ReactorSleuth.scopePassingSpanOperator(this.context));
}
else {
if (log.isTraceEnabled()) {
log.trace("Decorating onLast operator instrumentation");
}
Hooks.onLastOperator(SLEUTH_TRACE_REACTOR_KEY,
ReactorSleuth.scopePassingSpanOperator(this.context));
}
Schedulers.setExecutorServiceDecorator(
TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY,
(scheduler,

View File

@@ -18,9 +18,14 @@ package org.springframework.cloud.sleuth.instrument.reactor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Hooks;
import reactor.core.scheduler.Schedulers;
import org.springframework.context.ConfigurableApplicationContext;
import static org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY;
import static org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfiguration.TraceReactorConfiguration.SLEUTH_TRACE_REACTOR_KEY;
/**
* @author Marcin Grzejszczak
*/
@@ -37,7 +42,9 @@ public final class TraceReactorAutoConfigurationAccessorConfiguration {
if (log.isTraceEnabled()) {
log.trace("Cleaning up hooks");
}
new TraceReactorAutoConfiguration.TraceReactorConfiguration().cleanupHooks();
Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY);
Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY);
Schedulers.removeExecutorServiceDecorator(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY);
}
public static void setup(ConfigurableApplicationContext context) {