From deb6fa7be1a8a42e3a1467b371fbf93d24fc59f2 Mon Sep 17 00:00:00 2001 From: Johnny Lim Date: Thu, 11 Oct 2018 14:19:35 +0900 Subject: [PATCH] Rework Jetty ThreadPool metrics to work with any ThreadPool Closes gh-911 --- .../jetty/JettyServerThreadPoolMetrics.java | 57 ++++++++++------ .../jetty/JettyMetricsAutoConfiguration.java | 26 +++++++- .../web/jetty/JettyMetricsPostProcessor.java | 66 ------------------- 3 files changed, 60 insertions(+), 89 deletions(-) delete mode 100644 micrometer-spring-legacy/src/main/java/io/micrometer/spring/autoconfigure/web/jetty/JettyMetricsPostProcessor.java diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jetty/JettyServerThreadPoolMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jetty/JettyServerThreadPoolMetrics.java index e3f583182a..2b8f7c0a85 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jetty/JettyServerThreadPoolMetrics.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jetty/JettyServerThreadPoolMetrics.java @@ -19,38 +19,55 @@ import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.lang.NonNull; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.ThreadPool; +import org.eclipse.jetty.util.thread.ThreadPool.SizedThreadPool; /** + * {@link MeterBinder} for Jetty {@link ThreadPool}. + * * @author Manabu Matsuzaki + * @author Andy Wilkinson */ public class JettyServerThreadPoolMetrics implements MeterBinder { - private final InstrumentedQueuedThreadPool threadPool; + private final ThreadPool threadPool; + private final Iterable tags; - public JettyServerThreadPoolMetrics(InstrumentedQueuedThreadPool threadPool, Iterable tags) { + public JettyServerThreadPoolMetrics(ThreadPool threadPool, Iterable tags) { this.threadPool = threadPool; this.tags = tags; } @Override - public void bindTo(@NonNull MeterRegistry registry) { - Gauge.builder("jetty.threads.config.min", threadPool, InstrumentedQueuedThreadPool::getMinThreads) - .tags(tags) - .description("The number of min threads") - .register(registry); - Gauge.builder("jetty.threads.config.max", threadPool, InstrumentedQueuedThreadPool::getMaxThreads) - .tags(tags) - .description("The number of max threads") - .register(registry); - Gauge.builder("jetty.threads.current", threadPool, InstrumentedQueuedThreadPool::getThreads) - .tags(tags) - .description("The current number of current threads") - .register(registry); - Gauge.builder("jetty.threads.busy", threadPool, InstrumentedQueuedThreadPool::getBusyThreads) - .tags(tags) - .description("The current number of busy threads") - .register(registry); + public void bindTo(MeterRegistry registry) { + if (this.threadPool instanceof SizedThreadPool) { + SizedThreadPool sizedThreadPool = (SizedThreadPool) this.threadPool; + Gauge.builder("jetty.threads.config.min", sizedThreadPool, + SizedThreadPool::getMinThreads) + .description("The minimum number of threads in the pool") + .tags(this.tags).register(registry); + Gauge.builder("jetty.threads.config.max", sizedThreadPool, + SizedThreadPool::getMaxThreads) + .description("The maximum number of threads in the pool") + .tags(this.tags).register(registry); + if (this.threadPool instanceof QueuedThreadPool) { + QueuedThreadPool queuedThreadPool = (QueuedThreadPool) this.threadPool; + Gauge.builder("jetty.threads.busy", queuedThreadPool, + QueuedThreadPool::getBusyThreads) + .description("The number of busy threads in the pool") + .tags(this.tags).register(registry); + } + } + Gauge.builder("jetty.threads.current", this.threadPool, + ThreadPool::getThreads) + .description("The total number of threads in the pool") + .tags(this.tags).register(registry); + Gauge.builder("jetty.threads.idle", this.threadPool, + ThreadPool::getIdleThreads) + .description("The number of idle threads in the pool").tags(this.tags) + .register(registry); } + } diff --git a/micrometer-spring-legacy/src/main/java/io/micrometer/spring/autoconfigure/web/jetty/JettyMetricsAutoConfiguration.java b/micrometer-spring-legacy/src/main/java/io/micrometer/spring/autoconfigure/web/jetty/JettyMetricsAutoConfiguration.java index cfa75c57a7..4df6e2bca1 100644 --- a/micrometer-spring-legacy/src/main/java/io/micrometer/spring/autoconfigure/web/jetty/JettyMetricsAutoConfiguration.java +++ b/micrometer-spring-legacy/src/main/java/io/micrometer/spring/autoconfigure/web/jetty/JettyMetricsAutoConfiguration.java @@ -15,17 +15,22 @@ */ package io.micrometer.spring.autoconfigure.web.jetty; +import java.util.Collections; + import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.jetty.JettyServerThreadPoolMetrics; import io.micrometer.spring.autoconfigure.MetricsAutoConfiguration; import io.micrometer.spring.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; +import org.eclipse.jetty.server.Server; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 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.web.EmbeddedServletContainerAutoConfiguration; +import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -37,6 +42,7 @@ * @author Jon Schneider * @author Michael Weirauch * @author Johnny Lim + * @author Andy Wilkinson */ @Configuration @AutoConfigureAfter({ @@ -48,9 +54,23 @@ @Conditional(JettyMetricsAutoConfiguration.JettyMetricsAutoConfigurationConditionalOnBeans.class) public class JettyMetricsAutoConfiguration { + private volatile Server server; + @Bean - public JettyMetricsPostProcessor jettyMetricsPostProcessor(ApplicationContext context) { - return new JettyMetricsPostProcessor(context); + public EmbeddedServletContainerCustomizer jettyCustomizer() { + return (jetty) -> { + ((JettyEmbeddedServletContainerFactory) jetty).setServerCustomizers(Collections.singleton(this::setServer)); + }; + } + + @Bean + @ConditionalOnMissingBean + public JettyServerThreadPoolMetrics jettyThreadPoolMetrics() { + return new JettyServerThreadPoolMetrics(this.server.getThreadPool(), Collections.emptyList()); + } + + private void setServer(Server server) { + this.server = server; } static class JettyMetricsAutoConfigurationConditionalOnBeans extends AllNestedConditions { diff --git a/micrometer-spring-legacy/src/main/java/io/micrometer/spring/autoconfigure/web/jetty/JettyMetricsPostProcessor.java b/micrometer-spring-legacy/src/main/java/io/micrometer/spring/autoconfigure/web/jetty/JettyMetricsPostProcessor.java deleted file mode 100644 index a771a02e3d..0000000000 --- a/micrometer-spring-legacy/src/main/java/io/micrometer/spring/autoconfigure/web/jetty/JettyMetricsPostProcessor.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright 2017 Pivotal Software, Inc. - *

- * 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 io.micrometer.spring.autoconfigure.web.jetty; - -import java.util.Collections; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.core.Ordered; - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.jetty.InstrumentedQueuedThreadPool; - -/** - * @author Michael Weirauch - */ -public class JettyMetricsPostProcessor implements BeanPostProcessor, Ordered { - private final ApplicationContext context; - private volatile MeterRegistry registry; - - JettyMetricsPostProcessor(ApplicationContext context) { - this.context = context; - } - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) - throws BeansException { - return bean; - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) { - if (bean instanceof JettyEmbeddedServletContainerFactory) { - ((JettyEmbeddedServletContainerFactory) bean).setThreadPool( - new InstrumentedQueuedThreadPool(getMeterRegistry(), Collections.emptyList())); - } - return bean; - } - - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE; - } - - private MeterRegistry getMeterRegistry() { - if (this.registry == null) { - this.registry = this.context.getBean(MeterRegistry.class); - } - return this.registry; - } -}