|
|
@@ -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<String> { |
|
|
|
|
|
|
|
private MetricSearcher searcher; |
|
|
@@ -83,9 +88,11 @@ public class SendMetricCommandHandler implements CommandHandler<String> { |
|
|
|
} 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<String> { |
|
|
|
} |
|
|
|
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<MetricNode> 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}. |
|
|
|
* <p> |
|
|
|
* This is an eclectic scheme before we have a standard metric format. |
|
|
|
* </p> |
|
|
|
* |
|
|
|
* @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; |
|
|
|
} |
|
|
|
} |