Commit dfdee3e0 authored by Brian Clozel's avatar Brian Clozel

Revert "Add support for Reactor Netty Micrometer metrics"

This commit removes the support for Reactor Netty metrics since it
seems that Spring Boot should not use this feature:

* HTTP metrics are already covered by WebFlux
* TCP metrics are only meant to TCP server/clients
* allocator metrics are already provided by Netty and there is
no specific API to enable them here.

Closes gh-19388
parent fa01a159
/*
* Copyright 2012-2020 the original author or authors.
* 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.
......@@ -17,7 +17,6 @@
package org.springframework.boot.actuate.autoconfigure.metrics.web.client;
import io.micrometer.core.instrument.MeterRegistry;
import reactor.netty.http.client.HttpClient;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Client.ClientRequest;
......@@ -26,7 +25,6 @@ import org.springframework.boot.actuate.metrics.web.reactive.client.MetricsWebCl
import org.springframework.boot.actuate.metrics.web.reactive.client.WebClientExchangeTagsProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.web.reactive.function.client.ReactorNettyHttpClientMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
......@@ -55,14 +53,4 @@ class WebClientMetricsConfiguration {
request.getAutotime());
}
@ConditionalOnClass(HttpClient.class)
static class ReactorNettyClientMetricsConfiguration {
@Bean
ReactorNettyHttpClientMapper metricsHttpClientMapper() {
return (httpClient) -> httpClient.tcpConfiguration((tcpClient) -> tcpClient.metrics(true));
}
}
}
/*
* Copyright 2012-2020 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.actuate.autoconfigure.metrics.web.netty;
import io.micrometer.core.instrument.MeterRegistry;
import reactor.netty.http.server.HttpServer;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Reactor Netty metrics.
*
* @author Brian Clozel
* @since 2.3.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication
@ConditionalOnClass({ MeterRegistry.class, HttpServer.class })
public class NettyMetricsAutoConfiguration {
@Bean
public NettyServerCustomizer nettyServerMetricsCustomizer() {
return (httpServer) -> httpServer.tcpConfiguration((tcpServer) -> tcpServer.metrics(true));
}
}
/*
* Copyright 2012-2020 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.
*/
/**
* Auto-configuration for Reactor Netty actuator metrics.
*/
package org.springframework.boot.actuate.autoconfigure.metrics.web.netty;
......@@ -71,7 +71,6 @@ org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa.HibernateMetricsA
org.springframework.boot.actuate.autoconfigure.metrics.r2dbc.ConnectionPoolMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.client.HttpClientMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.jetty.JettyMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.netty.NettyMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.reactive.WebFluxMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat.TomcatMetricsAutoConfiguration,\
......
......@@ -18,25 +18,16 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.client;
import java.time.Duration;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
import io.micrometer.core.instrument.simple.SimpleConfig;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
import org.springframework.boot.actuate.metrics.web.reactive.client.WebClientExchangeTagsProvider;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
......@@ -116,47 +107,6 @@ class WebClientMetricsConfigurationTests {
});
}
@Test
void shouldConfigureMetricsForReactorNetty() {
this.contextRunner.withConfiguration(AutoConfigurations.of(ClientHttpConnectorAutoConfiguration.class))
.run((context) -> {
CompositeMeterRegistry registry = Metrics.globalRegistry;
MockWebServer server = new MockWebServer();
try {
server.start();
server.enqueue(new MockResponse());
String serverAddress = "http://" + server.getHostName() + ":" + server.getPort();
WebClient.Builder builder = context.getBean(WebClient.Builder.class);
WebClient client = builder.baseUrl(serverAddress).build();
assertThat(registry.find("reactor.netty.tcp.client.connect.time").timer()).isNull();
client.get().uri("/test").retrieve().toBodilessEntity().block();
assertThat(registry.find("reactor.netty.tcp.client.connect.time").timer()).isNotNull();
}
finally {
server.shutdown();
}
});
}
@Test
void sanityTest() throws Exception {
MockWebServer server = new MockWebServer();
try {
server.start();
server.enqueue(new MockResponse());
SimpleMeterRegistry registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, Clock.SYSTEM);
Metrics.addRegistry(registry);
HttpClient client = HttpClient.create().metrics(true);
assertThat(registry.find("reactor.netty.http.client.connect.time").timer()).isNull();
client.get().uri("http://" + server.getHostName() + ":" + server.getPort()).response().block();
assertThat(registry.find("reactor.netty.http.client.connect.time").timer()).isNotNull();
}
finally {
server.shutdown();
}
}
private MeterRegistry getInitializedMeterRegistry(AssertableApplicationContext context) {
WebClient webClient = mockWebClient(context.getBean(WebClient.Builder.class));
MeterRegistry registry = context.getBean(MeterRegistry.class);
......
/*
* Copyright 2012-2020 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.actuate.autoconfigure.metrics.web.netty;
import java.util.stream.Collectors;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Metrics;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.web.reactive.function.client.WebClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link NettyMetricsAutoConfiguration}
*
* @author Brian Clozel
*/
class NettyMetricsAutoConfigurationTests {
@Test
void autoConfiguresTcpMetricsWithReactorNettyServer() {
MeterRegistry registry = Metrics.globalRegistry;
assertThat(registry.find("reactor.netty.tcp.server.data.received").summary()).isNull();
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new)
.withConfiguration(AutoConfigurations.of(NettyMetricsAutoConfiguration.class,
ReactiveWebServerFactoryAutoConfiguration.class))
.withUserConfiguration(ReactiveWebServerConfiguration.class).run((context) -> {
AnnotationConfigReactiveWebServerApplicationContext serverContext = context
.getSourceApplicationContext(AnnotationConfigReactiveWebServerApplicationContext.class);
context.publishEvent(new ApplicationStartedEvent(new SpringApplication(), null,
context.getSourceApplicationContext()));
WebClient.create("http://localhost:" + serverContext.getWebServer().getPort()).get().retrieve()
.toBodilessEntity().block();
assertThat(registry.find("reactor.netty.tcp.server.data.received").summary()).isNotNull();
});
}
@Configuration(proxyBeanMethods = false)
static class ReactiveWebServerConfiguration {
@Bean
NettyReactiveWebServerFactory nettyFactory(ObjectProvider<NettyServerCustomizer> customizers) {
NettyReactiveWebServerFactory serverFactory = new NettyReactiveWebServerFactory(0);
serverFactory.setServerCustomizers(customizers.orderedStream().collect(Collectors.toList()));
return serverFactory;
}
@Bean
HttpHandler httpHandler() {
return (req, res) -> res.setComplete();
}
}
}
......@@ -1813,7 +1813,6 @@ Spring Boot registers the following core metrics when applicable:
* Logback metrics: record the number of events logged to Logback at each level
* Uptime metrics: report a gauge for uptime and a fixed gauge representing the application's absolute start time
* Tomcat metrics (`server.tomcat.mbeanregistry.enabled` must be set to `true` for all Tomcat metrics to be registered)
* Reactor Netty metrics (TCP and allocator metrics for client and server)
* {spring-integration-docs}system-management.html#micrometer-integration[Spring Integration] metrics
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment