Skip to content

Commit 02132a3

Browse files
committed
Adds ability to exclude deadlocked threads from exported metrics
Finding deadlocked threads might be an expensive operation if there are a large number of threads in the jvm since it requires a safepoint.
1 parent 683466f commit 02132a3

File tree

2 files changed

+73
-12
lines changed

2 files changed

+73
-12
lines changed

simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
*/
3333
public class ThreadExports extends Collector {
3434
private final ThreadMXBean threadBean;
35+
private boolean includeDeadlockedThreads = true;
3536

3637
public ThreadExports() {
3738
this(ManagementFactory.getThreadMXBean());
@@ -41,6 +42,14 @@ public ThreadExports(ThreadMXBean threadBean) {
4142
this.threadBean = threadBean;
4243
}
4344

45+
public final boolean isIncludeDeadlockedThreads() {
46+
return includeDeadlockedThreads;
47+
}
48+
49+
public final void setIncludeDeadlockedThreads(boolean includeDeadlockedThreads) {
50+
this.includeDeadlockedThreads = includeDeadlockedThreads;
51+
}
52+
4453
void addThreadMetrics(List<MetricFamilySamples> sampleFamilies) {
4554
sampleFamilies.add(
4655
new GaugeMetricFamily(
@@ -66,18 +75,20 @@ void addThreadMetrics(List<MetricFamilySamples> sampleFamilies) {
6675
"Started thread count of a JVM",
6776
threadBean.getTotalStartedThreadCount()));
6877

69-
sampleFamilies.add(
70-
new GaugeMetricFamily(
71-
"jvm_threads_deadlocked",
72-
"Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers",
73-
nullSafeArrayLength(threadBean.findDeadlockedThreads())));
74-
75-
sampleFamilies.add(
76-
new GaugeMetricFamily(
77-
"jvm_threads_deadlocked_monitor",
78-
"Cycles of JVM-threads that are in deadlock waiting to acquire object monitors",
79-
nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads())));
80-
78+
if (includeDeadlockedThreads) {
79+
sampleFamilies.add(
80+
new GaugeMetricFamily(
81+
"jvm_threads_deadlocked",
82+
"Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers",
83+
nullSafeArrayLength(threadBean.findDeadlockedThreads())));
84+
85+
sampleFamilies.add(
86+
new GaugeMetricFamily(
87+
"jvm_threads_deadlocked_monitor",
88+
"Cycles of JVM-threads that are in deadlock waiting to acquire object monitors",
89+
nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads())));
90+
}
91+
8192
GaugeMetricFamily threadStateFamily = new GaugeMetricFamily(
8293
"jvm_threads_state",
8394
"Current count of threads by state",

simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ThreadExportsTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.Arrays;
1111

1212
import static org.junit.Assert.assertEquals;
13+
import static org.junit.Assert.assertNull;
1314
import static org.mockito.Mockito.when;
1415

1516
public class ThreadExportsTest {
@@ -97,4 +98,53 @@ public void testThreadPools() {
9798
"jvm_threads_state", STATE_LABEL, STATE_TERMINATED_LABEL),
9899
.0000001);
99100
}
101+
102+
@Test
103+
public void testThreadPoolsNoDeadlocked() {
104+
collectorUnderTest.setIncludeDeadlockedThreads(false);
105+
106+
assertNull(registry.getSampleValue(
107+
"jvm_threads_deadlocked", EMPTY_LABEL, EMPTY_LABEL));
108+
assertNull(registry.getSampleValue(
109+
"jvm_threads_deadlocked_monitor", EMPTY_LABEL, EMPTY_LABEL));
110+
111+
assertEquals(
112+
300L,
113+
registry.getSampleValue(
114+
"jvm_threads_current", EMPTY_LABEL, EMPTY_LABEL),
115+
.0000001);
116+
assertEquals(
117+
200L,
118+
registry.getSampleValue(
119+
"jvm_threads_daemon", EMPTY_LABEL, EMPTY_LABEL),
120+
.0000001);
121+
assertEquals(
122+
301L,
123+
registry.getSampleValue(
124+
"jvm_threads_peak", EMPTY_LABEL, EMPTY_LABEL),
125+
.0000001);
126+
assertEquals(
127+
503L,
128+
registry.getSampleValue(
129+
"jvm_threads_started_total", EMPTY_LABEL, EMPTY_LABEL),
130+
.0000001);
131+
132+
assertEquals(
133+
1L,
134+
registry.getSampleValue(
135+
"jvm_threads_state", STATE_LABEL, STATE_BLOCKED_LABEL),
136+
.0000001);
137+
138+
assertEquals(
139+
2L,
140+
registry.getSampleValue(
141+
"jvm_threads_state", STATE_LABEL, STATE_RUNNABLE_LABEL),
142+
.0000001);
143+
144+
assertEquals(
145+
0L,
146+
registry.getSampleValue(
147+
"jvm_threads_state", STATE_LABEL, STATE_TERMINATED_LABEL),
148+
.0000001);
149+
}
100150
}

0 commit comments

Comments
 (0)