001package io.prometheus.client.jetty;
002
003import io.prometheus.client.Collector;
004import io.prometheus.client.CollectorRegistry;
005import io.prometheus.client.GaugeMetricFamily;
006import java.util.Arrays;
007import java.util.Collections;
008import java.util.List;
009import java.util.Map;
010import java.util.concurrent.ConcurrentHashMap;
011import java.util.function.Function;
012import org.eclipse.jetty.util.thread.QueuedThreadPool;
013
014public class QueuedThreadPoolStatisticsCollector extends Collector {
015
016  private static final List<String> LABEL_NAMES = Collections.singletonList("unit");
017
018  private final Map<String, QueuedThreadPool> queuedThreadPoolMap = new ConcurrentHashMap<>();
019
020  public QueuedThreadPoolStatisticsCollector() {
021  }
022
023  public QueuedThreadPoolStatisticsCollector(QueuedThreadPool queuedThreadPool, String name) {
024    add(queuedThreadPool, name);
025  }
026
027  public QueuedThreadPoolStatisticsCollector add(QueuedThreadPool queuedThreadPool, String name) {
028    queuedThreadPoolMap.put(name, queuedThreadPool);
029    return this;
030  }
031
032  @Override
033  public List<MetricFamilySamples> collect() {
034    return Arrays.asList(
035        buildGauge("jetty_queued_thread_pool_threads", "Number of total threads",
036            QueuedThreadPool::getThreads),
037        buildGauge("jetty_queued_thread_pool_threads_idle", "Number of idle threads",
038            QueuedThreadPool::getIdleThreads),
039        buildGauge("jetty_queued_thread_pool_threads_max", "Max size of thread pool",
040            QueuedThreadPool::getMaxThreads),
041        buildGauge("jetty_queued_thread_pool_jobs", "Number of total jobs",
042            QueuedThreadPool::getQueueSize));
043  }
044
045  @Override
046  public <T extends Collector> T register(CollectorRegistry registry) {
047    if (queuedThreadPoolMap.isEmpty()) {
048      throw new IllegalStateException("You must register at least one QueuedThreadPool.");
049    }
050    return super.register(registry);
051  }
052
053  private GaugeMetricFamily buildGauge(String metric, String help,
054      Function<QueuedThreadPool, Integer> metricValueProvider) {
055    final GaugeMetricFamily metricFamily = new GaugeMetricFamily(metric, help, LABEL_NAMES);
056    queuedThreadPoolMap.forEach((key, value) -> metricFamily.addMetric(
057        Collections.singletonList(key),
058        metricValueProvider.apply(value)
059    ));
060    return metricFamily;
061  }
062}