This is an automated email from the ASF dual-hosted git repository.

wuzhiguo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/bigtop-manager.git


The following commit(s) were added to refs/heads/main by this push:
     new aa5a320d BIGTOP-4296: Add API for cluster and host metrics (#119)
aa5a320d is described below

commit aa5a320d565eb43dcc810b489d972d562638b5f9
Author: chenwentao2024 <[email protected]>
AuthorDate: Tue Dec 31 14:26:15 2024 +0800

    BIGTOP-4296: Add API for cluster and host metrics (#119)
---
 .../manager/agent/metrics/MetricsCollector.java    |   2 +-
 ...oringController.java => MetricsController.java} |  37 +-
 .../manager/server/proxy/PrometheusProxy.java      | 587 ++++++++++++++-------
 ...{MonitoringService.java => MetricsService.java} |   6 +-
 ...ingServiceImpl.java => MetricsServiceImpl.java} |  12 +-
 .../bigtop/manager/server/utils/ProxyUtils.java    | 127 +++++
 ...trollerTest.java => MetricsControllerTest.java} |  16 +-
 7 files changed, 571 insertions(+), 216 deletions(-)

diff --git 
a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/metrics/MetricsCollector.java
 
b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/metrics/MetricsCollector.java
index 3053033a..2031a734 100644
--- 
a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/metrics/MetricsCollector.java
+++ 
b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/metrics/MetricsCollector.java
@@ -47,7 +47,7 @@ public class MetricsCollector {
     @Qualifier("diskIOMultiGauge") private MultiGauge diskIOMultiGauge;
 
     @Async
-    @Scheduled(cron = "*/10 * *  * * ?")
+    @Scheduled(cron = "0,30 * *  * * ?")
     public void collect() {
         // refresh agent host monitoring data
         scrape();
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/MonitoringController.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/MetricsController.java
similarity index 53%
rename from 
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/MonitoringController.java
rename to 
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/MetricsController.java
index 03ad663a..15870b57 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/MonitoringController.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/MetricsController.java
@@ -18,11 +18,13 @@
  */
 package org.apache.bigtop.manager.server.controller;
 
-import org.apache.bigtop.manager.server.service.MonitoringService;
+import org.apache.bigtop.manager.server.service.MetricsService;
 import org.apache.bigtop.manager.server.utils.ResponseEntity;
 
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import com.fasterxml.jackson.databind.JsonNode;
@@ -31,30 +33,31 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 
 import jakarta.annotation.Resource;
 
-@Tag(name = "Monitoring Controller")
+@Tag(name = "Metrics Controller")
 @RestController
-@RequestMapping("monitoring")
-public class MonitoringController {
+@RequestMapping("metrics")
+public class MetricsController {
 
     @Resource
-    private MonitoringService monitoringService;
+    private MetricsService metricsService;
 
-    @Operation(summary = "agent healthy", description = "agent healthy check")
-    @GetMapping("agenthealthy")
+    @Operation(summary = "hosts healthy", description = "hosts healthy check")
+    @GetMapping("hostshealthy")
     public ResponseEntity<JsonNode> agentHostsHealthyStatus() {
-        // json for response
-        return 
ResponseEntity.success(monitoringService.queryAgentsHealthyStatus());
+        return 
ResponseEntity.success(metricsService.queryAgentsHealthyStatus());
     }
 
-    @Operation(summary = "agent Info", description = "agent info query")
-    @GetMapping("agentinfo")
-    public ResponseEntity<JsonNode> queryAgentsInfo() {
-        return ResponseEntity.success(monitoringService.queryAgentsInfo());
+    @Operation(summary = "host info", description = "host info query")
+    @GetMapping("hosts/{id}")
+    public ResponseEntity<JsonNode> queryAgentInfo(
+            @RequestParam(value = "interval", defaultValue = "1m") String 
interval, @PathVariable String id) {
+        return 
ResponseEntity.success(metricsService.queryAgentsInfo(Long.valueOf(id), 
interval));
     }
 
-    @Operation(summary = "agent instant info", description = "agent instant 
info query")
-    @GetMapping("agentinstinfo")
-    public ResponseEntity<JsonNode> queryAgentsInstStatus() {
-        return 
ResponseEntity.success(monitoringService.queryAgentsInstStatus());
+    @Operation(summary = "cluster info", description = "cluster info query")
+    @GetMapping("clusters/{id}")
+    public ResponseEntity<JsonNode> queryCluster(
+            @RequestParam(value = "interval", defaultValue = "1m") String 
interval, @PathVariable String id) {
+        return 
ResponseEntity.success(metricsService.queryClustersInfo(Long.valueOf(id), 
interval));
     }
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/proxy/PrometheusProxy.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/proxy/PrometheusProxy.java
index e57f44f7..30920a27 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/proxy/PrometheusProxy.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/proxy/PrometheusProxy.java
@@ -18,6 +18,12 @@
  */
 package org.apache.bigtop.manager.server.proxy;
 
+import org.apache.bigtop.manager.dao.query.HostQuery;
+import org.apache.bigtop.manager.server.model.vo.HostVO;
+import org.apache.bigtop.manager.server.model.vo.PageVO;
+import org.apache.bigtop.manager.server.service.HostService;
+import org.apache.bigtop.manager.server.utils.ProxyUtils;
+
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Component;
@@ -30,12 +36,13 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import reactor.core.publisher.Mono;
 
+import jakarta.annotation.Resource;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
-import java.util.Set;
 
 @Component
 public class PrometheusProxy {
@@ -45,286 +52,504 @@ public class PrometheusProxy {
     @Value("${monitoring.agent-host-job-name}")
     private String agentHostJobName;
 
+    public static final String MEM_IDLE = "memIdle";
+    public static final String MEM_TOTAL = "memTotal";
+    public static final String DISK_IDLE = "diskFreeSpace";
+    public static final String DISK_TOTAL = "diskTotalSpace";
+    public static final String FILE_OPEN_DESCRIPTOR = "fileOpenDescriptor";
+    public static final String FILE_TOTAL_DESCRIPTOR = "fileTotalDescriptor";
+    public static final String CPU_LOAD_AVG_MIN_1 = "cpuLoadAvgMin_1";
+    public static final String CPU_LOAD_AVG_MIN_5 = "cpuLoadAvgMin_5";
+    public static final String CPU_LOAD_AVG_MIN_15 = "cpuLoadAvgMin_15";
+    public static final String CPU_USAGE = "cpuUsage";
+    public static final String PHYSICAL_CORES = "physical_cores";
+    public static final String DISK_READ = "diskRead";
+    public static final String DISK_WRITE = "diskWrite";
+
+    @Resource
+    private HostService hostService;
+
     public PrometheusProxy(
             WebClient.Builder webClientBuilder, 
@Value("${monitoring.prometheus-host}") String prometheusHost) {
         this.webClient = webClientBuilder.baseUrl(prometheusHost).build();
     }
-
-    public JsonNode queryAgentsHealthyStatus() {
+    /**
+     * Retrieve current data
+     */
+    public JsonNode query(String params) {
         Mono<JsonNode> body = webClient
                 .post()
                 .uri(uriBuilder -> uriBuilder.path("/api/v1/query").build())
                 .contentType(MediaType.APPLICATION_FORM_URLENCODED)
-                .body(BodyInserters.fromFormData("query", 
"up{job=\"%s\"}".formatted(agentHostJobName))
-                        .with("timeout", "10"))
+                .body(BodyInserters.fromFormData("query", 
params).with("timeout", "10"))
                 .retrieve()
                 .bodyToMono(JsonNode.class);
         JsonNode result = body.block();
-
-        ObjectMapper objectMapper = new ObjectMapper();
         if (result == null
                 || result.isEmpty()
                 || !"success".equals(result.get("status").asText("failure"))) {
-            return objectMapper.createObjectNode();
+            return null;
         }
-        JsonNode agents = result.get("data").get("result");
-        ArrayNode agentsHealthyStatus = objectMapper.createArrayNode();
-        for (JsonNode agent : agents) {
-            JsonNode agentStatus = agent.get("metric");
-            ObjectNode temp = objectMapper.createObjectNode();
-            temp.put("agentInfo", agentStatus.get("instance").asText());
-            temp.put("prometheusAgentJob", agentStatus.get("job").asText());
-            JsonNode status = agent.get("value");
-            LocalDateTime instant = 
Instant.ofEpochSecond(status.get(0).asLong())
-                    .atZone(ZoneId.systemDefault())
-                    .toLocalDateTime();
-            temp.put("time", instant.toString());
-            temp.put("agentHealthyStatus", status.get(1).asInt() == 1 ? 
"running" : "down");
-            agentsHealthyStatus.add(temp);
+        return result;
+    }
+    /**
+     * Retrieve data with a specified interval before the current time
+     */
+    public JsonNode queryRange(String query, long start, long end, String 
step) {
+        Mono<JsonNode> body = webClient
+                .post()
+                .uri(uriBuilder -> 
uriBuilder.path("/api/v1/query_range").build())
+                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
+                .body(BodyInserters.fromFormData("query", query)
+                        .with("timeout", "10")
+                        .with("start", String.valueOf(start))
+                        .with("end", String.valueOf(end))
+                        .with("step", step))
+                .retrieve()
+                .bodyToMono(JsonNode.class);
+        JsonNode result = body.block();
+        if (result == null
+                || result.isEmpty()
+                || !"success".equals(result.path("status").asText("failure"))) 
{
+            return null;
         }
-        return agentsHealthyStatus;
+        return result;
     }
 
-    private JsonNode queryAgents() {
-        JsonNode result = query("agent_host_monitoring_cpu");
+    /**
+     * query agents healthy
+     */
+    public JsonNode queryAgentsHealthyStatus() {
+        JsonNode result = query("up{job=\"%s\"}".formatted(agentHostJobName));
         ObjectMapper objectMapper = new ObjectMapper();
+        ArrayNode agentsHealthyStatus = objectMapper.createArrayNode();
         if (result != null) {
-            JsonNode agentCpus = result.get("data").get("result");
-            if (agentCpus.isArray() && !agentCpus.isEmpty()) {
-                Set<String> iPv4addrSet = new HashSet<>();
-                for (JsonNode agent : agentCpus) {
-                    
iPv4addrSet.add(agent.get("metric").get("iPv4addr").asText());
-                }
-                ArrayNode iPv4addrArray = objectMapper.createArrayNode();
-                for (String value : iPv4addrSet.toArray(new String[0])) {
-                    iPv4addrArray.add(value);
-                }
-                return objectMapper.createObjectNode().set("iPv4addr", 
iPv4addrArray); // iPv4
+            JsonNode agents = result.get("data").get("result");
+            for (JsonNode agent : agents) {
+                JsonNode agentStatus = agent.get("metric");
+                ObjectNode temp = objectMapper.createObjectNode();
+                temp.put("agentInfo", agentStatus.get("instance").asText());
+                temp.put("prometheusAgentJob", 
agentStatus.get("job").asText());
+                JsonNode status = agent.get("value");
+                LocalDateTime instant = 
Instant.ofEpochSecond(status.get(0).asLong())
+                        .atZone(ZoneId.systemDefault())
+                        .toLocalDateTime();
+                temp.put("time", instant.toString());
+                temp.put("agentHealthyStatus", status.get(1).asInt() == 1 ? 
"running" : "down");
+                agentsHealthyStatus.add(temp);
             }
+            return agentsHealthyStatus;
         }
         return objectMapper.createObjectNode();
     }
-
-    public JsonNode queryAgentsInfo() {
+    /**
+     * query agents info interval
+     */
+    public JsonNode queryAgentsInfo(Long id, String interval) {
         ObjectMapper objectMapper = new ObjectMapper();
-        ArrayNode agentsInfo = objectMapper.createArrayNode();
-        JsonNode agents = queryAgents().get("iPv4addr"); // get all host
-
-        for (JsonNode agent : agents) {
-            ObjectNode temp = objectMapper.createObjectNode();
-            JsonNode cpuResult = queryAgentCpu(agent.asText());
-            JsonNode memResult = queryAgentMemory(agent.asText());
-            JsonNode diskResult = queryAgentDisk(agent.asText());
-            // hostInfo
-            temp.put("hostname", cpuResult.get("hostname").asText());
-            temp.put("iPv4addr", cpuResult.get("iPv4addr").asText());
-            // temp.put("iPv6addr", cpuResult.get("iPv6addr").asText());
-            temp.put("cpuInfo", cpuResult.get("cpuInfo").asText().strip());
-            temp.put("time", cpuResult.get("time").asText());
-            temp.put("os", cpuResult.get("os").asText());
-            temp.put("architecture", cpuResult.get("architecture").asText());
-            temp.put("physical_cores", 
cpuResult.get("physical_cores").asText());
-            // MEM
-            temp.put("memIdle", memResult.get("memIdle").asLong());
-            temp.put("memTotal", memResult.get("memTotal").asLong());
-            // DISK
-            temp.set("diskSpace", diskResult.get("diskInfo"));
-            agentsInfo.add(temp);
-        }
+        String agentIpv4 = hostService.get(id).getIpv4();
+        if (!Objects.equals(agentIpv4, "")) {
+            ObjectNode ag = objectMapper.createObjectNode();
+            double[] agentsCpuUsage = new double[6];
+            double[] agentsCpuLoad1 = new double[6];
+            double[] agentsCpuLoad2 = new double[6];
+            double[] agentsCpuLoad3 = new double[6];
+            long[] agentMemIdle = new long[6];
+            long[] agentMemTotal = new long[6];
+            long[] agentDiskRead = new long[6];
+            long[] agentDiskWrite = new long[6];
 
-        return agentsInfo;
-    }
+            JsonNode agentCpu = retrieveAgentCpu(agentIpv4);
+            JsonNode agentMem = retrieveAgentMemory(agentIpv4);
+            JsonNode agentDisk = retrieveAgentDisk(agentIpv4);
+            JsonNode agentDiskIO = retrieveAgentDiskIO(agentIpv4);
+            JsonNode agentCpuInterval = retrieveAgentCpu(agentIpv4, interval);
+            JsonNode agentMemInterval = retrieveAgentMemory(agentIpv4, 
interval);
+            JsonNode agentDiskIOInterval = retrieveAgentDiskIO(agentIpv4, 
interval);
 
-    public JsonNode queryAgentsInstStatus() {
-        ObjectMapper objectMapper = new ObjectMapper();
-        ArrayNode agentsInfo = objectMapper.createArrayNode();
-        JsonNode agents = queryAgents().get("iPv4addr"); // get all host
-
-        for (JsonNode agent : agents) {
-            JsonNode cpuResult = queryAgentCpu(agent.asText());
-            JsonNode memResult = queryAgentMemory(agent.asText());
-            JsonNode diskResult = queryAgentDisk(agent.asText());
-            JsonNode diskIOResult = queryAgentDiskIO(agent.asText());
-            ObjectNode temp = objectMapper.createObjectNode();
-
-            // hostInfo
-            temp.put("hostname", cpuResult.get("hostname").asText());
-            temp.put("iPv4addr", cpuResult.get("iPv4addr").asText());
-            temp.put("cpuInfo", cpuResult.get("cpuInfo").asText().strip());
-            temp.put("time", cpuResult.get("time").asText());
-            temp.put("cpuLoadAvgMin_1", 
cpuResult.get("cpuLoadAvgMin_1").asDouble());
-            temp.put("cpuLoadAvgMin_5", 
cpuResult.get("cpuLoadAvgMin_5").asDouble());
-            temp.put("cpuLoadAvgMin_15", 
cpuResult.get("cpuLoadAvgMin_15").asDouble());
-            temp.put("cpuUsage", cpuResult.get("cpuUsage").asDouble());
-            temp.put("fileTotalDescriptor", 
cpuResult.get("fileTotalDescriptor").asLong());
-            temp.put("fileOpenDescriptor", 
cpuResult.get("fileOpenDescriptor").asLong());
-            // MEM
-            temp.put("memIdle", memResult.get("memIdle").asLong());
-            temp.put("memTotal", memResult.get("memTotal").asLong());
-            // DISK
-            temp.set("diskSpace", diskResult.get("diskInfo"));
-            // DISK IO
-            temp.set("diskIO", diskIOResult.get("diskIO"));
-            agentsInfo.add(temp);
-        }
+            // data process
+            for (int i = 0; i < 6; i++) {
+                // CPU
+                agentsCpuUsage[i] = 
ProxyUtils.getDoubleSafely(agentCpuInterval, CPU_USAGE, i);
+                agentsCpuLoad1[i] = 
ProxyUtils.getDoubleSafely(agentCpuInterval, CPU_LOAD_AVG_MIN_1, i);
+                agentsCpuLoad2[i] = 
ProxyUtils.getDoubleSafely(agentCpuInterval, CPU_LOAD_AVG_MIN_5, i);
+                agentsCpuLoad3[i] = 
ProxyUtils.getDoubleSafely(agentCpuInterval, CPU_LOAD_AVG_MIN_15, i);
+
+                // MEM
+                agentMemIdle[i] = ProxyUtils.getLongSafely(agentMemInterval, 
MEM_IDLE, i);
+                agentMemTotal[i] = ProxyUtils.getLongSafely(agentMemInterval, 
MEM_TOTAL, i);
+
+                // DISK IO
+                agentDiskRead[i] = 
ProxyUtils.getLongSafely(agentDiskIOInterval, DISK_READ, i);
+                agentDiskWrite[i] = 
ProxyUtils.getLongSafely(agentDiskIOInterval, DISK_WRITE, i);
+            }
 
-        return agentsInfo;
+            // cur
+            ag.put("cpuUsageCur", String.format("%.6f", 
agentCpu.get(CPU_USAGE).asDouble()));
+            ag.put(
+                    "memoryUsageCur",
+                    String.format(
+                            "%.6f",
+                            (double) (agentMem.get(MEM_TOTAL).asLong()
+                                            - agentMem.get(MEM_IDLE).asLong())
+                                    / agentMem.get(MEM_TOTAL).asLong()));
+            ag.put(
+                    "diskUsageCur",
+                    String.format(
+                            "%.6f",
+                            (double) (agentDisk.get(DISK_TOTAL).asLong()
+                                            - 
agentDisk.get(DISK_IDLE).asLong())
+                                    / agentDisk.get(DISK_TOTAL).asLong()));
+            ag.put(
+                    "fileDescriptorUsage",
+                    String.format(
+                            "%.6f",
+                            (double) 
agentCpu.get(FILE_OPEN_DESCRIPTOR).asLong()
+                                    / 
agentCpu.get(FILE_TOTAL_DESCRIPTOR).asLong()));
+            ag.put("diskReadCur", agentDiskIO.get(DISK_READ).asLong());
+            ag.put("diskWriteCur", agentDiskIO.get(DISK_WRITE).asLong());
+
+            // interval
+            ag.set("cpuUsage", ProxyUtils.array2node(agentsCpuUsage));
+            ag.set("systemLoad1", ProxyUtils.array2node(agentsCpuLoad1));
+            ag.set("systemLoad2", ProxyUtils.array2node(agentsCpuLoad2));
+            ag.set("systemLoad3", ProxyUtils.array2node(agentsCpuLoad3));
+            ag.set("memoryUsage", ProxyUtils.array2node(agentMemIdle, 
agentMemTotal));
+            ag.set("diskRead", ProxyUtils.array2node(agentDiskRead));
+            ag.set("diskWrite", ProxyUtils.array2node(agentDiskWrite));
+
+            return ag;
+        }
+        return objectMapper.createObjectNode();
     }
+    /**
+     * query clusters info interval
+     */
+    public JsonNode queryClustersInfo(Long clusterId, String interval) {
+        HostQuery hostQuery = new HostQuery();
+        hostQuery.setClusterId(clusterId);
+        PageVO<HostVO> hostPage = hostService.list(hostQuery); // query host 
list
+        List<HostVO> hostList = hostPage.getContent();
+        int agentsNum = Math.toIntExact(hostPage.getTotal()); // change to 
agentsNum
+        ObjectMapper objectMapper = new ObjectMapper();
+        if (agentsNum > 0) {
+            int totalPhysicalCores = 0;
+            long totalMemSpace = 0L, totalMemIdle = 0L;
+            double instantCpuUsage = 0.0;
+            double[][] agentsCpuUsage = new double[agentsNum][6];
+            double[][] agentsCpuLoad1 = new double[agentsNum][6];
+            double[][] agentsCpuLoad2 = new double[agentsNum][6];
+            double[][] agentsCpuLoad3 = new double[agentsNum][6];
+            long[][] agentMemIdle = new long[agentsNum][6];
+            long[][] agentMemTotal = new long[agentsNum][6];
 
-    public JsonNode query(String params) {
-        Mono<JsonNode> body = webClient
-                .post()
-                .uri("/api/v1/query")
-                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
-                .body(BodyInserters.fromFormData("query", 
params).with("timeout", "10"))
-                .retrieve()
-                .bodyToMono(JsonNode.class);
-        JsonNode result = body.block();
-        if (result == null
-                || result.isEmpty()
-                || !"success".equals(result.get("status").asText("failure"))) {
-            return null;
+            int agentIndex = 0;
+            ObjectNode clusterInfo = objectMapper.createObjectNode();
+            for (HostVO hostVO : hostList) {
+                String agentIpv4 = hostVO.getIpv4();
+                JsonNode agentCpu = retrieveAgentCpu(agentIpv4);
+                instantCpuUsage += agentCpu.get("cpuUsage").asDouble()
+                        * agentCpu.get(PHYSICAL_CORES).asInt();
+                JsonNode agentMem = retrieveAgentMemory(agentIpv4);
+                totalMemIdle += agentMem.get("memIdle").asLong();
+                totalMemSpace += agentMem.get(("memTotal")).asLong();
+                JsonNode agentCpuStep = retrieveAgentCpu(agentIpv4, interval);
+                JsonNode agentMemStep = retrieveAgentMemory(agentIpv4, 
interval);
+                int agentPhysicalCores = agentCpu.get(PHYSICAL_CORES).asInt();
+                totalPhysicalCores += agentPhysicalCores;
+
+                for (int i = 0; i < 6; i++) {
+                    // CPU
+                    agentsCpuUsage[agentIndex][i] =
+                            ProxyUtils.getDoubleSafely(agentCpuStep, 
CPU_USAGE, i) * agentPhysicalCores;
+                    agentsCpuLoad1[agentIndex][i] =
+                            ProxyUtils.getDoubleSafely(agentCpuStep, 
CPU_LOAD_AVG_MIN_1, i) * agentPhysicalCores;
+                    agentsCpuLoad2[agentIndex][i] =
+                            ProxyUtils.getDoubleSafely(agentCpuStep, 
CPU_LOAD_AVG_MIN_5, i) * agentPhysicalCores;
+                    agentsCpuLoad3[agentIndex][i] =
+                            ProxyUtils.getDoubleSafely(agentCpuStep, 
CPU_LOAD_AVG_MIN_15, i) * agentPhysicalCores;
+
+                    // MEM
+                    agentMemIdle[agentIndex][i] = 
ProxyUtils.getLongSafely(agentMemStep, MEM_IDLE, i);
+                    agentMemTotal[agentIndex][i] = 
ProxyUtils.getLongSafely(agentMemStep, MEM_TOTAL, i);
+                }
+
+                agentIndex++; // loop of agents
+            }
+            // cur
+            clusterInfo.put("cpuUsageCur", String.format("%.6f", 
instantCpuUsage / totalPhysicalCores));
+            clusterInfo.put(
+                    "memoryUsageCur", String.format("%.6f", (double) 
(totalMemSpace - totalMemIdle) / totalMemSpace));
+
+            // interval
+            clusterInfo.set("cpuUsage", ProxyUtils.array2node(agentsCpuUsage, 
totalPhysicalCores, agentsNum));
+            clusterInfo.set("systemLoad1", 
ProxyUtils.array2node(agentsCpuLoad1, totalPhysicalCores, agentsNum));
+            clusterInfo.set("systemLoad2", 
ProxyUtils.array2node(agentsCpuLoad2, totalPhysicalCores, agentsNum));
+            clusterInfo.set("systemLoad3", 
ProxyUtils.array2node(agentsCpuLoad3, totalPhysicalCores, agentsNum));
+            clusterInfo.set("memoryUsage", ProxyUtils.array2node(agentMemIdle, 
agentMemTotal, agentsNum));
+
+            return clusterInfo;
         }
-        return result;
+        return objectMapper.createObjectNode();
     }
 
-    public JsonNode queryAgentCpu(String iPv4addr) {
+    /**
+     * retrieve cpu
+     */
+    public JsonNode retrieveAgentCpu(String iPv4addr) {
         String params = 
String.format("agent_host_monitoring_cpu{iPv4addr=\"%s\"}", iPv4addr);
         JsonNode result = query(params);
         ObjectMapper objectMapper = new ObjectMapper();
         if (result != null) {
             JsonNode agentCpus = result.get("data").get("result");
             if (agentCpus.isArray() && !agentCpus.isEmpty()) {
+                // metric
                 JsonNode agentCpuMetric = agentCpus.get(0).get("metric");
-                JsonNode agentCpuValue = agentCpus.get(0).get("value");
                 ObjectNode agentInfo = objectMapper.createObjectNode();
                 agentInfo.put("hostname", 
agentCpuMetric.get("hostname").asText());
                 agentInfo.put("cpuInfo", 
agentCpuMetric.get("cpu_info").asText());
                 agentInfo.put("iPv4addr", 
agentCpuMetric.get("iPv4addr").asText());
-                // temp.put("iPv6addr", 
agentCpuMetric.get("iPv6addr").asText());
                 agentInfo.put("os", agentCpuMetric.get("os").asText());
                 agentInfo.put("architecture", 
agentCpuMetric.get("arch").asText());
+                agentInfo.put(PHYSICAL_CORES, 
agentCpuMetric.get(PHYSICAL_CORES).asText());
                 agentInfo.put(
-                        "physical_cores", 
agentCpuMetric.get("physical_cores").asText());
+                        FILE_OPEN_DESCRIPTOR,
+                        agentCpuMetric.get(FILE_OPEN_DESCRIPTOR).asLong());
                 agentInfo.put(
-                        "fileOpenDescriptor",
-                        agentCpuMetric.get("fileOpenDescriptor").asLong());
-                agentInfo.put(
-                        "fileTotalDescriptor",
-                        agentCpuMetric.get("fileTotalDescriptor").asLong());
-                LocalDateTime instant = Instant.ofEpochSecond(
-                                agentCpuValue.get(0).asLong())
-                        .atZone(ZoneId.systemDefault())
-                        .toLocalDateTime();
-                agentInfo.put("time", instant.toString());
+                        FILE_TOTAL_DESCRIPTOR,
+                        agentCpuMetric.get(FILE_TOTAL_DESCRIPTOR).asLong());
+
+                // value
                 for (JsonNode agent : agentCpus) {
                     agentInfo.put(
                             agent.get("metric").get("cpuUsage").asText(),
-                            agent.get("value").get(1).asDouble()); // cpu 
metric
+                            agent.get("value").get(1).asDouble());
                 }
                 return agentInfo;
             }
         }
         return objectMapper.createObjectNode();
     }
-
-    public JsonNode queryAgentMemory(String iPv4addr) {
+    /**
+     * retrieve cpu interval
+     */
+    public JsonNode retrieveAgentCpu(String iPv4addr, String interval) {
+        String params = 
String.format("agent_host_monitoring_cpu{iPv4addr=\"%s\"}", iPv4addr);
+        ArrayList<Long> timeStampsList = 
ProxyUtils.getTimeStampsList(ProxyUtils.processInternal(interval));
+        JsonNode result = queryRange(
+                params,
+                timeStampsList.get(timeStampsList.size() - 1),
+                timeStampsList.get(0),
+                
ProxyUtils.Number2Param(ProxyUtils.processInternal(interval))); // end start
         ObjectMapper objectMapper = new ObjectMapper();
+        if (result != null) {
+            JsonNode agentCpu = result.get("data").get("result");
+            if (agentCpu.isArray() && !agentCpu.isEmpty()) {
+                ObjectNode agentCpuInfo = objectMapper.createObjectNode();
+                // metric
+                JsonNode agentCpuMetrics = agentCpu.get(0).get("metric");
+                agentCpuInfo.put("hostname", 
agentCpuMetrics.get("hostname").asText());
+                agentCpuInfo.put("cpuInfo", 
agentCpuMetrics.get("cpu_info").asText());
+                agentCpuInfo.put("iPv4addr", 
agentCpuMetrics.get("iPv4addr").asText());
+                agentCpuInfo.put("os", agentCpuMetrics.get("os").asText());
+                agentCpuInfo.put("architecture", 
agentCpuMetrics.get("arch").asText());
+                agentCpuInfo.put(
+                        PHYSICAL_CORES, 
agentCpuMetrics.get(PHYSICAL_CORES).asInt());
+                agentCpuInfo.put(
+                        FILE_OPEN_DESCRIPTOR,
+                        agentCpuMetrics.get(FILE_OPEN_DESCRIPTOR).asLong());
+                agentCpuInfo.put(
+                        FILE_TOTAL_DESCRIPTOR,
+                        agentCpuMetrics.get(FILE_TOTAL_DESCRIPTOR).asLong());
+
+                // value
+                for (JsonNode cpuType : agentCpu) {
+                    JsonNode agentCpuValues = cpuType.get("values");
+                    ArrayNode cpuValues = objectMapper.createArrayNode();
+                    for (JsonNode stepValue : agentCpuValues) {
+                        cpuValues.add(stepValue.get(1).asDouble());
+                    }
+                    
agentCpuInfo.set(cpuType.get("metric").get("cpuUsage").asText(), cpuValues);
+                }
+                return agentCpuInfo;
+            }
+        }
+        return objectMapper.createObjectNode();
+    }
+
+    /**
+     * retrieve memory
+     */
+    public JsonNode retrieveAgentMemory(String iPv4addr) {
         String query = 
String.format("agent_host_monitoring_mem{iPv4addr=\"%s\"}", iPv4addr);
         JsonNode result = query(query);
+        ObjectMapper objectMapper = new ObjectMapper();
         if (result != null) {
             JsonNode agentsMem = result.get("data").get("result");
             if (agentsMem.isArray() && !agentsMem.isEmpty()) {
-                JsonNode agentMemValue = agentsMem.get(0).get("value");
+                ObjectNode agentsMemInfo = objectMapper.createObjectNode();
+                // metric
                 JsonNode agentMemMetric = agentsMem.get(0).get("metric");
-                ObjectNode agentsInfo = objectMapper.createObjectNode();
-                agentsInfo.put("hostname", 
agentMemMetric.get("hostname").asText());
-                agentsInfo.put("iPv4addr", 
agentMemMetric.get("iPv4addr").asText());
-                LocalDateTime instant = Instant.ofEpochSecond(
-                                agentMemValue.get(0).asLong())
-                        .atZone(ZoneId.systemDefault())
-                        .toLocalDateTime();
-                agentsInfo.put("time", instant.toString());
+                agentsMemInfo.put("hostname", 
agentMemMetric.get("hostname").asText());
+                agentsMemInfo.put("iPv4addr", 
agentMemMetric.get("iPv4addr").asText());
                 for (JsonNode agent : agentsMem) {
-                    agentsInfo.put(
+                    agentsMemInfo.put(
                             agent.get("metric").get("memUsage").asText(),
                             agent.get("value").get(1).asLong()); // mem metric
                 }
-                return agentsInfo;
+                return agentsMemInfo;
             }
         }
         return objectMapper.createObjectNode();
     }
-
-    public JsonNode queryAgentDisk(String iPv4addr) {
+    /**
+     * retrieve memory interval
+     */
+    public JsonNode retrieveAgentMemory(String iPv4addr, String interval) {
+        String params = 
String.format("agent_host_monitoring_mem{iPv4addr=\"%s\"}", iPv4addr);
+        ArrayList<Long> timeStampsList = 
ProxyUtils.getTimeStampsList(ProxyUtils.processInternal(interval));
+        JsonNode result = queryRange(
+                params,
+                timeStampsList.get(timeStampsList.size() - 1),
+                timeStampsList.get(0),
+                ProxyUtils.Number2Param(ProxyUtils.processInternal(interval)));
         ObjectMapper objectMapper = new ObjectMapper();
+        if (result != null) {
+            JsonNode agentMem = result.get("data").get("result");
+            if (agentMem.isArray() && !agentMem.isEmpty()) {
+                ObjectNode agentMemInfo = objectMapper.createObjectNode();
+                // metric
+                JsonNode agentMemMetrics = agentMem.get(0).get("metric");
+                agentMemInfo.put("hostname", 
agentMemMetrics.get("hostname").asText());
+                agentMemInfo.put("iPv4addr", 
agentMemMetrics.get("iPv4addr").asText());
+
+                // value
+                for (JsonNode stepAgent : agentMem) {
+                    JsonNode agentMemValues = stepAgent.get("values");
+                    ArrayNode memValues = objectMapper.createArrayNode();
+                    for (JsonNode value : agentMemValues) {
+                        memValues.add(value.get(1).asDouble());
+                    }
+                    
agentMemInfo.set(stepAgent.get("metric").get("memUsage").asText(), memValues);
+                }
+                return agentMemInfo;
+            }
+        }
+        return objectMapper.createObjectNode();
+    }
+
+    /**
+     * retrieve diskInfo
+     */
+    public JsonNode retrieveAgentDisk(String iPv4addr) {
         String params = 
String.format("agent_host_monitoring_disk{iPv4addr=\"%s\"}", iPv4addr);
         JsonNode result = query(params);
+        ObjectMapper objectMapper = new ObjectMapper();
         if (result != null) {
             JsonNode agentDisksResult = result.get("data").get("result");
             if (agentDisksResult.isArray() && !agentDisksResult.isEmpty()) {
-                JsonNode agentDisksMetric = 
agentDisksResult.get(0).get("metric");
-                JsonNode agentDisksValue = 
agentDisksResult.get(0).get("value");
                 ObjectNode agentDiskInfo = objectMapper.createObjectNode();
+                // metric
+                JsonNode agentDisksMetric = 
agentDisksResult.get(0).get("metric");
                 agentDiskInfo.put("hostname", 
agentDisksMetric.get("hostname").asText());
                 agentDiskInfo.put("iPv4addr", 
agentDisksMetric.get("iPv4addr").asText());
-                LocalDateTime instant = Instant.ofEpochSecond(
-                                agentDisksValue.get(0).asLong())
-                        .atZone(ZoneId.systemDefault())
-                        .toLocalDateTime();
-                agentDiskInfo.put("time", instant.toString());
-
-                ArrayNode tempDiskInfo = objectMapper.createArrayNode();
-                for (JsonNode agent : agentDisksResult) {
-                    JsonNode agentDisk = agent.get("metric");
-                    ObjectNode temp = objectMapper.createObjectNode();
-                    temp.put("diskName", agentDisk.get("diskUsage").asText());
-                    temp.put("diskUsage", agentDisk.get("diskUsage").asText());
-                    temp.put("diskValue", agent.get("value").get(1).asLong());
-                    tempDiskInfo.add(temp);
+
+                // value
+                Long diskTotalSpace = 0L, diskFreeSpace = 0L;
+                for (JsonNode disk : agentDisksResult) {
+                    if 
(Objects.equals(disk.get("metric").get("diskUsage").asText(), DISK_IDLE)) {
+                        diskFreeSpace += disk.get("value").get(1).asLong();
+                    } else {
+                        diskTotalSpace += disk.get("value").get(1).asLong();
+                    }
                 }
-                agentDiskInfo.set("diskInfo", tempDiskInfo);
+                agentDiskInfo.put(DISK_TOTAL, diskTotalSpace);
+                agentDiskInfo.put(DISK_IDLE, diskFreeSpace);
                 return agentDiskInfo;
             }
         }
         return objectMapper.createObjectNode();
     }
 
-    public JsonNode queryAgentDiskIO(String iPv4addr) {
-        ObjectMapper objectMapper = new ObjectMapper();
+    /**
+     * retrieve diskIO
+     */
+    public JsonNode retrieveAgentDiskIO(String iPv4addr) {
         String params = 
String.format("agent_host_monitoring_diskIO{iPv4addr=\"%s\"}", iPv4addr);
         JsonNode result = query(params);
+        ObjectMapper objectMapper = new ObjectMapper();
         if (result != null) {
             JsonNode agentDisksResult = result.get("data").get("result");
             if (agentDisksResult.isArray() && !agentDisksResult.isEmpty()) {
-                JsonNode agentDisksValue = 
agentDisksResult.get(0).get("value");
+                ObjectNode agentDiskIOInfo = objectMapper.createObjectNode();
+                // metric
                 JsonNode agentDisksMetric = 
agentDisksResult.get(0).get("metric");
+                agentDiskIOInfo
+                        .put("hostname", 
agentDisksMetric.get("hostname").asText())
+                        .put("iPv4addr", 
agentDisksMetric.get("iPv4addr").asText());
+
+                // value
+                long diskWrite = 0L;
+                long diskRead = 0L;
+                for (JsonNode disk : agentDisksResult) {
+                    if 
(Objects.equals(disk.get("metric").get("diskIO").asText(), DISK_WRITE)) {
+                        diskWrite += disk.get("value").get(1).asLong();
+                    } else {
+                        diskRead += disk.get("value").get(1).asLong();
+                    }
+                }
+                agentDiskIOInfo.put(DISK_WRITE, diskWrite);
+                agentDiskIOInfo.put(DISK_READ, diskRead);
+                return agentDiskIOInfo;
+            }
+        }
+        return objectMapper.createObjectNode();
+    }
+
+    /**
+     * retrieve diskIO interval
+     */
+    public JsonNode retrieveAgentDiskIO(String iPv4addr, String interval) {
+        String params = 
String.format("agent_host_monitoring_diskIO{iPv4addr=\"%s\"}", iPv4addr);
+        ArrayList<Long> timeStampsList = 
ProxyUtils.getTimeStampsList(ProxyUtils.processInternal(interval));
+        JsonNode result = queryRange(
+                params,
+                timeStampsList.get(timeStampsList.size() - 1),
+                timeStampsList.get(0),
+                ProxyUtils.Number2Param(ProxyUtils.processInternal(interval)));
+        ObjectMapper objectMapper = new ObjectMapper();
+        if (result != null) {
+            JsonNode agentDisksResult = result.get("data").get("result");
+            if (agentDisksResult.isArray() && !agentDisksResult.isEmpty()) {
                 ObjectNode agentDiskIOInfo = objectMapper.createObjectNode();
+                // metric
+                JsonNode agentDisksMetric = 
agentDisksResult.get(0).get("metric");
                 agentDiskIOInfo
                         .put("hostname", 
agentDisksMetric.get("hostname").asText())
                         .put("iPv4addr", 
agentDisksMetric.get("iPv4addr").asText());
-                LocalDateTime instant = Instant.ofEpochSecond(
-                                agentDisksValue.get(0).asLong())
-                        .atZone(ZoneId.systemDefault())
-                        .toLocalDateTime();
-                agentDiskIOInfo.put("time", instant.toString());
-
-                ArrayNode tempDiskInfo = objectMapper.createArrayNode();
-                for (JsonNode agent : agentDisksResult) {
-                    JsonNode agentDisk = agent.get("metric");
-                    ObjectNode temp = objectMapper.createObjectNode();
-                    temp.put(
-                            "physicalDiskName",
-                            agentDisk.get("physicalDiskName").asText());
-                    temp.put("physicalDiskUsage", 
agentDisk.get("diskIO").asText());
-                    if (Objects.equals(agentDisk.get("diskIO").asText(), 
"physicalDiskWrite")) {
-                        temp.put("physicalDiskWrite", 
agent.get("value").get(1).asLong());
+
+                // value
+                long[] diskWrite = new long[6];
+                long[] diskRead = new long[6];
+                for (JsonNode disk : agentDisksResult) {
+                    if 
(Objects.equals(disk.get("metric").get("diskIO").asText(), DISK_WRITE)) {
+                        for (int i = 0; i < 6; i++) {
+                            JsonNode listNode = disk.get("values");
+                            if (listNode != null && listNode.isArray() && i < 
listNode.size())
+                                diskWrite[i] += 
listNode.get(i).get(1).asLong();
+                            else diskWrite[i] += 0L;
+                        }
                     } else {
-                        temp.put("physicalDiskRead", 
agent.get("value").get(1).asLong());
+                        for (int i = 0; i < 6; i++) {
+                            JsonNode listNode = disk.get("values");
+                            if (listNode != null && listNode.isArray() && i < 
listNode.size())
+                                diskRead[i] += listNode.get(i).get(1).asLong();
+                            else diskRead[i] += 0L;
+                        }
                     }
-                    tempDiskInfo.add(temp);
                 }
-                agentDiskIOInfo.set("diskIO", tempDiskInfo);
+                agentDiskIOInfo.set(DISK_WRITE, 
ProxyUtils.array2node(diskWrite));
+                agentDiskIOInfo.set(DISK_READ, 
ProxyUtils.array2node(diskRead));
                 return agentDiskIOInfo;
             }
         }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MonitoringService.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
similarity index 86%
rename from 
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MonitoringService.java
rename to 
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
index ce6f82d4..23327b17 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MonitoringService.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
@@ -20,11 +20,11 @@ package org.apache.bigtop.manager.server.service;
 
 import com.fasterxml.jackson.databind.JsonNode;
 
-public interface MonitoringService {
+public interface MetricsService {
 
     JsonNode queryAgentsHealthyStatus();
 
-    JsonNode queryAgentsInfo();
+    JsonNode queryAgentsInfo(Long id, String interval);
 
-    JsonNode queryAgentsInstStatus();
+    JsonNode queryClustersInfo(Long clusterId, String interval);
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/MonitoringServiceImpl.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/MetricsServiceImpl.java
similarity index 77%
rename from 
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/MonitoringServiceImpl.java
rename to 
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/MetricsServiceImpl.java
index 38dde151..dff7728a 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/MonitoringServiceImpl.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/MetricsServiceImpl.java
@@ -19,7 +19,7 @@
 package org.apache.bigtop.manager.server.service.impl;
 
 import org.apache.bigtop.manager.server.proxy.PrometheusProxy;
-import org.apache.bigtop.manager.server.service.MonitoringService;
+import org.apache.bigtop.manager.server.service.MetricsService;
 
 import org.springframework.stereotype.Service;
 
@@ -30,7 +30,7 @@ import jakarta.annotation.Resource;
 
 @Slf4j
 @Service
-public class MonitoringServiceImpl implements MonitoringService {
+public class MetricsServiceImpl implements MetricsService {
 
     @Resource
     private PrometheusProxy prometheusProxy;
@@ -41,12 +41,12 @@ public class MonitoringServiceImpl implements 
MonitoringService {
     }
 
     @Override
-    public JsonNode queryAgentsInfo() {
-        return prometheusProxy.queryAgentsInfo();
+    public JsonNode queryAgentsInfo(Long id, String interval) {
+        return prometheusProxy.queryAgentsInfo(id, interval);
     }
 
     @Override
-    public JsonNode queryAgentsInstStatus() {
-        return prometheusProxy.queryAgentsInstStatus();
+    public JsonNode queryClustersInfo(Long clusterId, String interval) {
+        return prometheusProxy.queryClustersInfo(clusterId, interval);
     }
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/ProxyUtils.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/ProxyUtils.java
new file mode 100644
index 00000000..46b95d40
--- /dev/null
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/ProxyUtils.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bigtop.manager.server.utils;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+
+public class ProxyUtils {
+    public static double getDoubleSafely(JsonNode parentNode, String key, int 
index) {
+        JsonNode listNode = parentNode.get(key);
+        if (listNode != null && listNode.isArray() && index < listNode.size())
+            return listNode.get(index).asDouble();
+        return 0.0;
+    }
+
+    public static Long getLongSafely(JsonNode parentNode, String key, int 
index) {
+        JsonNode listNode = parentNode.get(key);
+        if (listNode != null && listNode.isArray() && index < listNode.size())
+            return listNode.get(index).asLong();
+        return 0L;
+    }
+
+    public static JsonNode array2node(double[][] array, int cores, int num) {
+        ObjectMapper mapper = new ObjectMapper();
+        double[] cache = new double[6];
+        for (int i = 0; i < num; i++) for (int j = 0; j < 6; j++) cache[j] += 
array[i][j];
+        ArrayNode node = mapper.createArrayNode();
+        for (int j = 0; j < 6; j++) node.add(String.format("%.6f", cache[j] / 
cores));
+        return node;
+    }
+
+    public static JsonNode array2node(double[] array) {
+        ArrayNode node = new ObjectMapper().createArrayNode();
+        for (int j = 0; j < 6; j++) node.add(String.format("%.6f", array[j]));
+        return node;
+    }
+
+    public static JsonNode array2node(long[] array) {
+        ArrayNode node = new ObjectMapper().createArrayNode();
+        for (int j = 0; j < 6; j++) node.add(array[j]);
+        return node;
+    }
+
+    public static JsonNode array2node(long[] array1, long[] array2) {
+        ArrayNode node = new ObjectMapper().createArrayNode();
+        for (int j = 0; j < 6; j++)
+            if (array2[j] <= 0) node.add(String.format("%.6f", 0.0));
+            else node.add(String.format("%.6f", (double) (array2[j] - 
array1[j]) / array2[j]));
+        return node;
+    }
+
+    public static JsonNode array2node(long[][] array1, long[][] array2, int 
num) {
+        ObjectMapper mapper = new ObjectMapper();
+        long[] cache1 = new long[6];
+        long[] cache2 = new long[6];
+        for (int i = 0; i < num; i++) {
+            for (int j = 0; j < 6; j++) {
+                cache1[j] += array1[i][j];
+                cache2[j] += array2[i][j];
+            }
+        }
+        ArrayNode node = mapper.createArrayNode();
+        // The data is sorted with earlier dates coming first and later dates 
following.
+        for (int j = 0; j < 6; j++)
+            if (cache2[j] <= 0) node.add(String.format("%.6f", 0.0));
+            else node.add(String.format("%.6f", (double) (cache2[j] - 
cache1[j]) / cache2[j]));
+        return node;
+    }
+
+    public static ArrayList<Long> getTimeStampsList(int step) {
+        // format
+        String currentTimeStr = 
LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
+        String currentDateStr = 
LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 
HH:mm:ss");
+        LocalDateTime currentDateTime = LocalDateTime.parse(currentDateStr + " 
" + currentTimeStr, formatter);
+        int roundedMinute = (currentDateTime.getMinute() / step) * step;
+        LocalDateTime roundedCurrentDateTime =
+                
currentDateTime.withMinute(roundedMinute).withSecond(0).withNano(0);
+        // get 8 point
+        ArrayList<Long> timestamps = new ArrayList<>();
+        ZoneId zid = ZoneId.systemDefault();
+        for (int i = 0; i < 7; i++) {
+            LocalDateTime pastTime = 
roundedCurrentDateTime.minus(Duration.ofMinutes((long) step * i));
+            long timestamp = pastTime.atZone(zid).toInstant().toEpochMilli() / 
1000L;
+            timestamps.add(timestamp);
+        }
+        return timestamps;
+    }
+
+    public static String Number2Param(int step) {
+        return String.format("%sm", step);
+    }
+
+    public static int processInternal(String internal) {
+        int inter = Integer.parseInt(internal.substring(0, internal.length() - 
1));
+        if (internal.endsWith("m")) return inter * 60;
+        else if (internal.endsWith("h")) {
+            return inter * 60 * 60;
+        }
+        return inter;
+    }
+}
diff --git 
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/MonitoringControllerTest.java
 
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/MetricsControllerTest.java
similarity index 82%
rename from 
bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/MonitoringControllerTest.java
rename to 
bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/MetricsControllerTest.java
index cc391a17..6e760c9b 100644
--- 
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/MonitoringControllerTest.java
+++ 
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/MetricsControllerTest.java
@@ -18,7 +18,7 @@
  */
 package org.apache.bigtop.manager.server.controller;
 
-import org.apache.bigtop.manager.server.service.MonitoringService;
+import org.apache.bigtop.manager.server.service.MetricsService;
 import org.apache.bigtop.manager.server.utils.MessageSourceUtils;
 import org.apache.bigtop.manager.server.utils.ResponseEntity;
 
@@ -42,13 +42,13 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.when;
 
 @ExtendWith(MockitoExtension.class)
-class MonitoringControllerTest {
+class MetricsControllerTest {
 
     @Mock
-    private MonitoringService monitoringService;
+    private MetricsService metricsService;
 
     @InjectMocks
-    private MonitoringController monitoringController;
+    private MetricsController metricsController;
 
     private MockedStatic<MessageSourceUtils> mockedMessageSourceUtils;
 
@@ -66,9 +66,9 @@ class MonitoringControllerTest {
     @Test
     void agentHostsHealthyStatusReturnsSuccess() {
         JsonNode mockResponse = new ObjectMapper().createObjectNode();
-        
when(monitoringService.queryAgentsHealthyStatus()).thenReturn(mockResponse);
+        
when(metricsService.queryAgentsHealthyStatus()).thenReturn(mockResponse);
 
-        ResponseEntity<JsonNode> response = 
monitoringController.agentHostsHealthyStatus();
+        ResponseEntity<JsonNode> response = 
metricsController.agentHostsHealthyStatus();
 
         assertTrue(response.isSuccess());
         assertEquals(mockResponse, response.getData());
@@ -76,9 +76,9 @@ class MonitoringControllerTest {
 
     @Test
     void agentHostsHealthyStatusReturnsEmptyResponse() {
-        when(monitoringService.queryAgentsHealthyStatus()).thenReturn(null);
+        when(metricsService.queryAgentsHealthyStatus()).thenReturn(null);
 
-        ResponseEntity<JsonNode> response = 
monitoringController.agentHostsHealthyStatus();
+        ResponseEntity<JsonNode> response = 
metricsController.agentHostsHealthyStatus();
 
         assertTrue(response.isSuccess());
         assertNull(response.getData());

Reply via email to