001package io.prometheus.client.hotspot; 002 003import io.prometheus.client.Collector; 004import io.prometheus.client.CounterMetricFamily; 005import io.prometheus.client.GaugeMetricFamily; 006 007import java.lang.management.ManagementFactory; 008import java.lang.management.ThreadMXBean; 009import java.util.ArrayList; 010import java.util.List; 011 012/** 013 * Exports metrics about JVM thread areas. 014 * <p> 015 * Example usage: 016 * <pre> 017 * {@code 018 * new ThreadExports().register(); 019 * } 020 * </pre> 021 * Example metrics being exported: 022 * <pre> 023 * jvm_threads_current{} 300 024 * jvm_threads_daemon{} 200 025 * jvm_threads_peak{} 410 026 * jvm_threads_started_total{} 1200 027 * </pre> 028 */ 029public class ThreadExports extends Collector { 030 private final ThreadMXBean threadBean; 031 032 public ThreadExports() { 033 this(ManagementFactory.getThreadMXBean()); 034 } 035 036 public ThreadExports(ThreadMXBean threadBean) { 037 this.threadBean = threadBean; 038 } 039 040 void addThreadMetrics(List<MetricFamilySamples> sampleFamilies) { 041 sampleFamilies.add( 042 new GaugeMetricFamily( 043 "jvm_threads_current", 044 "Current thread count of a JVM", 045 threadBean.getThreadCount())); 046 047 sampleFamilies.add( 048 new GaugeMetricFamily( 049 "jvm_threads_daemon", 050 "Daemon thread count of a JVM", 051 threadBean.getDaemonThreadCount())); 052 053 sampleFamilies.add( 054 new GaugeMetricFamily( 055 "jvm_threads_peak", 056 "Peak thread count of a JVM", 057 threadBean.getPeakThreadCount())); 058 059 sampleFamilies.add( 060 new CounterMetricFamily( 061 "jvm_threads_started_total", 062 "Started thread count of a JVM", 063 threadBean.getTotalStartedThreadCount())); 064 065 sampleFamilies.add( 066 new GaugeMetricFamily( 067 "jvm_threads_deadlocked", 068 "Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers", 069 nullSafeArrayLength(threadBean.findDeadlockedThreads()))); 070 071 sampleFamilies.add( 072 new GaugeMetricFamily( 073 "jvm_threads_deadlocked_monitor", 074 "Cycles of JVM-threads that are in deadlock waiting to acquire object monitors", 075 nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads()))); 076 } 077 078 private static double nullSafeArrayLength(long[] array) { 079 return null == array ? 0 : array.length; 080 } 081 082 public List<MetricFamilySamples> collect() { 083 List<MetricFamilySamples> mfs = new ArrayList<MetricFamilySamples>(); 084 addThreadMetrics(mfs); 085 return mfs; 086 } 087}