I would like to know is there a way to get the CPU Usage metrics with Spring Boot Actuator? Im able to see other metrics with /metrics and /health endpoints but not getting the CPU Usage. I want to avoid writing an extra class just to see the CPU Usage. Any idea? Thanks
-
The /metrics endpoint shows a load average of the machine. Is this what you are looking for ? A idle computer has a load average of 0. Each running process using or waiting for CPU resources adds 1 to the load average.rjdkolb– rjdkolb2016-12-20 06:39:26 +00:00Commented Dec 20, 2016 at 6:39
3 Answers
Just checked and I found this actuator... /actuator/metrics/process.cpu.usage
It outputs the following:
{
name: "process.cpu.usage",
description: "The "recent cpu usage" for the Java Virtual Machine process",
baseUnit: null,
measurements: [
{
statistic: "VALUE",
value: 0.0001742149747252696
}
],
availableTags: [ ]
}
Currently using Spring Boot version 2.2.2.RELEASE.
Comments
Spring Boot 2 actuator solution (building on @diginoise's code to measure CPU load), registering a Gauge with a function to measure the value when requested (no need to start Threads or schedule timers):
@Component
public class CpuMetrics {
private final static String METRICS_NAME = "process.cpu.load";
@Autowired
private MeterRegistry meterRegistry;
@PostConstruct
public void init() {
Gauge.builder(METRICS_NAME, this, CpuMetrics::getProcessCpuLoad)
.baseUnit("%")
.description("CPU Load")
.register(meterRegistry);
}
public Double getProcessCpuLoad() {
try {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = ObjectName.getInstance("java.lang:type=OperatingSystem");
AttributeList list = mbs.getAttributes(name, new String[]{"ProcessCpuLoad"});
return Optional.ofNullable(list)
.map(l -> l.isEmpty() ? null : l)
.map(List::iterator)
.map(Iterator::next)
.map(Attribute.class::cast)
.map(Attribute::getValue)
.map(Double.class::cast)
.orElse(null);
} catch (Exception ex) {
return null;
}
}
}
The CPU metrics will then be available at /actuator/metrics/process.cpu.load:
{
"name": "process.cpu.load",
"description": "CPU Load",
"baseUnit": "%",
"measurements": [
{
"statistic": "VALUE",
"value": 0.09767676212004521
}
],
"availableTags": []
}
3 Comments
"value": 0.09767676212004521 represents?Unfortunately there isn't a CPU metric available via Spring Boot Actuator.
Fortunately you could write your own.
Just create a measuring bean which fulfills the following:
It has access to
GaugeServiceas it will be tracking one value.@Autowired private GaugeService gaugeService;Creates a thread which calls routine to measure process' CPU load:
@PostConstruct public void startMeasuring() { new Thread() { @Override public void run() { gaugeService.submit("process.cpu.load", getProcessCpuLoad()); Thread.sleep(2000); //measure every 2sec. } }.start(); }Has a routine which gets CPU load for your process using MxBeans:
public static double getProcessCpuLoad() throws Exception { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ObjectName name = ObjectName.getInstance("java.lang:type=OperatingSystem"); AttributeList list = mbs.getAttributes(name, new String[]{ "ProcessCpuLoad" }); if (list.isEmpty()) return Double.NaN; Attribute att = (Attribute)list.get(0); Double value = (Double)att.getValue(); // usually takes a couple of seconds before we get real values if (value == -1.0) return Double.NaN; // returns a percentage value with 1 decimal point precision return ((int)(value * 1000) / 10.0); }
You could also extract the system wide CPU load using this method.
Hope this helps.