diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml
index c8ef34f78c..c202ae0e1a 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml
@@ -248,6 +248,11 @@
elasticsearch
true
+
+ org.eclipse.jetty
+ jetty-server
+ true
+
org.flywaydb
flyway-core
@@ -470,6 +475,11 @@
aspectjrt
test
+
+ org.eclipse.jetty
+ jetty-webapp
+ test
+
org.hsqldb
hsqldb
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java
new file mode 100644
index 0000000000..ca96c9b180
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012-2018 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.boot.actuate.autoconfigure.metrics.web.jetty;
+
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.binder.jetty.JettyServerThreadPoolMetrics;
+import org.eclipse.jetty.server.Server;
+
+import org.springframework.boot.actuate.metrics.web.jetty.JettyServerThreadPoolMetricsBinder;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+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.ConditionalOnWebApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for Jetty metrics.
+ *
+ * @author Andy Wilkinson
+ * @since 2.1.0
+ */
+@Configuration
+@ConditionalOnWebApplication
+@ConditionalOnClass({ JettyServerThreadPoolMetrics.class, Server.class })
+public class JettyMetricsAutoConfiguration {
+
+ @Bean
+ @ConditionalOnBean(MeterRegistry.class)
+ @ConditionalOnMissingBean({ JettyServerThreadPoolMetrics.class,
+ JettyServerThreadPoolMetricsBinder.class })
+ public JettyServerThreadPoolMetricsBinder jettyServerThreadPoolMetricsBinder(
+ MeterRegistry meterRegistry) {
+ return new JettyServerThreadPoolMetricsBinder(meterRegistry);
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/package-info.java
new file mode 100644
index 0000000000..9132210467
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012-2018 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.
+ */
+
+/**
+ * Auto-configuration for Jetty actuator metrics.
+ */
+package org.springframework.boot.actuate.autoconfigure.metrics.web.jetty;
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories
index 29af9cef1b..da69ef3055 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories
@@ -64,6 +64,7 @@ org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetric
org.springframework.boot.actuate.autoconfigure.metrics.jersey.JerseyServerMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa.HibernateMetricsAutoConfiguration,\
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.reactive.WebFluxMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat.TomcatMetricsAutoConfiguration,\
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfigurationTests.java
new file mode 100644
index 0000000000..75189b8437
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfigurationTests.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2012-2018 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.boot.actuate.autoconfigure.metrics.web.jetty;
+
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
+import org.junit.Test;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.actuate.metrics.web.jetty.JettyServerThreadPoolMetricsBinder;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration;
+import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
+import org.springframework.boot.context.event.ApplicationStartedEvent;
+import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
+import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
+import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
+import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
+import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
+import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.server.reactive.HttpHandler;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for {@link JettyMetricsAutoConfiguration}.
+ *
+ * @author Andy Wilkinson
+ */
+public class JettyMetricsAutoConfigurationTests {
+
+ @Test
+ public void autoConfiguresThreadPoolMetricsWithEmbeddedServletJetty() {
+ new WebApplicationContextRunner(
+ AnnotationConfigServletWebServerApplicationContext::new)
+ .withConfiguration(
+ AutoConfigurations.of(JettyMetricsAutoConfiguration.class,
+ ServletWebServerFactoryAutoConfiguration.class))
+ .withUserConfiguration(ServletWebServerConfiguration.class,
+ MeterRegistryConfiguration.class)
+ .run((context) -> {
+ context.publishEvent(
+ new ApplicationStartedEvent(new SpringApplication(),
+ null, context.getSourceApplicationContext()));
+ assertThat(context).hasSingleBean(
+ JettyServerThreadPoolMetricsBinder.class);
+ SimpleMeterRegistry registry = context
+ .getBean(SimpleMeterRegistry.class);
+ assertThat(registry.find("jetty.threads.config.min").meter())
+ .isNotNull();
+ });
+ }
+
+ @Test
+ public void autoConfiguresThreadPoolMetricsWithEmbeddedReactiveJetty() {
+ new ReactiveWebApplicationContextRunner(
+ AnnotationConfigReactiveWebServerApplicationContext::new)
+ .withConfiguration(
+ AutoConfigurations.of(JettyMetricsAutoConfiguration.class,
+ ReactiveWebServerFactoryAutoConfiguration.class))
+ .withUserConfiguration(ReactiveWebServerConfiguration.class,
+ MeterRegistryConfiguration.class)
+ .run((context) -> {
+ context.publishEvent(
+ new ApplicationStartedEvent(new SpringApplication(),
+ null, context.getSourceApplicationContext()));
+ SimpleMeterRegistry registry = context
+ .getBean(SimpleMeterRegistry.class);
+ assertThat(registry.find("jetty.threads.config.min").meter())
+ .isNotNull();
+ });
+ }
+
+ @Test
+ public void allowsCustomJettyServerThreadPoolMetricsBinderToBeUsed() {
+ new WebApplicationContextRunner()
+ .withConfiguration(
+ AutoConfigurations.of(JettyMetricsAutoConfiguration.class))
+ .withUserConfiguration(CustomJettyServerThreadPoolMetricsBinder.class,
+ MeterRegistryConfiguration.class)
+ .run((context) -> assertThat(context)
+ .hasSingleBean(JettyServerThreadPoolMetricsBinder.class)
+ .hasBean("customJettyServerThreadPoolMetricsBinder"));
+ }
+
+ @Configuration
+ static class MeterRegistryConfiguration {
+
+ @Bean
+ public SimpleMeterRegistry meterRegistry() {
+ return new SimpleMeterRegistry();
+ }
+
+ }
+
+ @Configuration
+ static class ServletWebServerConfiguration {
+
+ @Bean
+ public JettyServletWebServerFactory jettyFactory() {
+ return new JettyServletWebServerFactory(0);
+ }
+
+ }
+
+ @Configuration
+ static class ReactiveWebServerConfiguration {
+
+ @Bean
+ public JettyReactiveWebServerFactory jettyFactory() {
+ return new JettyReactiveWebServerFactory(0);
+ }
+
+ @Bean
+ public HttpHandler httpHandler() {
+ return mock(HttpHandler.class);
+ }
+
+ }
+
+ @Configuration
+ static class CustomJettyServerThreadPoolMetricsBinder {
+
+ @Bean
+ public JettyServerThreadPoolMetricsBinder customJettyServerThreadPoolMetricsBinder(
+ MeterRegistry meterRegistry) {
+ return new JettyServerThreadPoolMetricsBinder(meterRegistry);
+ }
+
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator/pom.xml b/spring-boot-project/spring-boot-actuator/pom.xml
index a02ba2d1e7..de7fa8560c 100644
--- a/spring-boot-project/spring-boot-actuator/pom.xml
+++ b/spring-boot-project/spring-boot-actuator/pom.xml
@@ -113,6 +113,11 @@
aspectjweaver
true
+
+ org.eclipse.jetty
+ jetty-server
+ true
+
org.elasticsearch
elasticsearch
diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java
new file mode 100644
index 0000000000..86b3c0976b
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012-2018 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.boot.actuate.metrics.web.jetty;
+
+import java.util.Collections;
+
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Tag;
+import io.micrometer.core.instrument.binder.jetty.JettyServerThreadPoolMetrics;
+import org.eclipse.jetty.util.thread.ThreadPool;
+
+import org.springframework.boot.context.event.ApplicationStartedEvent;
+import org.springframework.boot.web.context.WebServerApplicationContext;
+import org.springframework.boot.web.embedded.jetty.JettyWebServer;
+import org.springframework.boot.web.server.WebServer;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationListener;
+
+/**
+ * Binds {@link JettyServerThreadPoolMetrics} in response to the
+ * {@link ApplicationStartedEvent}.
+ *
+ * @author Andy Wilkinson
+ * @since 2.1.0
+ */
+public class JettyServerThreadPoolMetricsBinder
+ implements ApplicationListener {
+
+ private final MeterRegistry meterRegistry;
+
+ private final Iterable tags;
+
+ public JettyServerThreadPoolMetricsBinder(MeterRegistry meterRegistry) {
+ this(meterRegistry, Collections.emptyList());
+ }
+
+ public JettyServerThreadPoolMetricsBinder(MeterRegistry meterRegistry,
+ Iterable tags) {
+ this.meterRegistry = meterRegistry;
+ this.tags = tags;
+ }
+
+ @Override
+ public void onApplicationEvent(ApplicationStartedEvent event) {
+ ApplicationContext applicationContext = event.getApplicationContext();
+ ThreadPool threadPool = findThreadPool(applicationContext);
+ if (threadPool != null) {
+ new JettyServerThreadPoolMetrics(threadPool, this.tags)
+ .bindTo(this.meterRegistry);
+ }
+ }
+
+ private ThreadPool findThreadPool(ApplicationContext applicationContext) {
+ if (applicationContext instanceof WebServerApplicationContext) {
+ WebServer webServer = ((WebServerApplicationContext) applicationContext)
+ .getWebServer();
+ if (webServer instanceof JettyWebServer) {
+ return ((JettyWebServer) webServer).getServer().getThreadPool();
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/package-info.java
new file mode 100644
index 0000000000..c977a9ab42
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012-2017 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.
+ */
+
+/**
+ * Actuator support for Jetty metrics.
+ */
+package org.springframework.boot.actuate.metrics.web.jetty;