Commit a66fc303 authored by Christian Dupuis's avatar Christian Dupuis

Add more runtime metrics like information about heap, class loading and...

Add more runtime metrics like information about heap, class loading and threads to the metrics infrastructure
parent a0972227
/* /*
* Copyright 2012-2013 the original author or authors. * Copyright 2012-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,6 +16,10 @@ ...@@ -16,6 +16,10 @@
package org.springframework.boot.actuate.endpoint; package org.springframework.boot.actuate.endpoint;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadMXBean;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
...@@ -28,6 +32,7 @@ import org.springframework.util.Assert; ...@@ -28,6 +32,7 @@ import org.springframework.util.Assert;
* {@link MetricReader} along with memory information. * {@link MetricReader} along with memory information.
* *
* @author Dave Syer * @author Dave Syer
* @author Christian Dupuis
*/ */
public class VanillaPublicMetrics implements PublicMetrics { public class VanillaPublicMetrics implements PublicMetrics {
...@@ -44,13 +49,65 @@ public class VanillaPublicMetrics implements PublicMetrics { ...@@ -44,13 +49,65 @@ public class VanillaPublicMetrics implements PublicMetrics {
for (Metric<?> metric : this.reader.findAll()) { for (Metric<?> metric : this.reader.findAll()) {
result.add(metric); result.add(metric);
} }
addMetrics(result);
addHeapMetrics(result);
addThreadMetrics(result);
addClassLoadingMetrics(result);
return result;
}
/**
* Add basic system metrics.
*/
protected void addMetrics(Collection<Metric<?>> result) {
result.add(new Metric<Long>("mem", result.add(new Metric<Long>("mem",
new Long(Runtime.getRuntime().totalMemory()) / 1024)); new Long(Runtime.getRuntime().totalMemory()) / 1024));
result.add(new Metric<Long>("mem.free", new Long(Runtime.getRuntime() result.add(new Metric<Long>("mem.free", new Long(Runtime.getRuntime()
.freeMemory()) / 1024)); .freeMemory()) / 1024));
result.add(new Metric<Integer>("processors", Runtime.getRuntime() result.add(new Metric<Integer>("processors", Runtime.getRuntime()
.availableProcessors())); .availableProcessors()));
return result; // Add JVM uptime in ms
result.add(new Metric<Long>("uptime", new Long(ManagementFactory
.getRuntimeMXBean().getUptime())));
}
/**
* Add JVM heap metrics.
*/
protected void addHeapMetrics(Collection<Metric<?>> result) {
MemoryUsage memoryUsage = ManagementFactory.getMemoryMXBean()
.getHeapMemoryUsage();
result.add(new Metric<Long>("heap.committed", memoryUsage.getCommitted() / 1024));
result.add(new Metric<Long>("heap.init", memoryUsage.getInit() / 1024));
result.add(new Metric<Long>("heap.used", memoryUsage.getUsed() / 1024));
result.add(new Metric<Long>("heap", memoryUsage.getMax() / 1024));
}
/**
* Add thread metrics.
*/
protected void addThreadMetrics(Collection<Metric<?>> result) {
ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
result.add(new Metric<Long>("threads.peak", new Long(threadMxBean
.getPeakThreadCount())));
result.add(new Metric<Long>("threads.deamon", new Long(threadMxBean
.getDaemonThreadCount())));
result.add(new Metric<Long>("threads", new Long(threadMxBean.getThreadCount())));
}
/**
* Add class loading metrics.
*/
protected void addClassLoadingMetrics(Collection<Metric<?>> result) {
ClassLoadingMXBean classLoadingMxBean = ManagementFactory.getClassLoadingMXBean();
result.add(new Metric<Long>("classes", new Long(classLoadingMxBean
.getLoadedClassCount())));
result.add(new Metric<Long>("classes.loaded", new Long(classLoadingMxBean
.getTotalLoadedClassCount())));
result.add(new Metric<Long>("classes.unloaded", new Long(classLoadingMxBean
.getUnloadedClassCount())));
} }
} }
/* /*
* Copyright 2012-2013 the original author or authors. * Copyright 2012-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -32,6 +32,7 @@ import static org.junit.Assert.assertTrue; ...@@ -32,6 +32,7 @@ import static org.junit.Assert.assertTrue;
* Tests for {@link VanillaPublicMetrics}. * Tests for {@link VanillaPublicMetrics}.
* *
* @author Phillip Webb * @author Phillip Webb
* @author Christian Dupuis
*/ */
public class VanillaPublicMetricsTests { public class VanillaPublicMetricsTests {
...@@ -48,4 +49,32 @@ public class VanillaPublicMetricsTests { ...@@ -48,4 +49,32 @@ public class VanillaPublicMetricsTests {
assertTrue(results.containsKey("mem.free")); assertTrue(results.containsKey("mem.free"));
assertThat(results.get("a").getValue().doubleValue(), equalTo(0.5)); assertThat(results.get("a").getValue().doubleValue(), equalTo(0.5));
} }
@Test
public void testSystemMetrics() throws Exception {
InMemoryMetricRepository repository = new InMemoryMetricRepository();
repository.set(new Metric<Double>("a", 0.5, new Date()));
VanillaPublicMetrics publicMetrics = new VanillaPublicMetrics(repository);
Map<String, Metric<?>> results = new HashMap<String, Metric<?>>();
for (Metric<?> metric : publicMetrics.metrics()) {
results.put(metric.getName(), metric);
}
assertTrue(results.containsKey("mem"));
assertTrue(results.containsKey("mem.free"));
assertTrue(results.containsKey("processors"));
assertTrue(results.containsKey("uptime"));
assertTrue(results.containsKey("heap.committed"));
assertTrue(results.containsKey("heap.init"));
assertTrue(results.containsKey("heap.used"));
assertTrue(results.containsKey("heap"));
assertTrue(results.containsKey("threads.peak"));
assertTrue(results.containsKey("threads.deamon"));
assertTrue(results.containsKey("threads"));
assertTrue(results.containsKey("classes.loaded"));
assertTrue(results.containsKey("classes.unloaded"));
assertTrue(results.containsKey("classes"));
}
} }
...@@ -578,16 +578,27 @@ decrement). Metrics for all HTTP requests are automatically recorded, so if you ...@@ -578,16 +578,27 @@ decrement). Metrics for all HTTP requests are automatically recorded, so if you
"counter.status.401.root": 4, "counter.status.401.root": 4,
"gauge.response.root": 2, "gauge.response.root": 2,
"gauge.response.metrics": 3, "gauge.response.metrics": 3,
"mem": 466944, "classes": 5808,
"mem.free": 410117, "classes.loaded": 5808,
"processors": 8 "classes.unloaded": 0,
"heap": 3728384,
"heap.committed": 986624,
"heap.init": 262144,
"heap.used": 52765,
"mem": 986624,
"mem.free": 933858,
"processors": 8,
"threads": 15,
"threads.deamon": 11,
"threads.peak": 15,
"uptime": 494836
} }
---- ----
Here we can see basic `memory` and `processor` information along with some HTTP metrics. Here we can see basic `memory`, `heap`, `class loading`, `processor` and `thread pool`
In this instance the `root` (``/'') and `/metrics` URLs have returned `HTTP 200` responses information along with some HTTP metrics. In this instance the `root` (``/'') and `/metrics`
`20` and `3` times respectively. It also appears that the `root` URL returned `HTTP 401` URLs have returned `HTTP 200` responses `20` and `3` times respectively. It also appears
(unauthorized) `4` times. that the `root` URL returned `HTTP 401` (unauthorized) `4` times.
The `gauge` shows the last response time for a request. So the last request to `root` took The `gauge` shows the last response time for a request. So the last request to `root` took
`2ms` to respond and the last to `/metrics` took `3ms`. `2ms` to respond and the last to `/metrics` took `3ms`.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment