package org.kie.perf.metrics; import static com.codahale.metrics.MetricRegistry.name; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import com.codahale.metrics.Gauge; import com.codahale.metrics.Metric; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricSet; import com.codahale.metrics.jvm.ThreadDeadlockDetector; public class ThreadStatesGaugeSet implements MetricSet { // do not compute stack traces. private static final int STACK_TRACE_DEPTH = 0; private Class<?> scenario; private final ThreadMXBean threads; private final ThreadDeadlockDetector deadlockDetector; public ThreadStatesGaugeSet(Class<?> scenario) { this.scenario = scenario; this.threads = ManagementFactory.getThreadMXBean(); this.deadlockDetector = new ThreadDeadlockDetector(); } @Override public Map<String, Metric> getMetrics() { final Map<String, Metric> gauges = new HashMap<String, Metric>(); for (final Thread.State state : Thread.State.values()) { gauges.put(MetricRegistry.name(scenario, "thread.state", state.toString().toLowerCase(), "count"), new Gauge<Object>() { @Override public Object getValue() { return getThreadCount(state); } }); } gauges.put(MetricRegistry.name(scenario, "threads.count"), new Gauge<Integer>() { @Override public Integer getValue() { return threads.getThreadCount(); } }); gauges.put(MetricRegistry.name(scenario, "daemon.count"), new Gauge<Integer>() { @Override public Integer getValue() { return threads.getDaemonThreadCount(); } }); gauges.put(MetricRegistry.name(scenario, "deadlock.count"), new Gauge<Integer>() { @Override public Integer getValue() { return deadlockDetector.getDeadlockedThreads().size(); } }); gauges.put(MetricRegistry.name(scenario, "deadlocks"), new Gauge<Set<String>>() { @Override public Set<String> getValue() { return deadlockDetector.getDeadlockedThreads(); } }); return Collections.unmodifiableMap(gauges); } private int getThreadCount(Thread.State state) { final ThreadInfo[] allThreads = getThreadInfo(); int count = 0; for (ThreadInfo info : allThreads) { if (info != null && info.getThreadState() == state) { count++; } } return count; } ThreadInfo[] getThreadInfo() { return threads.getThreadInfo(threads.getAllThreadIds(), STACK_TRACE_DEPTH); } }