Skip to content

Commit 699a828

Browse files
committed
improve ProcessUtil impl
1 parent 9c68ebf commit 699a828

File tree

2 files changed

+57
-35
lines changed

2 files changed

+57
-35
lines changed

base-kv/base-kv-store-server/src/main/java/com/baidu/bifromq/basekv/store/util/ProcessUtil.java

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
package com.baidu.bifromq.basekv.store.util;
1515

16-
import io.micrometer.common.lang.Nullable;
1716
import java.lang.management.ManagementFactory;
1817
import java.lang.management.OperatingSystemMXBean;
1918
import java.lang.reflect.InvocationTargetException;
@@ -22,7 +21,47 @@
2221
import java.util.List;
2322

2423
public class ProcessUtil {
25-
private static final ProcessCpuLoad CPU_LOAD = new ProcessCpuLoad();
24+
private interface IProcessCpuLoad {
25+
double get();
26+
}
27+
28+
private static final List<String> OPERATING_SYSTEM_BEAN_CLASS_NAMES = Arrays.asList(
29+
"com.ibm.lang.management.OperatingSystemMXBean", // J9
30+
"com.sun.management.OperatingSystemMXBean" // HotSpot
31+
);
32+
33+
private static final List<String> POSSIBLE_METHODS =
34+
Arrays.asList("getProcessCpuLoad", "getSystemCpuLoad", "getCpuLoad");
35+
36+
private static final IProcessCpuLoad CPU_LOAD;
37+
38+
static {
39+
OperatingSystemMXBean operatingSystemBean = ManagementFactory.getOperatingSystemMXBean();
40+
Method method = null;
41+
for (String className : OPERATING_SYSTEM_BEAN_CLASS_NAMES) {
42+
try {
43+
Class<?> osBeanClass = Class.forName(className);
44+
// ensure the Bean we have is actually an instance of the interface
45+
osBeanClass.cast(operatingSystemBean);
46+
method = findMethod(osBeanClass);
47+
break;
48+
} catch (Throwable ignore) {
49+
}
50+
}
51+
if (method != null) {
52+
IProcessCpuLoad finalMethod = null;
53+
try {
54+
double load = (double) method.invoke(operatingSystemBean);
55+
finalMethod = new ProcessCpuLoad(operatingSystemBean, method);
56+
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
57+
finalMethod = () -> Double.NaN;
58+
} finally {
59+
CPU_LOAD = finalMethod;
60+
}
61+
} else {
62+
CPU_LOAD = () -> Double.NaN;
63+
}
64+
}
2665

2766
public static double cpuLoad() {
2867
return CPU_LOAD.get();
@@ -32,51 +71,34 @@ public static String processId() {
3271
return ManagementFactory.getRuntimeMXBean().getName();
3372
}
3473

35-
private static class ProcessCpuLoad {
36-
private static final List<String> OPERATING_SYSTEM_BEAN_CLASS_NAMES = Arrays.asList(
37-
"com.ibm.lang.management.OperatingSystemMXBean", // J9
38-
"com.sun.management.OperatingSystemMXBean" // HotSpot
39-
);
40-
41-
private static final List<String> POSSIBLE_METHODS =
42-
Arrays.asList("getProcessCpuLoad", "getSystemCpuLoad", "getCpuLoad");
74+
private static class ProcessCpuLoad implements IProcessCpuLoad {
4375
private final OperatingSystemMXBean operatingSystemBean;
4476

45-
@Nullable
4677
private final Method cpuUsageMethod;
4778

48-
ProcessCpuLoad() {
49-
this.operatingSystemBean = ManagementFactory.getOperatingSystemMXBean();
50-
Method method = null;
51-
for (String className : OPERATING_SYSTEM_BEAN_CLASS_NAMES) {
52-
try {
53-
Class<?> osBeanClass = Class.forName(className);
54-
// ensure the Bean we have is actually an instance of the interface
55-
osBeanClass.cast(operatingSystemBean);
56-
method = findMethod(osBeanClass);
57-
break;
58-
} catch (Throwable ignore) {
59-
}
60-
}
61-
this.cpuUsageMethod = method;
79+
private ProcessCpuLoad(OperatingSystemMXBean operatingSystemBean, Method cpuUsageMethod) {
80+
this.operatingSystemBean = operatingSystemBean;
81+
this.cpuUsageMethod = cpuUsageMethod;
6282
}
6383

64-
private double get() {
84+
85+
public double get() {
6586
try {
66-
return cpuUsageMethod != null ? (double) cpuUsageMethod.invoke(operatingSystemBean) : Double.NaN;
87+
double load = (double) cpuUsageMethod.invoke(operatingSystemBean);
88+
return load > 1.0 ? load / 100 : load;
6789
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
6890
return Double.NaN;
6991
}
7092
}
93+
}
7194

72-
private Method findMethod(Class<?> clazz) {
73-
for (String methodName : POSSIBLE_METHODS) {
74-
try {
75-
return clazz.getMethod(methodName);
76-
} catch (ClassCastException | NoSuchMethodException | SecurityException e) {
77-
}
95+
private static Method findMethod(Class<?> clazz) {
96+
for (String methodName : POSSIBLE_METHODS) {
97+
try {
98+
return clazz.getMethod(methodName);
99+
} catch (ClassCastException | NoSuchMethodException | SecurityException e) {
78100
}
79-
return null;
80101
}
102+
return null;
81103
}
82104
}

base-kv/base-kv-store-server/src/test/java/com/baidu/bifromq/basekv/store/util/ProcessUtilTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ public class ProcessUtilTest extends MockableTest {
2222
@Test
2323
public void cpuLoad() {
2424
double cpuLoad = ProcessUtil.cpuLoad();
25-
assertTrue((cpuLoad >= 0.0 && cpuLoad < 1.0) || Double.isNaN(cpuLoad));
25+
assertTrue((cpuLoad >= 0.0 && cpuLoad <= 1.0) || Double.isNaN(cpuLoad));
2626
}
2727
}

0 commit comments

Comments
 (0)