Spring Boot 使用 嵌入式 Jetty 容器 集成 Prometheus 监控

添加Maven依赖

<!-- For Embed Jetty -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

核心对象

自动装配:JettyMetricsAutoConfiguration
@Configuration(proxyBeanMethods = false)
@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);
    }

}
度量绑定:JettyServerThreadPoolMetricsBinder

基于 ApplicationListener 监听 onApplicationEvent,查找 ThreadPool 对象, 初始化 JettyServerThreadPoolMetrics

public class JettyServerThreadPoolMetricsBinder implements ApplicationListener<ApplicationStartedEvent> {

    private final MeterRegistry meterRegistry;

    private final Iterable<Tag> tags;

    public JettyServerThreadPoolMetricsBinder(MeterRegistry meterRegistry) {
        this(meterRegistry, Collections.emptyList());
    }

    public JettyServerThreadPoolMetricsBinder(MeterRegistry meterRegistry, Iterable<Tag> 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;
    }

}
度量实现:JettyServerThreadPoolMetrics
public class JettyServerThreadPoolMetrics implements MeterBinder {

    private final ThreadPool threadPool;

    private final Iterable<Tag> tags;

    public JettyServerThreadPoolMetrics(ThreadPool threadPool, Iterable<Tag> tags) {
        this.threadPool = threadPool;
        this.tags = tags;
    }

    @Override
    public void bindTo(MeterRegistry registry) {
        if (threadPool instanceof SizedThreadPool) {
            SizedThreadPool sizedThreadPool = (SizedThreadPool) threadPool;
            Gauge.builder("jetty.threads.config.min", sizedThreadPool, SizedThreadPool::getMinThreads)
                    .description("The minimum number of threads in the pool").tags(tags).register(registry);
            Gauge.builder("jetty.threads.config.max", sizedThreadPool, SizedThreadPool::getMaxThreads)
                    .description("The maximum number of threads in the pool").tags(tags).register(registry);
            if (threadPool instanceof QueuedThreadPool) {
                QueuedThreadPool queuedThreadPool = (QueuedThreadPool) threadPool;
                Gauge.builder("jetty.threads.busy", queuedThreadPool, QueuedThreadPool::getBusyThreads)
                        .description("The number of busy threads in the pool").tags(tags).register(registry);
                Gauge.builder("jetty.threads.jobs", queuedThreadPool, QueuedThreadPool::getQueueSize)
                        .description("Number of jobs queued waiting for a thread").tags(tags).register(registry);
            }
        }
        Gauge.builder("jetty.threads.current", threadPool, ThreadPool::getThreads)
                .description("The total number of threads in the pool").tags(tags).register(registry);
        Gauge.builder("jetty.threads.idle", threadPool, ThreadPool::getIdleThreads)
                .description("The number of idle threads in the pool").tags(tags).register(registry);
    }

}
作者:Jeebiz  创建时间:2023-04-20 21:15
最后编辑:Jeebiz  更新时间:2024-01-24 21:48