Skip to content
This repository was archived by the owner on Feb 29, 2020. It is now read-only.

Commit 5638a2a

Browse files
committed
Build upon Michal's work for jvm stats.
Spaces are okay in label values, no need to switch to hyphens. Export committed and max separately. Inline rather than using constants, so it's easier to read. Use a summary for GC stats. Add a way to pick up current and future jvm collectors.
1 parent 3fc8c10 commit 5638a2a

File tree

8 files changed

+191
-144
lines changed

8 files changed

+191
-144
lines changed

AUTHORS.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ The following individuals have contributed code to this repository
1414
* Flavio W. Brasil <[email protected]>
1515
* Julius Volz <[email protected]>
1616
* Matt T. Proud <[email protected]>
17+
* Michal Witkowski <[email protected]>
1718
* Ursula Kallio <[email protected]>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package io.prometheus.client.hotspot;
2+
3+
/**
4+
* Registers the default Hotspot collectors.
5+
* <p>
6+
* This is intended to avoid users having to add in new
7+
* registrations every time a new exporter is added.
8+
* <p>
9+
* Example usage:
10+
* <pre>
11+
* {@code
12+
* DefaultExports().initialize();
13+
* }
14+
* </pre>
15+
*/
16+
public class DefaultExports {
17+
private static boolean initialized = false;
18+
/**
19+
* Register the default Hotspot collectors.
20+
*/
21+
public static synchronized void initialize() {
22+
if (!initialized) {
23+
new StandardExports().register();
24+
new MemoryPoolsExports().register();
25+
new GarbageCollectorExports().register();
26+
initialized = true;
27+
}
28+
}
29+
30+
}

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

+16-46
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,11 @@
2121
* </pre>
2222
* Example metrics being exported:
2323
* <pre>
24-
* jvm_gc_collections{gc="PS1} 200
25-
* jvm_gc_collections_time{gc="PS1} 6.7
24+
* jvm_gc_collection_seconds_count{gc="PS1"} 200
25+
* jvm_gc_collection_seconds_sum{gc="PS1"} 6.7
2626
* </pre>
2727
*/
2828
public class GarbageCollectorExports extends Collector {
29-
private static final Pattern WHITESPACE = Pattern.compile("[\\s]+");
30-
static final String COLLECTIONS_COUNT_METRIC = "jvm_gc_collections";
31-
static final String COLLECTIONS_TIME_METRIC = "jvm_gc_collections_time";
32-
static final List<String> LABEL_NAMES = Arrays.asList("gc");
33-
private static final List<String> DEFAULT_LABEL = Arrays.asList("unknown");
34-
35-
private final HashMap<GarbageCollectorMXBean, List<String>> labelValues =
36-
new HashMap<GarbageCollectorMXBean, List<String>>();
3729
private final List<GarbageCollectorMXBean> garbageCollectors;
3830

3931
public GarbageCollectorExports() {
@@ -42,52 +34,30 @@ public GarbageCollectorExports() {
4234

4335
GarbageCollectorExports(List<GarbageCollectorMXBean> garbageCollectors) {
4436
this.garbageCollectors = garbageCollectors;
45-
for (final GarbageCollectorMXBean gc : garbageCollectors) {
46-
if (!labelValues.containsKey(gc)) {
47-
String gcName = WHITESPACE.matcher(gc.getName()).replaceAll("-");
48-
labelValues.put(gc, Arrays.asList(gcName));
49-
}
50-
}
5137
}
5238

53-
MetricFamilySamples collectorCountMetric() {
39+
public List<MetricFamilySamples> collect() {
5440
ArrayList<MetricFamilySamples.Sample> samples = new ArrayList<MetricFamilySamples.Sample>();
5541
for (final GarbageCollectorMXBean gc : garbageCollectors) {
5642
samples.add(
5743
new MetricFamilySamples.Sample(
58-
COLLECTIONS_COUNT_METRIC,
59-
LABEL_NAMES,
60-
labelValues.getOrDefault(gc, DEFAULT_LABEL),
61-
gc.getCollectionCount()));
62-
}
63-
return new MetricFamilySamples(
64-
COLLECTIONS_COUNT_METRIC,
65-
Type.COUNTER,
66-
"Number of collections of a given JVM garbage collector.",
67-
samples);
68-
}
69-
70-
MetricFamilySamples collectorTimeMetric() {
71-
ArrayList<MetricFamilySamples.Sample> samples = new ArrayList<MetricFamilySamples.Sample>();
72-
for (final GarbageCollectorMXBean gc : garbageCollectors) {
44+
"jvm_gc_collection_seconds_sum",
45+
Arrays.asList("gc"),
46+
Arrays.asList(gc.getName()),
47+
gc.getCollectionTime() / MILLISECONDS_PER_SECOND));
7348
samples.add(
7449
new MetricFamilySamples.Sample(
75-
COLLECTIONS_TIME_METRIC,
76-
LABEL_NAMES,
77-
labelValues.getOrDefault(gc, DEFAULT_LABEL),
78-
gc.getCollectionTime() / MILLISECONDS_PER_SECOND));
50+
"jvm_gc_collection_seconds_count",
51+
Arrays.asList("gc"),
52+
Arrays.asList(gc.getName()),
53+
gc.getCollectionCount()));
7954
}
80-
return new MetricFamilySamples(
81-
COLLECTIONS_TIME_METRIC,
82-
Type.COUNTER,
83-
"Accumulated time (s) spent in a given JVM garbage collector.",
84-
samples);
85-
}
86-
87-
public List<MetricFamilySamples> collect() {
8855
List<MetricFamilySamples> mfs = new ArrayList<MetricFamilySamples>();
89-
mfs.add(collectorCountMetric());
90-
mfs.add(collectorTimeMetric());
56+
mfs.add(new MetricFamilySamples(
57+
"jvm_gc_collection_seconds",
58+
Type.SUMMARY,
59+
"Time spent in a given JVM garbage collector in seconds.",
60+
samples));
9161

9262
return mfs;
9363
}

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

+71-56
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,13 @@
2323
* </pre>
2424
* Example metrics being exported:
2525
* <pre>
26-
* jvm_memory_used{area="heap} 2000000
27-
* jvm_memory_limit{area="nonheap"} 200000
28-
* jvm_memory_pool_used{pool="PS-Eden-Space"} 2000
26+
* jvm_memory_bytes_used{area="heap"} 2000000
27+
* jvm_memory_bytes_committed{area="nonheap"} 200000
28+
* jvm_memory_bytes_max{area="nonheap"} 2000000
29+
* jvm_memory_pool_bytes_used{pool="PS Eden Space"} 2000
2930
* </pre>
3031
*/
3132
public class MemoryPoolsExports extends Collector {
32-
private static final Pattern WHITESPACE = Pattern.compile("[\\s]+");
33-
static final String MEMORY_USED_METRIC = "jvm_memory_used";
34-
static final String MEMORY_LIMIT_METRIC = "jvm_memory_limit";
35-
static final String POOLS_USED_METRIC = "jvm_memory_pool_used";
36-
static final String POOLS_LIMIT_METRIC = "jvm_memory_pool_limit";
37-
38-
private static final List<String> MEMORY_LABEL_NAMES = Arrays.asList("area");
39-
private static final List<String> MEMORY_HEAP_LABEL = Arrays.asList("heap");
40-
private static final List<String> MEMORY_NONHEAP_LABEL = Arrays.asList("nonheap");
41-
42-
private static final List<String> POOLS_LABEL_NAMES = Arrays.asList("pool");
43-
44-
private final HashMap<MemoryPoolMXBean, List<String>> poolLabelValues = new HashMap<MemoryPoolMXBean, List<String>>();
4533
private final MemoryMXBean memoryBean;
4634
private final List<MemoryPoolMXBean> poolBeans;
4735

@@ -55,12 +43,6 @@ public MemoryPoolsExports(MemoryMXBean memoryBean,
5543
List<MemoryPoolMXBean> poolBeans) {
5644
this.memoryBean = memoryBean;
5745
this.poolBeans = poolBeans;
58-
for (final MemoryPoolMXBean pool : poolBeans) {
59-
if (!poolLabelValues.containsKey(pool)) {
60-
String gcName = WHITESPACE.matcher(pool.getName()).replaceAll("-");
61-
poolLabelValues.put(pool, Arrays.asList(gcName));
62-
}
63-
}
6446
}
6547

6648
void addMemoryAreaMetrics(List<MetricFamilySamples> sampleFamilies) {
@@ -69,74 +51,107 @@ void addMemoryAreaMetrics(List<MetricFamilySamples> sampleFamilies) {
6951
ArrayList<MetricFamilySamples.Sample> usedSamples = new ArrayList<MetricFamilySamples.Sample>();
7052
usedSamples.add(
7153
new MetricFamilySamples.Sample(
72-
MEMORY_USED_METRIC,
73-
MEMORY_LABEL_NAMES,
74-
MEMORY_HEAP_LABEL,
54+
"jvm_memory_bytes_used",
55+
Arrays.asList("area"),
56+
Arrays.asList("heap"),
7557
heapUsage.getUsed()));
7658
usedSamples.add(
7759
new MetricFamilySamples.Sample(
78-
MEMORY_USED_METRIC,
79-
MEMORY_LABEL_NAMES,
80-
MEMORY_NONHEAP_LABEL,
60+
"jvm_memory_bytes_used",
61+
Arrays.asList("area"),
62+
Arrays.asList("nonheap"),
8163
nonHeapUsage.getUsed()));
8264
sampleFamilies.add(
8365
new MetricFamilySamples(
84-
MEMORY_USED_METRIC,
66+
"jvm_memory_bytes_used",
8567
Type.GAUGE,
86-
"Used bytes of a given JVM memory area (heap, nonheap).",
68+
"Used bytes of a given JVM memory area.",
8769
usedSamples));
88-
ArrayList<MetricFamilySamples.Sample> limitSamples = new ArrayList<MetricFamilySamples.Sample>();
89-
limitSamples.add(
70+
ArrayList<MetricFamilySamples.Sample> committedSamples = new ArrayList<MetricFamilySamples.Sample>();
71+
committedSamples.add(
9072
new MetricFamilySamples.Sample(
91-
MEMORY_LIMIT_METRIC,
92-
MEMORY_LABEL_NAMES,
93-
MEMORY_HEAP_LABEL,
94-
heapUsage.getMax() == -1 ? heapUsage.getMax() : heapUsage.getCommitted()));
95-
limitSamples.add(
73+
"jvm_memory_bytes_committed",
74+
Arrays.asList("area"),
75+
Arrays.asList("heap"),
76+
heapUsage.getCommitted()));
77+
committedSamples.add(
9678
new MetricFamilySamples.Sample(
97-
MEMORY_LIMIT_METRIC,
98-
MEMORY_LABEL_NAMES,
99-
MEMORY_NONHEAP_LABEL,
100-
nonHeapUsage.getMax() == -1 ? nonHeapUsage.getMax() : nonHeapUsage.getCommitted()));
79+
"jvm_memory_bytes_committed",
80+
Arrays.asList("area"),
81+
Arrays.asList("nonheap"),
82+
nonHeapUsage.getCommitted()));
10183
sampleFamilies.add(
10284
new MetricFamilySamples(
103-
MEMORY_LIMIT_METRIC,
85+
"jvm_memory_bytes_committed",
10486
Type.GAUGE,
105-
"Limit (bytes) of a given JVM memory area (heap, nonheap).",
106-
limitSamples));
87+
"Committed (bytes) of a given JVM memory area.",
88+
committedSamples));
89+
ArrayList<MetricFamilySamples.Sample> maxSamples = new ArrayList<MetricFamilySamples.Sample>();
90+
maxSamples.add(
91+
new MetricFamilySamples.Sample(
92+
"jvm_memory_bytes_max",
93+
Arrays.asList("area"),
94+
Arrays.asList("heap"),
95+
heapUsage.getMax()));
96+
maxSamples.add(
97+
new MetricFamilySamples.Sample(
98+
"jvm_memory_bytes_max",
99+
Arrays.asList("area"),
100+
Arrays.asList("nonheap"),
101+
nonHeapUsage.getMax()));
102+
sampleFamilies.add(
103+
new MetricFamilySamples(
104+
"jvm_memory_bytes_max",
105+
Type.GAUGE,
106+
"Maximum (bytes) of a given JVM memory area.",
107+
maxSamples));
107108
}
108109

109110
void addMemoryPoolMetrics(List<MetricFamilySamples> sampleFamilies) {
110111
ArrayList<MetricFamilySamples.Sample> usedSamples = new ArrayList<MetricFamilySamples.Sample>();
111-
ArrayList<MetricFamilySamples.Sample> limitSamples = new ArrayList<MetricFamilySamples.Sample>();
112+
ArrayList<MetricFamilySamples.Sample> committedSamples = new ArrayList<MetricFamilySamples.Sample>();
113+
ArrayList<MetricFamilySamples.Sample> maxSamples = new ArrayList<MetricFamilySamples.Sample>();
112114
for (final MemoryPoolMXBean pool : poolBeans) {
113115
MemoryUsage poolUsage = pool.getUsage();
114116
usedSamples.add(
115117
new MetricFamilySamples.Sample(
116-
POOLS_USED_METRIC,
117-
POOLS_LABEL_NAMES,
118-
poolLabelValues.get(pool),
118+
"jvm_memory_pool_bytes_used",
119+
Arrays.asList("pool"),
120+
Arrays.asList(pool.getName()),
119121
poolUsage.getUsed()));
120-
limitSamples.add(
122+
committedSamples.add(
121123
new MetricFamilySamples.Sample(
122-
POOLS_LIMIT_METRIC,
123-
POOLS_LABEL_NAMES,
124-
poolLabelValues.get(pool),
125-
poolUsage.getMax() != -1 ? poolUsage.getMax() : poolUsage.getCommitted()));
124+
"jvm_memory_pool_bytes_committed",
125+
Arrays.asList("pool"),
126+
Arrays.asList(pool.getName()),
127+
poolUsage.getCommitted()));
128+
maxSamples.add(
129+
new MetricFamilySamples.Sample(
130+
"jvm_memory_pool_bytes_max",
131+
Arrays.asList("pool"),
132+
Arrays.asList(pool.getName()),
133+
poolUsage.getMax()));
126134
}
127135
sampleFamilies.add(
128136
new MetricFamilySamples(
129-
POOLS_USED_METRIC,
137+
"jvm_memory_pool_bytes_used",
130138
Type.GAUGE,
131139
"Used bytes of a given JVM memory pool.",
132140
usedSamples));
133141

134142
sampleFamilies.add(
135143
new MetricFamilySamples(
136-
POOLS_LIMIT_METRIC,
144+
"jvm_memory_pool_bytes_committed",
137145
Type.GAUGE,
138146
"Limit (bytes) of a given JVM memory pool.",
139-
limitSamples));
147+
committedSamples));
148+
149+
sampleFamilies.add(
150+
new MetricFamilySamples(
151+
"jvm_memory_pool_bytes_max",
152+
Type.GAUGE,
153+
"Max (bytes) of a given JVM memory pool.",
154+
maxSamples));
140155
}
141156

142157

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@
66
import org.eclipse.jetty.servlet.ServletContextHandler;
77
import org.eclipse.jetty.servlet.ServletHolder;
88

9+
910
public class ExampleExporter {
1011

1112
public static void main(String[] args) throws Exception {
12-
new StandardExports().register();
13+
DefaultExports.initialize();
1314
Server server = new Server(1234);
1415
ServletContextHandler context = new ServletContextHandler();
1516
context.setContextPath("/");
1617
server.setHandler(context);
1718
context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics");
1819
server.start();
19-
while(true) {
20-
}
20+
server.join();
2121
}
2222

2323
}

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

+11-10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.util.concurrent.TimeUnit;
1212

1313
import static org.junit.Assert.assertEquals;
14+
import static org.mockito.Mockito.when;
1415

1516

1617
public class GarbageCollectorExportsTest {
@@ -23,12 +24,12 @@ public class GarbageCollectorExportsTest {
2324

2425
@Before
2526
public void setUp() {
26-
Mockito.when(mockGcBean1.getName()).thenReturn("MyGC1");
27-
Mockito.when(mockGcBean1.getCollectionCount()).thenReturn(100L);
28-
Mockito.when(mockGcBean1.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(10));
29-
Mockito.when(mockGcBean2.getName()).thenReturn("MyGC2");
30-
Mockito.when(mockGcBean2.getCollectionCount()).thenReturn(200L);
31-
Mockito.when(mockGcBean2.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(20));
27+
when(mockGcBean1.getName()).thenReturn("MyGC1");
28+
when(mockGcBean1.getCollectionCount()).thenReturn(100L);
29+
when(mockGcBean1.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(10));
30+
when(mockGcBean2.getName()).thenReturn("MyGC2");
31+
when(mockGcBean2.getCollectionCount()).thenReturn(200L);
32+
when(mockGcBean2.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(20));
3233
collectorUnderTest = new GarbageCollectorExports(mockList).register(registry);
3334
}
3435

@@ -37,28 +38,28 @@ public void testGarbageCollectorExports() {
3738
assertEquals(
3839
100L,
3940
registry.getSampleValue(
40-
GarbageCollectorExports.COLLECTIONS_COUNT_METRIC,
41+
"jvm_gc_collection_seconds_count",
4142
new String[]{"gc"},
4243
new String[]{"MyGC1"}),
4344
.0000001);
4445
assertEquals(
4546
10d,
4647
registry.getSampleValue(
47-
GarbageCollectorExports.COLLECTIONS_TIME_METRIC,
48+
"jvm_gc_collection_seconds_sum",
4849
new String[]{"gc"},
4950
new String[]{"MyGC1"}),
5051
.0000001);
5152
assertEquals(
5253
200L,
5354
registry.getSampleValue(
54-
GarbageCollectorExports.COLLECTIONS_COUNT_METRIC,
55+
"jvm_gc_collection_seconds_count",
5556
new String[]{"gc"},
5657
new String[]{"MyGC2"}),
5758
.0000001);
5859
assertEquals(
5960
20d,
6061
registry.getSampleValue(
61-
GarbageCollectorExports.COLLECTIONS_TIME_METRIC,
62+
"jvm_gc_collection_seconds_sum",
6263
new String[]{"gc"},
6364
new String[]{"MyGC2"}),
6465
.0000001);

0 commit comments

Comments
 (0)