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
This commit is contained in:
Brian Clozel 2020-04-27 12:06:26 +02:00
parent fa01a1599f
commit dfdee3e00e
7 changed files with 1 additions and 213 deletions

View File

@ -1,5 +1,5 @@
/*
* 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));
}
}
}

View File

@ -1,45 +0,0 @@
/*
* 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));
}
}

View File

@ -1,20 +0,0 @@
/*
* 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;

View File

@ -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,\

View File

@ -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);

View File

@ -1,83 +0,0 @@
/*
* 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();
}
}
}

View File

@ -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