Add support for reactor-tools debug agent
The `reactor-tools` dependency now brings a new Reactor Debug Agent which instruments loaded classes for better Reactor stacktraces. This commit removes the `spring.reactor.stacktrace-mode.enabled` configuration property since the related Reactor Hook is about to be removed. As a replacement, we're introducing `spring.reactor.debug-agent.enabled` which tells whether the Reactor Debug Agent should be loaded, given that the `reactor-tools` dependency is available. This option is enabled by default, since adding the dependency on classpath is a strong signal already. Fixes gh-17128
This commit is contained in:
@@ -76,6 +76,11 @@
|
||||
<artifactId>reactor-netty</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-tools</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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.boot.reactor;
|
||||
|
||||
import reactor.tools.agent.ReactorDebugAgent;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link EnvironmentPostProcessor} to enable the Reactor Debug Agent if available.
|
||||
* <p>
|
||||
* The debug agent is enabled by default, unless the
|
||||
* {@code "spring.reactor.debug-agent.enabled"} configuration property is set to false. We
|
||||
* are using here an {@link EnvironmentPostProcessor} instead of an auto-configuration
|
||||
* class to enable the agent as soon as possible during the startup process.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class DebugAgentEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
|
||||
|
||||
private static final String REACTOR_DEBUGAGENT_CLASS = "reactor.tools.agent.ReactorDebugAgent";
|
||||
|
||||
private static final String DEBUGAGENT_ENABLED_CONFIG_KEY = "spring.reactor.debug-agent.enabled";
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
if (ClassUtils.isPresent(REACTOR_DEBUGAGENT_CLASS, null)) {
|
||||
Boolean agentEnabled = environment.getProperty(DEBUGAGENT_ENABLED_CONFIG_KEY, Boolean.class);
|
||||
if (agentEnabled != Boolean.FALSE) {
|
||||
ReactorDebugAgent.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -719,6 +719,13 @@
|
||||
"sourceType": "org.springframework.boot.context.config.ConfigFileApplicationListener",
|
||||
"description": "Unconditionally activate the specified comma-separated list of profiles (or list of profiles if using YAML)."
|
||||
},
|
||||
{
|
||||
"name": "spring.reactor.debug-agent.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"sourceType": "org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor",
|
||||
"description": "Whether the Reactor Debug Agent should be enabled when reactor-tools is present.",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"name": "trace",
|
||||
"type": "java.lang.Boolean",
|
||||
|
||||
@@ -34,7 +34,8 @@ org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
|
||||
org.springframework.boot.env.EnvironmentPostProcessor=\
|
||||
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
|
||||
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
|
||||
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
|
||||
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\
|
||||
org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor
|
||||
|
||||
# Failure Analyzers
|
||||
org.springframework.boot.diagnostics.FailureAnalyzer=\
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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.boot.reactor;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.Scannable;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DebugAgentEnvironmentPostProcessor}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class DebugAgentEnvironmentPostProcessorTests {
|
||||
|
||||
static {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
DebugAgentEnvironmentPostProcessor postProcessor = new DebugAgentEnvironmentPostProcessor();
|
||||
postProcessor.postProcessEnvironment(environment, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void enablesReactorDebugAgent() {
|
||||
InstrumentedFluxProvider fluxProvider = new InstrumentedFluxProvider();
|
||||
Flux<Integer> flux = fluxProvider.newFluxJust();
|
||||
assertThat(Scannable.from(flux).stepName())
|
||||
.startsWith("Flux.just ⇢ at org.springframework.boot.reactor.InstrumentedFluxProvider.newFluxJust");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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.boot.reactor;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
/**
|
||||
* Utility class that should be instrumented by the reactor debug agent.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @see DebugAgentEnvironmentPostProcessorTests
|
||||
*/
|
||||
class InstrumentedFluxProvider {
|
||||
|
||||
Flux<Integer> newFluxJust() {
|
||||
return Flux.just(1);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user