优化监控

This commit is contained in:
zhouhao 2020-02-25 17:16:34 +08:00
parent ed40ec3045
commit 8d4f191d49
7 changed files with 307 additions and 66 deletions

View File

@ -8,7 +8,8 @@ import org.hswebframework.web.dict.EnumDict;
@Getter
public enum DefaultDashboardDefinition implements DashboardDefinition, EnumDict<String> {
systemMonitor("系统监控")
systemMonitor("系统监控"),
jvmMonitor("jvm监控")
;

View File

@ -0,0 +1,79 @@
package org.jetlinks.community.dashboard.measurements;
import org.hswebframework.utils.time.DateFormatter;
import org.jetlinks.core.metadata.ConfigMetadata;
import org.jetlinks.core.metadata.DataType;
import org.jetlinks.core.metadata.types.DoubleType;
import org.jetlinks.core.metadata.unit.UnifyUnit;
import org.jetlinks.community.dashboard.*;
import org.jetlinks.community.dashboard.supports.StaticMeasurement;
import org.jetlinks.community.dashboard.supports.StaticMeasurementProvider;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.Date;
import static java.math.BigDecimal.ROUND_HALF_UP;
/**
* 实时CPU 使用率监控
* <pre>
* /dashboard/systemMonitor/cpu/usage/realTime
* </pre>
*
* @author zhouhao
*/
@Component
public class JvmCpuMeasurementProvider
extends StaticMeasurementProvider {
public JvmCpuMeasurementProvider() {
super(DefaultDashboardDefinition.jvmMonitor, MonitorObjectDefinition.cpu);
addMeasurement(cpuUseAgeMeasurement);
}
static DataType type = new DoubleType().scale(1).min(0).max(100).unit(UnifyUnit.percent);
static StaticMeasurement cpuUseAgeMeasurement = new StaticMeasurement(CommonMeasurementDefinition.usage)
.addDimension(new CpuRealTimeMeasurementDimension());
static class CpuRealTimeMeasurementDimension implements MeasurementDimension {
@Override
public DimensionDefinition getDefinition() {
return CommonDimensionDefinition.realTime;
}
@Override
public DataType getValueType() {
return type;
}
@Override
public ConfigMetadata getParams() {
return null;
}
@Override
public boolean isRealTime() {
return true;
}
@Override
public Flux<MeasurementValue> getValue(MeasurementParameter parameter) {
//每秒获取系统CPU使用率
return Flux.interval(Duration.ofSeconds(1))
.map(t -> SimpleMeasurementValue.of(BigDecimal
.valueOf(SystemMonitor.jvmCpuUsage.getValue())
.setScale(1, ROUND_HALF_UP),
DateFormatter.toString(new Date(), "HH:mm:ss"),
System.currentTimeMillis()))
.cast(MeasurementValue.class);
}
}
}

View File

@ -0,0 +1,128 @@
package org.jetlinks.community.dashboard.measurements;
import lombok.Getter;
import lombok.Setter;
import org.hswebframework.utils.time.DateFormatter;
import org.jetlinks.core.metadata.ConfigMetadata;
import org.jetlinks.core.metadata.DataType;
import org.jetlinks.core.metadata.SimplePropertyMetadata;
import org.jetlinks.core.metadata.types.DoubleType;
import org.jetlinks.core.metadata.types.LongType;
import org.jetlinks.core.metadata.types.ObjectType;
import org.jetlinks.community.dashboard.*;
import org.jetlinks.community.dashboard.supports.StaticMeasurement;
import org.jetlinks.community.dashboard.supports.StaticMeasurementProvider;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.Date;
import static java.math.BigDecimal.ROUND_HALF_UP;
/**
* 实时内存使用率监控
* <pre>
* /dashboard/jvmMonitor/memory/info/realTime
* </pre>
*
* @author zhouhao
*/
@Component
public class JvmMemoryMeasurementProvider extends StaticMeasurementProvider {
public JvmMemoryMeasurementProvider() {
super(DefaultDashboardDefinition.jvmMonitor, MonitorObjectDefinition.memory);
addMeasurement(jvmMemoryInfo);
}
static ObjectType type = new ObjectType();
static {
{
SimplePropertyMetadata metadata = new SimplePropertyMetadata();
metadata.setId("max");
metadata.setName("最大值");
metadata.setValueType(new LongType());
type.addPropertyMetadata(metadata);
}
{
SimplePropertyMetadata metadata = new SimplePropertyMetadata();
metadata.setId("used");
metadata.setName("已使用");
metadata.setValueType(new LongType());
type.addPropertyMetadata(metadata);
}
{
SimplePropertyMetadata metadata = new SimplePropertyMetadata();
metadata.setId("usage");
metadata.setName("使用率");
metadata.setValueType(new DoubleType());
type.addPropertyMetadata(metadata);
}
}
static StaticMeasurement jvmMemoryInfo = new StaticMeasurement(CommonMeasurementDefinition.info)
.addDimension(new JvmMemoryInfoDimension());
static class JvmMemoryInfoDimension implements MeasurementDimension {
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
@Override
public DimensionDefinition getDefinition() {
return CommonDimensionDefinition.realTime;
}
@Override
public DataType getValueType() {
return type;
}
@Override
public ConfigMetadata getParams() {
return null;
}
@Override
public boolean isRealTime() {
return true;
}
@Override
public Flux<MeasurementValue> getValue(MeasurementParameter parameter) {
// TODO: 2020/1/15 性能优化
return Flux.interval(Duration.ofSeconds(1))
.map(t -> SimpleMeasurementValue.of(MemoryInfo.of(memoryMXBean.getHeapMemoryUsage()),
DateFormatter.toString(new Date(), "HH:mm:ss"),
System.currentTimeMillis()))
.cast(MeasurementValue.class);
}
}
@Getter
@Setter
public static class MemoryInfo {
private long max;
private long used;
private double usage;
public static MemoryInfo of(MemoryUsage usage) {
MemoryInfo info = new MemoryInfo();
info.max = (usage.getMax()) / 1000 / 1000;
info.used = usage.getUsed() / 1000 / 1000;
info.usage = BigDecimal.valueOf(((double) usage.getUsed() / usage.getMax()) * 100D).setScale(2, ROUND_HALF_UP)
.doubleValue();
return info;
}
}
}

View File

@ -6,7 +6,7 @@ import org.jetlinks.community.dashboard.ObjectDefinition;
@Getter
@AllArgsConstructor
public enum SystemObjectDefinition implements ObjectDefinition {
public enum MonitorObjectDefinition implements ObjectDefinition {
cpu("CPU"),
memory("内存");

View File

@ -1,6 +1,5 @@
package org.jetlinks.community.dashboard.measurements;
import lombok.SneakyThrows;
import org.hswebframework.utils.time.DateFormatter;
import org.jetlinks.core.metadata.ConfigMetadata;
import org.jetlinks.core.metadata.DataType;
@ -12,15 +11,9 @@ import org.jetlinks.community.dashboard.supports.StaticMeasurementProvider;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import static java.math.BigDecimal.ROUND_HALF_UP;
@ -37,7 +30,7 @@ public class SystemCpuMeasurementProvider
extends StaticMeasurementProvider {
public SystemCpuMeasurementProvider() {
super(DefaultDashboardDefinition.systemMonitor, SystemObjectDefinition.cpu);
super(DefaultDashboardDefinition.systemMonitor, MonitorObjectDefinition.cpu);
addMeasurement(cpuUseAgeMeasurement);
}
@ -46,39 +39,6 @@ public class SystemCpuMeasurementProvider
static StaticMeasurement cpuUseAgeMeasurement = new StaticMeasurement(CommonMeasurementDefinition.usage)
.addDimension(new CpuRealTimeMeasurementDimension());
static OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean();
static Callable<Double> processCpuUsage;
static Callable<Double> systemCpuUsage;
private static final List<String> OPERATING_SYSTEM_BEAN_CLASS_NAMES = Arrays.asList(
"com.sun.management.OperatingSystemMXBean", // HotSpot
"com.ibm.lang.management.OperatingSystemMXBean" // J9
);
static {
Class<?> mxBeanClass = null;
for (String s : OPERATING_SYSTEM_BEAN_CLASS_NAMES) {
try {
mxBeanClass = Class.forName(s);
} catch (Exception ignore) {
}
}
try {
if (mxBeanClass != null) {
Method method = mxBeanClass.getMethod("getProcessCpuLoad");
Method system = mxBeanClass.getMethod("getSystemCpuLoad");
processCpuUsage = () -> (double) method.invoke(osMxBean);
systemCpuUsage = () -> (double) system.invoke(osMxBean);
} else {
processCpuUsage = () -> 0D;
systemCpuUsage = () -> 0D;
}
} catch (Exception e) {
e.printStackTrace();
}
}
static class CpuRealTimeMeasurementDimension implements MeasurementDimension {
@ -102,21 +62,13 @@ public class SystemCpuMeasurementProvider
return true;
}
@SneakyThrows
public double getProcessCpu() {
return processCpuUsage.call() * 100;
}
@SneakyThrows
public double getSystemCpu() {
return systemCpuUsage.call() * 100;
}
@Override
public Flux<MeasurementValue> getValue(MeasurementParameter parameter) {
//每秒获取系统CPU使用率
return Flux.interval(Duration.ofSeconds(1))
.map(t -> SimpleMeasurementValue.of(BigDecimal.valueOf(getSystemCpu()).setScale(1, ROUND_HALF_UP),
.map(t -> SimpleMeasurementValue.of(BigDecimal
.valueOf(SystemMonitor.systemCpuUsage.getValue())
.setScale(1, ROUND_HALF_UP),
DateFormatter.toString(new Date(), "HH:mm:ss"),
System.currentTimeMillis()))
.cast(MeasurementValue.class);

View File

@ -17,7 +17,6 @@ import reactor.core.publisher.Flux;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.Date;
@ -35,8 +34,8 @@ import static java.math.BigDecimal.ROUND_HALF_UP;
@Component
public class SystemMemoryMeasurementProvider extends StaticMeasurementProvider {
public SystemMemoryMeasurementProvider() {
super(DefaultDashboardDefinition.systemMonitor, SystemObjectDefinition.memory);
addMeasurement(jvmMemoryInfo);
super(DefaultDashboardDefinition.systemMonitor, MonitorObjectDefinition.memory);
addMeasurement(systemMemoryInfo);
}
static ObjectType type = new ObjectType();
@ -68,13 +67,11 @@ public class SystemMemoryMeasurementProvider extends StaticMeasurementProvider {
}
static StaticMeasurement jvmMemoryInfo = new StaticMeasurement(CommonMeasurementDefinition.info)
static StaticMeasurement systemMemoryInfo = new StaticMeasurement(CommonMeasurementDefinition.info)
.addDimension(new JvmMemoryInfoDimension());
static class JvmMemoryInfoDimension implements MeasurementDimension {
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
@Override
public DimensionDefinition getDefinition() {
return CommonDimensionDefinition.realTime;
@ -97,9 +94,8 @@ public class SystemMemoryMeasurementProvider extends StaticMeasurementProvider {
@Override
public Flux<MeasurementValue> getValue(MeasurementParameter parameter) {
// TODO: 2020/1/15 性能优化
return Flux.interval(Duration.ofSeconds(1))
.map(t -> SimpleMeasurementValue.of(MemoryInfo.of(memoryMXBean.getHeapMemoryUsage()),
.map(t -> SimpleMeasurementValue.of(MemoryInfo.of(),
DateFormatter.toString(new Date(), "HH:mm:ss"),
System.currentTimeMillis()))
.cast(MeasurementValue.class);
@ -116,11 +112,13 @@ public class SystemMemoryMeasurementProvider extends StaticMeasurementProvider {
private double usage;
public static MemoryInfo of(MemoryUsage usage) {
public static MemoryInfo of() {
MemoryInfo info = new MemoryInfo();
info.max = (usage.getMax()) / 1000 / 1000;
info.used = usage.getUsed() / 1000 / 1000;
info.usage = BigDecimal.valueOf(((double) usage.getUsed() / usage.getMax()) / 100D).setScale(2, ROUND_HALF_UP)
long total = (long) SystemMonitor.totalSystemMemory.getValue();
info.max = total;
info.used = (long) (total - SystemMonitor.freeSystemMemory.getValue());
info.usage = BigDecimal.valueOf(((double)info.getUsed() / info.getMax()) * 100D).setScale(2, ROUND_HALF_UP)
.doubleValue();
return info;
}

View File

@ -0,0 +1,83 @@
package org.jetlinks.community.dashboard.measurements;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.SneakyThrows;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.function.Function;
@AllArgsConstructor
@Getter
public enum SystemMonitor {
systemCpuUsage("系统CPU使用率"),
jvmCpuUsage("JVM进程CPU使用率"),
freeSystemMemory("系统空闲内存"),
totalSystemMemory("系统总内存"),
openFileCount("已打开文件数"),
maxOpenFileCount("最大打开文件数"),
;
private String text;
public double getValue() {
return getValue(name());
}
static OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean();
private static Map<String, Callable<Double>> items = new HashMap<>();
private static final List<String> OPERATING_SYSTEM_BEAN_CLASS_NAMES = Arrays.asList(
"com.sun.management.OperatingSystemMXBean", // HotSpot
"com.ibm.lang.management.OperatingSystemMXBean" // J9
);
private static Callable<Double> zero = () -> 0D;
private static Class<?> mxBeanClass;
private static void register(String item, String methodName, Function<Double, Double> mapping) {
try {
Method method = mxBeanClass.getMethod(methodName);
items.put(item, () -> mapping.apply(((Number) method.invoke(osMxBean)).doubleValue()));
} catch (Exception e) {
}
}
static {
for (String s : OPERATING_SYSTEM_BEAN_CLASS_NAMES) {
try {
mxBeanClass = Class.forName(s);
} catch (Exception ignore) {
}
}
try {
if (mxBeanClass != null) {
register(systemCpuUsage.name(), "getSystemCpuLoad", usage -> usage * 100D);
register(jvmCpuUsage.name(), "getProcessCpuLoad", usage -> usage * 100D);
register(freeSystemMemory.name(), "getFreePhysicalMemorySize", val -> val / 1024 / 1024);
register(freeSystemMemory.name(), "getFreePhysicalMemorySize", val -> val / 1024 / 1024);
register(totalSystemMemory.name(), "getTotalPhysicalMemorySize", val -> val / 1024 / 1024);
register(openFileCount.name(), "getOpenFileDescriptorCount", Function.identity());
register(maxOpenFileCount.name(), "getMaxFileDescriptorCount", Function.identity());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@SneakyThrows
public static double getValue(String id) {
return items.getOrDefault(id, zero).call();
}
}