From 18d8b4c8a7ba6063dc8e24c486b721ad8acb0ab6 Mon Sep 17 00:00:00 2001 From: Carpenter Lee Date: Fri, 10 May 2019 14:20:00 +0800 Subject: [PATCH] Add CPU usage and system load to metric (#749) Signed-off-by: Carpenter Lee --- .../com/alibaba/csp/sentinel/Constants.java | 10 ++++ .../slots/system/SystemRuleManager.java | 1 + .../slots/system/SystemStatusListener.java | 6 -- .../handler/SendMetricCommandHandler.java | 56 +++++++++++++++++-- 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java index f4ff433e..f7ba9288 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java @@ -43,6 +43,16 @@ public final class Constants { */ public final static String TOTAL_IN_RESOURCE_NAME = "__total_inbound_traffic__"; + /** + * A virtual resource identifier for cpu usage statistics (since 1.6.1). + */ + public final static String CPU_USAGE_RESOURCE_NAME = "__cpu_usage__"; + + /** + * A virtual resource identifier for system load statistics (since 1.6.1). + */ + public final static String SYSTEM_LOAD_RESOURCE_NAME = "__system_load__"; + /** * Global ROOT statistic node that represents the universal parent node. */ diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java index 99b93a93..13be34de 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java @@ -222,6 +222,7 @@ public class SystemRuleManager { qps = Double.MAX_VALUE; highestSystemLoadIsSet = false; + highestCpuUsageIsSet = false; maxRtIsSet = false; maxThreadIsSet = false; qpsIsSet = false; diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemStatusListener.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemStatusListener.java index 8cf45a37..e02f0c85 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemStatusListener.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemStatusListener.java @@ -33,8 +33,6 @@ public class SystemStatusListener implements Runnable { volatile String reason = StringUtil.EMPTY; - static final int processor = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors(); - public double getSystemAverageLoad() { return currentLoad; } @@ -46,10 +44,6 @@ public class SystemStatusListener implements Runnable { @Override public void run() { try { - if (!SystemRuleManager.getCheckSystemStatus()) { - return; - } - OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class); currentLoad = osBean.getSystemLoadAverage(); /** diff --git a/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/SendMetricCommandHandler.java b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/SendMetricCommandHandler.java index e841004c..b3692e14 100755 --- a/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/SendMetricCommandHandler.java +++ b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/SendMetricCommandHandler.java @@ -15,18 +15,22 @@ */ package com.alibaba.csp.sentinel.command.handler; +import java.util.ArrayList; import java.util.List; +import com.alibaba.csp.sentinel.Constants; import com.alibaba.csp.sentinel.command.CommandHandler; import com.alibaba.csp.sentinel.command.CommandRequest; import com.alibaba.csp.sentinel.command.CommandResponse; import com.alibaba.csp.sentinel.command.annotation.CommandMapping; -import com.alibaba.csp.sentinel.util.PidUtil; import com.alibaba.csp.sentinel.config.SentinelConfig; -import com.alibaba.csp.sentinel.util.StringUtil; import com.alibaba.csp.sentinel.node.metric.MetricNode; import com.alibaba.csp.sentinel.node.metric.MetricSearcher; import com.alibaba.csp.sentinel.node.metric.MetricWriter; +import com.alibaba.csp.sentinel.slots.system.SystemRuleManager; +import com.alibaba.csp.sentinel.util.PidUtil; +import com.alibaba.csp.sentinel.util.StringUtil; +import com.alibaba.csp.sentinel.util.TimeUtil; /** * Retrieve and aggregate {@link MetricNode} metrics. @@ -34,7 +38,8 @@ import com.alibaba.csp.sentinel.node.metric.MetricWriter; * @author leyou * @author Eric Zhao */ -@CommandMapping(name = "metric", desc = "get and aggregate metrics, accept param: startTime={startTime}&endTime={endTime}&maxLines={maxLines}&identify={resourceName}") +@CommandMapping(name = "metric", desc = "get and aggregate metrics, accept param: " + + "startTime={startTime}&endTime={endTime}&maxLines={maxLines}&identify={resourceName}") public class SendMetricCommandHandler implements CommandHandler { private MetricSearcher searcher; @@ -83,9 +88,11 @@ public class SendMetricCommandHandler implements CommandHandler { } catch (Exception ex) { return CommandResponse.ofFailure(new RuntimeException("Error when retrieving metrics", ex)); } - if (list == null) { - return CommandResponse.ofSuccess("No metrics"); + list = new ArrayList<>(); + } + if (StringUtil.isBlank(identity)) { + addCpuUsageAndLoad(list); } StringBuilder sb = new StringBuilder(); for (MetricNode node : list) { @@ -93,4 +100,43 @@ public class SendMetricCommandHandler implements CommandHandler { } return CommandResponse.ofSuccess(sb.toString()); } + + /** + * add current cpu usage and load to the metric list. + * + * @param list metric list, should not be null + */ + private void addCpuUsageAndLoad(List list) { + long time = TimeUtil.currentTimeMillis() / 1000 * 1000; + double load = SystemRuleManager.getCurrentSystemAvgLoad(); + double usage = SystemRuleManager.getCurrentCpuUsage(); + if (load > 0) { + MetricNode loadNode = toNode(load, time, Constants.SYSTEM_LOAD_RESOURCE_NAME); + list.add(loadNode); + } + if (usage > 0) { + MetricNode usageNode = toNode(usage, time, Constants.CPU_USAGE_RESOURCE_NAME); + list.add(usageNode); + } + } + + /** + * transfer the value to a MetricNode, the value will multiply 10000 then truncate + * to long value, and as the {@link MetricNode#passQps}. + *

+ * This is an eclectic scheme before we have a standard metric format. + *

+ * + * @param value value to save. + * @param ts timestamp + * @param resource resource name. + * @return a MetricNode represents the value. + */ + private MetricNode toNode(double value, long ts, String resource) { + MetricNode node = new MetricNode(); + node.setPassQps((long)(value * 10000)); + node.setTimestamp(ts); + node.setResource(resource); + return node; + } }