This is an automated email from the ASF dual-hosted git repository.
liuhaopeng 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 2b1da68e BIGTOP-4464: Optimize cluster/host metrics structure (#240)
2b1da68e is described below
commit 2b1da68e2526d33c8f9d0b27edb6f4941d547e16
Author: Zhiguo Wu <[email protected]>
AuthorDate: Fri Jul 11 23:17:21 2025 +0800
BIGTOP-4464: Optimize cluster/host metrics structure (#240)
---
.../agent/grpc/interceptor/TaskInterceptor.java | 18 +-
.../bigtop/manager/dao/repository/ServiceDao.java | 2 +
.../main/resources/mapper/mysql/ClusterMapper.xml | 3 +-
.../main/resources/mapper/mysql/ServiceMapper.xml | 8 +
.../resources/mapper/postgresql/ClusterMapper.xml | 3 +-
.../resources/mapper/postgresql/ServiceMapper.xml | 8 +
.../command/helper/ComponentStageHelper.java | 4 +-
.../server/controller/MetricsController.java | 27 +-
.../model/req/command/ServiceCommandReq.java | 2 +-
.../vo/ClusterMetricsVO.java} | 16 +-
.../vo/HostMetricsVO.java} | 25 +-
.../PrometheusData.java} | 14 +-
.../manager/server/prometheus/PrometheusProxy.java | 490 ++++++++++++++++++
.../PrometheusResponse.java} | 20 +-
.../PrometheusResult.java} | 20 +-
.../manager/server/proxy/PrometheusProxy.java | 547 ---------------------
.../manager/server/service/MetricsService.java | 9 +-
.../server/service/impl/ClusterServiceImpl.java | 3 +-
.../server/service/impl/MetricsServiceImpl.java | 24 +-
.../bigtop/manager/server/utils/ProxyUtils.java | 127 -----
.../server/controller/MetricsControllerTest.java | 35 +-
.../manager/server/service/ClusterServiceTest.java | 5 +-
.../manager/server/utils/ProxyUtilsTest.java | 217 --------
23 files changed, 641 insertions(+), 986 deletions(-)
diff --git
a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptor.java
b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptor.java
index 43f382ed..6d741433 100644
---
a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptor.java
+++
b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptor.java
@@ -43,11 +43,15 @@ public class TaskInterceptor implements ServerInterceptor {
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call, Metadata headers,
ServerCallHandler<ReqT, RespT> next) {
return new
ForwardingServerCallListener.SimpleForwardingServerCallListener<>(next.startCall(call,
headers)) {
+
+ private boolean taskRequest = false;
+
@Override
public void onMessage(ReqT message) {
super.onMessage(message);
+ taskRequest = isTaskRequest(message);
- if (isTaskRequest(message)) {
+ if (taskRequest) {
try {
Method method =
message.getClass().getDeclaredMethod("getTaskId");
Long taskId = (Long) method.invoke(message);
@@ -69,16 +73,20 @@ public class TaskInterceptor implements ServerInterceptor {
public void onCancel() {
super.onCancel();
- Caches.RUNNING_TASK = null;
- MDC.clear();
+ if (taskRequest) {
+ Caches.RUNNING_TASK = null;
+ MDC.clear();
+ }
}
@Override
public void onComplete() {
super.onComplete();
- Caches.RUNNING_TASK = null;
- MDC.clear();
+ if (taskRequest) {
+ Caches.RUNNING_TASK = null;
+ MDC.clear();
+ }
}
@Override
diff --git
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/ServiceDao.java
b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/ServiceDao.java
index 06a26808..accbdd40 100644
---
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/ServiceDao.java
+++
b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/ServiceDao.java
@@ -30,6 +30,8 @@ public interface ServiceDao extends BaseDao<ServicePO> {
List<ServicePO> findByQuery(@Param("query") ServiceQuery query);
+ int countByClusterId(@Param("clusterId") Long clusterId);
+
List<ServicePO> findByClusterId(@Param("clusterId") Long clusterId);
ServicePO findByClusterIdAndName(@Param("clusterId") Long clusterId,
@Param("name") String name);
diff --git
a/bigtop-manager-dao/src/main/resources/mapper/mysql/ClusterMapper.xml
b/bigtop-manager-dao/src/main/resources/mapper/mysql/ClusterMapper.xml
index df0035bc..80774122 100644
--- a/bigtop-manager-dao/src/main/resources/mapper/mysql/ClusterMapper.xml
+++ b/bigtop-manager-dao/src/main/resources/mapper/mysql/ClusterMapper.xml
@@ -36,11 +36,10 @@
<property name="alias" value="c"/>
</include>, u.nickname as create_user,
count(h.id) as total_host, sum(h.available_processors) as
total_processor,
- sum(h.total_memory_size) as total_memory, sum(h.total_disk) as
total_disk, count(s.id) as total_service
+ sum(h.total_memory_size) as total_memory, sum(h.total_disk) as
total_disk
from
cluster c left join user u on c.create_by = u.id
left join host h on c.id = h.cluster_id
- left join service s on c.id = s.cluster_id
where c.id = #{id}
limit 1
</select>
diff --git
a/bigtop-manager-dao/src/main/resources/mapper/mysql/ServiceMapper.xml
b/bigtop-manager-dao/src/main/resources/mapper/mysql/ServiceMapper.xml
index f1179956..7753c85c 100644
--- a/bigtop-manager-dao/src/main/resources/mapper/mysql/ServiceMapper.xml
+++ b/bigtop-manager-dao/src/main/resources/mapper/mysql/ServiceMapper.xml
@@ -52,6 +52,14 @@
</where>
</select>
+ <select id="countByClusterId" parameterType="java.lang.Long"
resultType="int">
+ select
+ count(*)
+ from service
+ where
+ cluster_id = #{clusterId}
+ </select>
+
<select id="findByClusterId" parameterType="java.lang.Long"
resultType="org.apache.bigtop.manager.dao.po.ServicePO">
select
<include refid="baseColumns" />
diff --git
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/ClusterMapper.xml
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ClusterMapper.xml
index 54986b93..09c277f5 100644
--- a/bigtop-manager-dao/src/main/resources/mapper/postgresql/ClusterMapper.xml
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ClusterMapper.xml
@@ -36,11 +36,10 @@
<property name="alias" value="c"/>
</include>, u.nickname as create_user,
count(h.id) as total_host, sum(h.available_processors) as
total_processor,
- sum(h.total_memory_size) as total_memory, sum(h.total_disk) as
total_disk, count(s.id) as total_service
+ sum(h.total_memory_size) as total_memory, sum(h.total_disk) as
total_disk
from
cluster c left join "user" u on c.create_by = u.id
left join host h on c.id = h.cluster_id
- left join service s on c.id = s.cluster_id
where c.id = #{id}
group by c.id, u.nickname
limit 1
diff --git
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/ServiceMapper.xml
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ServiceMapper.xml
index df383204..e86f6e67 100644
--- a/bigtop-manager-dao/src/main/resources/mapper/postgresql/ServiceMapper.xml
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ServiceMapper.xml
@@ -52,6 +52,14 @@
</where>
</select>
+ <select id="countByClusterId" parameterType="java.lang.Long"
resultType="int">
+ select
+ count(*)
+ from service
+ where
+ cluster_id = #{clusterId}
+ </select>
+
<select id="findByClusterId" parameterType="java.lang.Long"
resultType="org.apache.bigtop.manager.dao.po.ServicePO">
select
<include refid="baseColumns" />
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/helper/ComponentStageHelper.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/helper/ComponentStageHelper.java
index 49cddd16..ea4bb43a 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/helper/ComponentStageHelper.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/helper/ComponentStageHelper.java
@@ -99,13 +99,13 @@ public class ComponentStageHelper {
stages.add(new ComponentConfigureStage(stageContext));
break;
case INIT:
- stageContext = createStageContext(componentName,
hostnames, commandDTO);
+ stageContext = createStageContext(componentName,
List.of(hostnames.get(0)), commandDTO);
stages.add(new ComponentInitStage(stageContext));
break;
case PREPARE:
// Prepare phase runs after component started, client
component shouldn't create this.
if (!StackUtils.isClientComponent(componentName)) {
- stageContext = createStageContext(componentName,
hostnames, commandDTO);
+ stageContext = createStageContext(componentName,
List.of(hostnames.get(0)), commandDTO);
stages.add(new ComponentPrepareStage(stageContext));
}
break;
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/MetricsController.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/MetricsController.java
index 15870b57..65fb6a1e 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/MetricsController.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/MetricsController.java
@@ -18,6 +18,8 @@
*/
package org.apache.bigtop.manager.server.controller;
+import org.apache.bigtop.manager.server.model.vo.ClusterMetricsVO;
+import org.apache.bigtop.manager.server.model.vo.HostMetricsVO;
import org.apache.bigtop.manager.server.service.MetricsService;
import org.apache.bigtop.manager.server.utils.ResponseEntity;
@@ -27,7 +29,6 @@ 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;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -35,29 +36,23 @@ import jakarta.annotation.Resource;
@Tag(name = "Metrics Controller")
@RestController
-@RequestMapping("metrics")
+@RequestMapping("/metrics")
public class MetricsController {
@Resource
private MetricsService metricsService;
- @Operation(summary = "hosts healthy", description = "hosts healthy check")
- @GetMapping("hostshealthy")
- public ResponseEntity<JsonNode> agentHostsHealthyStatus() {
- return
ResponseEntity.success(metricsService.queryAgentsHealthyStatus());
- }
-
@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));
+ @GetMapping("/hosts/{id}")
+ public ResponseEntity<HostMetricsVO> queryAgentInfo(
+ @RequestParam(value = "interval", defaultValue = "1m") String
interval, @PathVariable Long id) {
+ return ResponseEntity.success(metricsService.queryAgentsInfo(id,
interval));
}
@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));
+ @GetMapping("/clusters/{id}")
+ public ResponseEntity<ClusterMetricsVO> queryCluster(
+ @RequestParam(value = "interval", defaultValue = "1m") String
interval, @PathVariable Long id) {
+ return ResponseEntity.success(metricsService.queryClustersInfo(id,
interval));
}
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/command/ServiceCommandReq.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/command/ServiceCommandReq.java
index 14c73043..0df9ea78 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/command/ServiceCommandReq.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/command/ServiceCommandReq.java
@@ -36,7 +36,7 @@ public class ServiceCommandReq {
@NotNull @Schema(description = "Service name", example = "zookeeper")
private String serviceName;
- @NotNull @Schema(description = "Whether the service is already installed",
example = "false")
+ @Schema(description = "Whether the service is already installed", example
= "false")
private Boolean installed;
@NotEmpty(groups =
{CommandGroupSequenceProvider.ServiceInstallCommandGroup.class})
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ClusterMetricsVO.java
similarity index 72%
copy from
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
copy to
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ClusterMetricsVO.java
index 23327b17..a597849d 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ClusterMetricsVO.java
@@ -16,15 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.bigtop.manager.server.service;
+package org.apache.bigtop.manager.server.model.vo;
-import com.fasterxml.jackson.databind.JsonNode;
+import lombok.Data;
-public interface MetricsService {
+import java.util.List;
- JsonNode queryAgentsHealthyStatus();
+@Data
+public class ClusterMetricsVO {
- JsonNode queryAgentsInfo(Long id, String interval);
+ private String cpuUsageCur;
+ private String memoryUsageCur;
- JsonNode queryClustersInfo(Long clusterId, String interval);
+ private List<String> timestamps;
+ private List<String> cpuUsage;
+ private List<String> memoryUsage;
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/HostMetricsVO.java
similarity index 56%
copy from
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
copy to
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/HostMetricsVO.java
index 23327b17..b52b09f6 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/HostMetricsVO.java
@@ -16,15 +16,28 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.bigtop.manager.server.service;
+package org.apache.bigtop.manager.server.model.vo;
-import com.fasterxml.jackson.databind.JsonNode;
+import lombok.Data;
-public interface MetricsService {
+import java.util.List;
- JsonNode queryAgentsHealthyStatus();
+@Data
+public class HostMetricsVO {
- JsonNode queryAgentsInfo(Long id, String interval);
+ private String cpuUsageCur;
+ private String memoryUsageCur;
+ private String diskUsageCur;
+ private String fileDescriptorUsage;
+ private String diskReadCur;
+ private String diskWriteCur;
- JsonNode queryClustersInfo(Long clusterId, String interval);
+ private List<String> timestamps;
+ private List<String> cpuUsage;
+ private List<String> systemLoad1;
+ private List<String> systemLoad5;
+ private List<String> systemLoad15;
+ private List<String> memoryUsage;
+ private List<String> diskRead;
+ private List<String> diskWrite;
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusData.java
similarity index 73%
copy from
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
copy to
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusData.java
index 23327b17..33a499eb 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusData.java
@@ -16,15 +16,17 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.bigtop.manager.server.service;
+package org.apache.bigtop.manager.server.prometheus;
-import com.fasterxml.jackson.databind.JsonNode;
+import lombok.Data;
-public interface MetricsService {
+import java.util.List;
- JsonNode queryAgentsHealthyStatus();
+@Data
+public class PrometheusData {
- JsonNode queryAgentsInfo(Long id, String interval);
+ // "matrix" | "vector" | "scalar" | "string",
+ private String resultType;
- JsonNode queryClustersInfo(Long clusterId, String interval);
+ private List<PrometheusResult> result;
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusProxy.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusProxy.java
new file mode 100644
index 00000000..07984207
--- /dev/null
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusProxy.java
@@ -0,0 +1,490 @@
+/*
+ * 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.prometheus;
+
+import org.apache.bigtop.manager.server.model.vo.ClusterMetricsVO;
+import org.apache.bigtop.manager.server.model.vo.HostMetricsVO;
+
+import org.springframework.http.MediaType;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+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;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public class PrometheusProxy {
+
+ private final WebClient webClient;
+
+ 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";
+
+ private static final ThreadLocal<List<String>> timestampCache =
ThreadLocal.withInitial(ArrayList::new);
+
+ public PrometheusProxy(String prometheusHost, Integer prometheusPort) {
+ this.webClient = WebClient.builder()
+ .baseUrl("http://" + prometheusHost + ":" + prometheusPort)
+ .build();
+ }
+
+ public PrometheusResponse query(String params) {
+ return webClient
+ .post()
+ .uri(uriBuilder -> uriBuilder.path("/api/v1/query").build())
+ .contentType(MediaType.APPLICATION_FORM_URLENCODED)
+ .body(BodyInserters.fromFormData("query",
params).with("timeout", "10"))
+ .retrieve()
+ .bodyToMono(PrometheusResponse.class)
+ .block();
+ }
+
+ public PrometheusResponse queryRange(String query, String start, String
end, String step) {
+ return 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", start)
+ .with("end", end)
+ .with("step", step))
+ .retrieve()
+ .bodyToMono(PrometheusResponse.class)
+ .block();
+ }
+
+ public HostMetricsVO queryAgentsInfo(String agentIpv4, String interval) {
+ timestampCache.set(getTimestampsList(processInternal(interval)));
+
+ HostMetricsVO res = new HostMetricsVO();
+ if (!agentIpv4.isBlank()) {
+ // Instant metrics
+ Map<String, BigDecimal> agentCpu = retrieveAgentCpu(agentIpv4);
+ Map<String, BigDecimal> agentMem = retrieveAgentMemory(agentIpv4);
+ Map<String, BigDecimal> agentDisk = retrieveAgentDisk(agentIpv4);
+ Map<String, BigDecimal> agentDiskIO =
retrieveAgentDiskIO(agentIpv4);
+
+ // Use physical cores to check if the metrics is starting collect
+ if (!agentCpu.containsKey(PHYSICAL_CORES)) {
+ return res;
+ }
+
+ res.setCpuUsageCur(
+ agentCpu.get(CPU_USAGE).multiply(new
BigDecimal("100")).toString());
+
res.setMemoryUsageCur((agentMem.get(MEM_TOTAL).subtract(agentMem.get(MEM_IDLE)))
+ .divide(agentMem.get(MEM_TOTAL), 4, RoundingMode.HALF_UP)
+ .multiply(new BigDecimal("100"))
+ .toString());
+ res.setDiskUsageCur(agentDisk
+ .get(DISK_TOTAL)
+ .subtract(agentDisk.get(DISK_IDLE))
+ .divide(agentDisk.get(DISK_TOTAL), 4, RoundingMode.HALF_UP)
+ .multiply(new BigDecimal("100"))
+ .toString());
+ res.setFileDescriptorUsage(agentCpu.get(FILE_OPEN_DESCRIPTOR)
+ .divide(agentCpu.get(FILE_TOTAL_DESCRIPTOR), 4,
RoundingMode.HALF_UP)
+ .multiply(new BigDecimal("100"))
+ .toString());
+ res.setDiskReadCur(agentDiskIO.get(DISK_READ).toString());
+ res.setDiskWriteCur(agentDiskIO.get(DISK_WRITE).toString());
+
+ // Range metrics
+ Map<String, List<BigDecimal>> agentCpuInterval =
retrieveAgentCpu(agentIpv4, interval);
+ Map<String, List<BigDecimal>> agentMemInterval =
retrieveAgentMemory(agentIpv4, interval);
+ Map<String, List<BigDecimal>> agentDiskIOInterval =
retrieveAgentDiskIO(agentIpv4, interval);
+
+ res.setCpuUsage(convertList(agentCpuInterval.get(CPU_USAGE), 100));
+
res.setSystemLoad1(convertList(agentCpuInterval.get(CPU_LOAD_AVG_MIN_1)));
+
res.setSystemLoad5(convertList(agentCpuInterval.get(CPU_LOAD_AVG_MIN_5)));
+
res.setSystemLoad15(convertList(agentCpuInterval.get(CPU_LOAD_AVG_MIN_15)));
+ res.setMemoryUsage(convertList(agentMemInterval.get("memUsage"),
100));
+ res.setDiskRead(convertList(agentDiskIOInterval.get(DISK_READ)));
+ res.setDiskWrite(convertList(agentDiskIOInterval.get(DISK_WRITE)));
+ }
+
+ res.setTimestamps(timestampCache.get());
+ timestampCache.remove();
+ return res;
+ }
+
+ public ClusterMetricsVO queryClustersInfo(List<String> agentIpv4s, String
interval) {
+ timestampCache.set(getTimestampsList(processInternal(interval)));
+
+ ClusterMetricsVO res = new ClusterMetricsVO();
+ if (!agentIpv4s.isEmpty()) {
+ BigDecimal totalPhysicalCores = new BigDecimal("0.0");
+ BigDecimal totalMemSpace = new BigDecimal("0.0");
+
+ BigDecimal usedPhysicalCores = new BigDecimal("0.0");
+ BigDecimal totalMemIdle = new BigDecimal("0.0");
+
+ List<BigDecimal> timeUsedCores = getEmptyList();
+ List<BigDecimal> timeMemIdle = getEmptyList();
+
+ for (String agentIpv4 : agentIpv4s) {
+ // Instant Metrics
+ Map<String, BigDecimal> agentCpu = retrieveAgentCpu(agentIpv4);
+ Map<String, BigDecimal> agentMem =
retrieveAgentMemory(agentIpv4);
+
+ // Use physical cores to check if the metrics is starting
collect
+ if (!agentCpu.containsKey(PHYSICAL_CORES)) {
+ return res;
+ }
+
+ BigDecimal cpuUsage = agentCpu.get(CPU_USAGE);
+ BigDecimal physicalCores = agentCpu.get(PHYSICAL_CORES);
+ BigDecimal usedCores = cpuUsage.multiply(physicalCores);
+ BigDecimal memIdle = agentMem.get(MEM_IDLE);
+ BigDecimal memTotal = agentMem.get(MEM_TOTAL);
+
+ totalPhysicalCores = totalPhysicalCores.add(physicalCores);
+ usedPhysicalCores = usedPhysicalCores.add(usedCores);
+ totalMemIdle = totalMemIdle.add(memIdle);
+ totalMemSpace = totalMemSpace.add(memTotal);
+
+ // Range Metrics
+ List<BigDecimal> cpuUsageInterval =
+ retrieveAgentCpu(agentIpv4, interval).get(CPU_USAGE);
+ for (int i = 0; i < cpuUsageInterval.size(); i++) {
+ BigDecimal c = cpuUsageInterval.get(i);
+ if (c != null) {
+ c = c.multiply(physicalCores);
+ BigDecimal b = timeUsedCores.get(i);
+ if (b == null) {
+ b = new BigDecimal("0.0");
+ }
+
+ timeUsedCores.set(i, c.add(b));
+ }
+ }
+
+ List<BigDecimal> memIdleInterval =
+ retrieveAgentMemory(agentIpv4, interval).get(MEM_IDLE);
+ for (int i = 0; i < memIdleInterval.size(); i++) {
+ BigDecimal m = memIdleInterval.get(i);
+ if (m != null) {
+ BigDecimal b = timeMemIdle.get(i);
+ if (b == null) {
+ b = new BigDecimal("0.0");
+ }
+
+ timeMemIdle.set(i, m.add(b));
+ }
+ }
+ }
+
+ // Instant Metrics
+ res.setCpuUsageCur(usedPhysicalCores
+ .divide(totalPhysicalCores, 4, RoundingMode.HALF_UP)
+ .multiply(new BigDecimal("100"))
+ .toString());
+ res.setMemoryUsageCur(totalMemSpace
+ .subtract(totalMemIdle)
+ .divide(totalMemSpace, 4, RoundingMode.HALF_UP)
+ .multiply(new BigDecimal("100"))
+ .toString());
+
+ // Range Metrics
+ List<BigDecimal> cpuUsageList = getEmptyList();
+ List<BigDecimal> memUsageList = getEmptyList();
+
+ for (int i = 0; i < timeUsedCores.size(); i++) {
+ BigDecimal usedCores = timeUsedCores.get(i);
+ if (usedCores != null) {
+ usedCores = usedCores.divide(totalPhysicalCores, 4,
RoundingMode.HALF_UP);
+ cpuUsageList.set(i, usedCores);
+ }
+ }
+
+ for (int i = 0; i < timeMemIdle.size(); i++) {
+ BigDecimal memIdle = timeMemIdle.get(i);
+ if (memIdle != null) {
+ memIdle =
totalMemSpace.subtract(memIdle).divide(totalMemSpace, 4, RoundingMode.HALF_UP);
+ memUsageList.set(i, memIdle);
+ }
+ }
+
+ res.setCpuUsage(convertList(cpuUsageList, 100));
+ res.setMemoryUsage(convertList(memUsageList, 100));
+ }
+
+ res.setTimestamps(timestampCache.get());
+ timestampCache.remove();
+ return res;
+ }
+
+ public Map<String, BigDecimal> retrieveAgentCpu(String iPv4addr) {
+ Map<String, BigDecimal> map = new HashMap<>();
+ String params =
String.format("agent_host_monitoring_cpu{iPv4addr=\"%s\"}", iPv4addr);
+ PrometheusResponse response = query(params);
+ for (PrometheusResult result : response.getData().getResult()) {
+ String key = result.getMetric().get("cpuUsage");
+ map.put(key, new BigDecimal(result.getValue().get(1)));
+ }
+
+ // Get common metrics
+ if (!CollectionUtils.isEmpty(response.getData().getResult())) {
+ Map<String, String> metric =
response.getData().getResult().get(0).getMetric();
+ map.put(PHYSICAL_CORES, new
BigDecimal(metric.get(PHYSICAL_CORES)));
+ map.put(FILE_OPEN_DESCRIPTOR, new
BigDecimal(metric.get(FILE_OPEN_DESCRIPTOR)));
+ map.put(FILE_TOTAL_DESCRIPTOR, new
BigDecimal(metric.get(FILE_TOTAL_DESCRIPTOR)));
+ }
+
+ return map;
+ }
+
+ public Map<String, List<BigDecimal>> retrieveAgentCpu(String iPv4addr,
String interval) {
+ List<String> timestamps = timestampCache.get();
+ Map<String, List<BigDecimal>> map = new HashMap<>();
+ String params =
String.format("agent_host_monitoring_cpu{iPv4addr=\"%s\"}", iPv4addr);
+ PrometheusResponse response = queryRange(
+ params,
+ timestamps.get(0),
+ timestamps.get(timestamps.size() - 1),
+ number2Param(processInternal(interval)));
+
+ for (PrometheusResult result : response.getData().getResult()) {
+ String key = result.getMetric().get("cpuUsage");
+ List<BigDecimal> list = map.computeIfAbsent(key, k ->
getEmptyList());
+ for (List<String> value : result.getValues()) {
+ String timestamp = value.get(0);
+ int index = timestamps.indexOf(timestamp);
+ list.set(index, new BigDecimal(value.get(1)));
+ }
+ }
+
+ return map;
+ }
+
+ public Map<String, BigDecimal> retrieveAgentMemory(String iPv4addr) {
+ Map<String, BigDecimal> map = new HashMap<>();
+ String params =
String.format("agent_host_monitoring_mem{iPv4addr=\"%s\"}", iPv4addr);
+ PrometheusResponse response = query(params);
+ for (PrometheusResult result : response.getData().getResult()) {
+ String key = result.getMetric().get("memUsage");
+ map.put(key, new BigDecimal(result.getValue().get(1)));
+ }
+
+ return map;
+ }
+
+ public Map<String, List<BigDecimal>> retrieveAgentMemory(String iPv4addr,
String interval) {
+ List<String> timestamps = timestampCache.get();
+ Map<String, List<BigDecimal>> map = new HashMap<>();
+ String params =
String.format("agent_host_monitoring_mem{iPv4addr=\"%s\"}", iPv4addr);
+ PrometheusResponse response = queryRange(
+ params,
+ timestamps.get(0),
+ timestamps.get(timestamps.size() - 1),
+ number2Param(processInternal(interval)));
+
+ for (PrometheusResult result : response.getData().getResult()) {
+ String key = result.getMetric().get("memUsage");
+ List<BigDecimal> list = map.computeIfAbsent(key, k ->
getEmptyList());
+ for (List<String> value : result.getValues()) {
+ String timestamp = value.get(0);
+ int index = timestamps.indexOf(timestamp);
+ list.set(index, new BigDecimal(value.get(1)));
+ }
+ }
+
+ List<BigDecimal> memTotalList = map.get(MEM_TOTAL) == null ?
getEmptyList() : map.get(MEM_TOTAL);
+ List<BigDecimal> memIdleList = map.get(MEM_IDLE) == null ?
getEmptyList() : map.get(MEM_IDLE);
+ List<BigDecimal> memUsageList = getEmptyList();
+
+ for (int i = 0; i < memTotalList.size(); i++) {
+ BigDecimal memTotal = memTotalList.get(i);
+ BigDecimal memIdle = memIdleList.get(i);
+ if (memTotal != null && memIdle != null) {
+ BigDecimal memUsage =
memTotal.subtract(memIdle).divide(memTotal, 4, RoundingMode.HALF_UP);
+ memUsageList.set(i, memUsage);
+ }
+ }
+
+ map.put("memUsage", memUsageList);
+ return map;
+ }
+
+ public Map<String, BigDecimal> retrieveAgentDisk(String iPv4addr) {
+ Map<String, BigDecimal> map = new HashMap<>();
+ String params =
String.format("agent_host_monitoring_disk{iPv4addr=\"%s\"}", iPv4addr);
+ PrometheusResponse response = query(params);
+ BigDecimal diskTotalSpace = new BigDecimal("0.0");
+ BigDecimal diskFreeSpace = new BigDecimal("0.0");
+ for (PrometheusResult result : response.getData().getResult()) {
+ String key = result.getMetric().get("diskUsage");
+ if (Objects.equals(key, DISK_IDLE)) {
+ diskFreeSpace =
+ diskFreeSpace.add(new
BigDecimal(result.getValue().get(1)));
+ } else {
+ diskTotalSpace =
+ diskTotalSpace.add(new
BigDecimal(result.getValue().get(1)));
+ }
+ }
+
+ map.put(DISK_IDLE, diskFreeSpace);
+ map.put(DISK_TOTAL, diskTotalSpace);
+ return map;
+ }
+
+ public Map<String, BigDecimal> retrieveAgentDiskIO(String iPv4addr) {
+ Map<String, BigDecimal> map = new HashMap<>();
+ String params =
String.format("agent_host_monitoring_diskIO{iPv4addr=\"%s\"}", iPv4addr);
+ PrometheusResponse response = query(params);
+ BigDecimal diskWrite = new BigDecimal("0.0");
+ BigDecimal diskRead = new BigDecimal("0.0");
+ for (PrometheusResult result : response.getData().getResult()) {
+ String key = result.getMetric().get("diskIO");
+ if (Objects.equals(key, DISK_WRITE)) {
+ diskWrite = diskWrite.add(new
BigDecimal(result.getValue().get(1)));
+ } else {
+ diskRead = diskRead.add(new
BigDecimal(result.getValue().get(1)));
+ }
+ }
+
+ map.put(DISK_WRITE, diskWrite);
+ map.put(DISK_READ, diskRead);
+ return map;
+ }
+
+ public Map<String, List<BigDecimal>> retrieveAgentDiskIO(String iPv4addr,
String interval) {
+ List<String> timestamps = timestampCache.get();
+ Map<String, List<BigDecimal>> map = new HashMap<>();
+ String params =
String.format("agent_host_monitoring_diskIO{iPv4addr=\"%s\"}", iPv4addr);
+ PrometheusResponse response = queryRange(
+ params,
+ timestamps.get(0),
+ timestamps.get(timestamps.size() - 1),
+ number2Param(processInternal(interval)));
+
+ List<BigDecimal> diskWriteList = getEmptyList();
+ List<BigDecimal> diskReadList = getEmptyList();
+
+ for (PrometheusResult result : response.getData().getResult()) {
+ String key = result.getMetric().get("diskIO");
+ for (List<String> value : result.getValues()) {
+ String timestamp = value.get(0);
+ int index = timestamps.indexOf(timestamp);
+ if (Objects.equals(key, DISK_WRITE)) {
+ BigDecimal w = diskWriteList.get(index);
+ if (w == null) {
+ w = new BigDecimal("0.0");
+ }
+
+ w = w.add(new BigDecimal(value.get(1)));
+ diskWriteList.set(index, w);
+ } else {
+ BigDecimal r = diskReadList.get(index);
+ if (r == null) {
+ r = new BigDecimal("0.0");
+ }
+
+ r = r.add(new BigDecimal(value.get(1)));
+ diskReadList.set(index, r);
+ }
+ }
+ }
+
+ map.put(DISK_WRITE, diskWriteList);
+ map.put(DISK_READ, diskReadList);
+ return map;
+ }
+
+ private List<String> convertList(List<BigDecimal> list) {
+ return convertList(list, 1);
+ }
+
+ private List<String> convertList(List<BigDecimal> list, Integer multiply) {
+ List<String> resultList = getEmptyList();
+ if (list == null) {
+ Collections.fill(resultList, "");
+ } else {
+ for (int i = 0; i < list.size(); i++) {
+ BigDecimal value = list.get(i);
+ if (value != null) {
+ resultList.set(i, value.multiply(new
BigDecimal(multiply)).toString());
+ } else {
+ resultList.set(i, "");
+ }
+ }
+ }
+
+ return resultList;
+ }
+
+ private static List<String> 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);
+ // get 8 point
+ List<String> timestamps = new ArrayList<>();
+ ZoneId zid = ZoneId.systemDefault();
+ for (int i = 6; i >= 0; i--) {
+ LocalDateTime pastTime =
currentDateTime.minus(Duration.ofSeconds((long) step * i));
+ long timestamp = pastTime.atZone(zid).toInstant().toEpochMilli() /
1000L;
+ timestamps.add(String.valueOf(timestamp));
+ }
+
+ return timestamps;
+ }
+
+ private String number2Param(int step) {
+ return String.format("%ss", step);
+ }
+
+ private 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;
+ }
+
+ private <T> List<T> getEmptyList() {
+ int size = timestampCache.get().size();
+ return new ArrayList<>(Collections.nCopies(size, null));
+ }
+}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusResponse.java
similarity index 64%
copy from
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
copy to
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusResponse.java
index 23327b17..ae17e144 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusResponse.java
@@ -16,15 +16,23 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.bigtop.manager.server.service;
+package org.apache.bigtop.manager.server.prometheus;
-import com.fasterxml.jackson.databind.JsonNode;
+import lombok.Data;
-public interface MetricsService {
+/**
+ * <a
href="https://prometheus.io/docs/prometheus/latest/querying/api/">Prometheus
HTTP API</a>
+ */
+@Data
+public class PrometheusResponse {
+
+ // "success" | "error"
+ private String status;
- JsonNode queryAgentsHealthyStatus();
+ private PrometheusData data;
- JsonNode queryAgentsInfo(Long id, String interval);
+ // Only set if status is "error". The data field may still hold additional
data.
+ private String errorType;
- JsonNode queryClustersInfo(Long clusterId, String interval);
+ private String error;
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusResult.java
similarity index 63%
copy from
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
copy to
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusResult.java
index 23327b17..f39b14d3 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/prometheus/PrometheusResult.java
@@ -16,15 +16,23 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.bigtop.manager.server.service;
+package org.apache.bigtop.manager.server.prometheus;
-import com.fasterxml.jackson.databind.JsonNode;
+import lombok.Data;
-public interface MetricsService {
+import java.util.List;
+import java.util.Map;
- JsonNode queryAgentsHealthyStatus();
+@Data
+public class PrometheusResult {
- JsonNode queryAgentsInfo(Long id, String interval);
+ private Map<String, String> metric;
- JsonNode queryClustersInfo(Long clusterId, String interval);
+ // For resultType "vector" only
+ // Contains a single value of [timestamp, value]
+ private List<String> value;
+
+ // For resultType "matrix" only
+ // Contains a list of values, each value is a list of [timestamp, value]
+ private List<List<String>> values;
}
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
deleted file mode 100644
index 78e1b284..00000000
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/proxy/PrometheusProxy.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * 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.proxy;
-
-import org.apache.bigtop.manager.server.utils.ProxyUtils;
-
-import org.springframework.http.MediaType;
-import org.springframework.web.reactive.function.BodyInserters;
-import org.springframework.web.reactive.function.client.WebClient;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import reactor.core.publisher.Mono;
-
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-public class PrometheusProxy {
-
- private final WebClient webClient;
-
- 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";
-
- public PrometheusProxy(String prometheusHost, Integer prometheusPort) {
- this.webClient = WebClient.builder()
- .baseUrl("http://" + prometheusHost + ":" + prometheusPort)
- .build();
- }
- /**
- * 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",
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;
- }
- 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 result;
- }
-
- /**
- * query agents healthy
- */
- public JsonNode queryAgentsHealthyStatus() {
- JsonNode result = query("up{job=\"%s\"}".formatted("bm-agent-host"));
- ObjectMapper objectMapper = new ObjectMapper();
- ArrayNode agentsHealthyStatus = objectMapper.createArrayNode();
- if (result != null) {
- 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();
- }
- /**
- * query agents info interval
- */
- public JsonNode queryAgentsInfo(String agentIpv4, String interval) {
- ObjectMapper objectMapper = new ObjectMapper();
- 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];
-
- 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);
-
- // 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);
- }
-
- // 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(List<String> agentIpv4s, String
interval) {
- int agentsNum = agentIpv4s.size(); // 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];
-
- int agentIndex = 0;
- ObjectNode clusterInfo = objectMapper.createObjectNode();
- for (String agentIpv4 : agentIpv4s) {
- 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 objectMapper.createObjectNode();
- }
-
- /**
- * 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");
- ObjectNode agentInfo = objectMapper.createObjectNode();
- agentInfo.put("hostname",
agentCpuMetric.get("hostname").asText());
- agentInfo.put(
- "cpuInfo",
- agentCpuMetric.get("cpu_info") == null
- ? ""
- : agentCpuMetric.get("cpu_info").asText());
- agentInfo.put("iPv4addr",
agentCpuMetric.get("iPv4addr").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(
- FILE_OPEN_DESCRIPTOR,
- agentCpuMetric.get(FILE_OPEN_DESCRIPTOR).asLong());
- agentInfo.put(
- 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());
- }
- return agentInfo;
- }
- }
- return objectMapper.createObjectNode();
- }
- /**
- * 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",
- agentCpuInfo.get("cpu_info") == null
- ? ""
- : agentCpuInfo.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()) {
- ObjectNode agentsMemInfo = objectMapper.createObjectNode();
- // metric
- JsonNode agentMemMetric = agentsMem.get(0).get("metric");
- agentsMemInfo.put("hostname",
agentMemMetric.get("hostname").asText());
- agentsMemInfo.put("iPv4addr",
agentMemMetric.get("iPv4addr").asText());
- for (JsonNode agent : agentsMem) {
- agentsMemInfo.put(
- agent.get("metric").get("memUsage").asText(),
- agent.get("value").get(1).asLong()); // mem metric
- }
- return agentsMemInfo;
- }
- }
- return objectMapper.createObjectNode();
- }
- /**
- * 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()) {
- 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());
-
- // 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.put(DISK_TOTAL, diskTotalSpace);
- agentDiskInfo.put(DISK_IDLE, diskFreeSpace);
- return agentDiskInfo;
- }
- }
- return objectMapper.createObjectNode();
- }
-
- /**
- * 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()) {
- 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());
-
- // 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 {
- 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;
- }
- }
- }
- agentDiskIOInfo.set(DISK_WRITE,
ProxyUtils.array2node(diskWrite));
- agentDiskIOInfo.set(DISK_READ,
ProxyUtils.array2node(diskRead));
- return agentDiskIOInfo;
- }
- }
- return objectMapper.createObjectNode();
- }
-}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
index 23327b17..8e25da1a 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/MetricsService.java
@@ -18,13 +18,12 @@
*/
package org.apache.bigtop.manager.server.service;
-import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.bigtop.manager.server.model.vo.ClusterMetricsVO;
+import org.apache.bigtop.manager.server.model.vo.HostMetricsVO;
public interface MetricsService {
- JsonNode queryAgentsHealthyStatus();
+ HostMetricsVO queryAgentsInfo(Long id, String interval);
- JsonNode queryAgentsInfo(Long id, String interval);
-
- JsonNode queryClustersInfo(Long clusterId, String interval);
+ ClusterMetricsVO queryClustersInfo(Long clusterId, String interval);
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java
index 25f2bae3..e5e62fa0 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java
@@ -62,11 +62,12 @@ public class ClusterServiceImpl implements ClusterService {
@Override
public ClusterVO get(Long id) {
ClusterPO clusterPO = clusterDao.findDetailsById(id);
-
if (clusterPO == null) {
throw new ApiException(ApiExceptionEnum.CLUSTER_NOT_FOUND);
}
+ int serviceNum = serviceDao.countByClusterId(id);
+ clusterPO.setTotalService((long) serviceNum);
return ClusterConverter.INSTANCE.fromPO2VO(clusterPO);
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/MetricsServiceImpl.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/MetricsServiceImpl.java
index c34721a7..10519aef 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/MetricsServiceImpl.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/MetricsServiceImpl.java
@@ -28,13 +28,13 @@ import
org.apache.bigtop.manager.dao.repository.ServiceConfigDao;
import org.apache.bigtop.manager.server.model.converter.ServiceConfigConverter;
import org.apache.bigtop.manager.server.model.dto.PropertyDTO;
import org.apache.bigtop.manager.server.model.dto.ServiceConfigDTO;
-import org.apache.bigtop.manager.server.proxy.PrometheusProxy;
+import org.apache.bigtop.manager.server.model.vo.ClusterMetricsVO;
+import org.apache.bigtop.manager.server.model.vo.HostMetricsVO;
+import org.apache.bigtop.manager.server.prometheus.PrometheusProxy;
import org.apache.bigtop.manager.server.service.MetricsService;
import org.springframework.stereotype.Service;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import jakarta.annotation.Resource;
@@ -54,20 +54,10 @@ public class MetricsServiceImpl implements MetricsService {
private ServiceConfigDao serviceConfigDao;
@Override
- public JsonNode queryAgentsHealthyStatus() {
+ public HostMetricsVO queryAgentsInfo(Long id, String interval) {
PrometheusProxy proxy = getProxy();
if (proxy == null) {
- return new ObjectMapper().createObjectNode();
- }
-
- return proxy.queryAgentsHealthyStatus();
- }
-
- @Override
- public JsonNode queryAgentsInfo(Long id, String interval) {
- PrometheusProxy proxy = getProxy();
- if (proxy == null) {
- return new ObjectMapper().createObjectNode();
+ return new HostMetricsVO();
}
String ipv4 = hostDao.findById(id).getIpv4();
@@ -75,10 +65,10 @@ public class MetricsServiceImpl implements MetricsService {
}
@Override
- public JsonNode queryClustersInfo(Long clusterId, String interval) {
+ public ClusterMetricsVO queryClustersInfo(Long clusterId, String interval)
{
PrometheusProxy proxy = getProxy();
if (proxy == null) {
- return new ObjectMapper().createObjectNode();
+ return new ClusterMetricsVO();
}
List<String> ipv4s = hostDao.findAllByClusterId(clusterId).stream()
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
deleted file mode 100644
index 46b95d40..00000000
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/ProxyUtils.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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/MetricsControllerTest.java
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/MetricsControllerTest.java
index 6e760c9b..b99d30ab 100644
---
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/MetricsControllerTest.java
+++
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/MetricsControllerTest.java
@@ -18,6 +18,8 @@
*/
package org.apache.bigtop.manager.server.controller;
+import org.apache.bigtop.manager.server.model.vo.ClusterMetricsVO;
+import org.apache.bigtop.manager.server.model.vo.HostMetricsVO;
import org.apache.bigtop.manager.server.service.MetricsService;
import org.apache.bigtop.manager.server.utils.MessageSourceUtils;
import org.apache.bigtop.manager.server.utils.ResponseEntity;
@@ -32,11 +34,7 @@ import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@@ -64,23 +62,36 @@ class MetricsControllerTest {
}
@Test
- void agentHostsHealthyStatusReturnsSuccess() {
- JsonNode mockResponse = new ObjectMapper().createObjectNode();
-
when(metricsService.queryAgentsHealthyStatus()).thenReturn(mockResponse);
+ void testQueryAgentInfo() {
+ Long hostId = 1L;
+ String interval = "1m";
+ HostMetricsVO mockResponse = new HostMetricsVO();
+ mockResponse.setCpuUsageCur("50%");
+ mockResponse.setMemoryUsageCur("70%");
+
+ when(metricsService.queryAgentsInfo(hostId,
interval)).thenReturn(mockResponse);
- ResponseEntity<JsonNode> response =
metricsController.agentHostsHealthyStatus();
+ ResponseEntity<HostMetricsVO> response =
metricsController.queryAgentInfo(interval, hostId);
+ assertEquals("Mocked message", response.getMessage());
assertTrue(response.isSuccess());
assertEquals(mockResponse, response.getData());
}
@Test
- void agentHostsHealthyStatusReturnsEmptyResponse() {
- when(metricsService.queryAgentsHealthyStatus()).thenReturn(null);
+ void testQueryClusterInfo() {
+ Long clusterId = 1L;
+ String interval = "1m";
+ ClusterMetricsVO mockResponse = new ClusterMetricsVO();
+ mockResponse.setCpuUsageCur("60%");
+ mockResponse.setMemoryUsageCur("80%");
- ResponseEntity<JsonNode> response =
metricsController.agentHostsHealthyStatus();
+ when(metricsService.queryClustersInfo(clusterId,
interval)).thenReturn(mockResponse);
+ ResponseEntity<ClusterMetricsVO> response =
metricsController.queryCluster(interval, clusterId);
+
+ assertEquals("Mocked message", response.getMessage());
assertTrue(response.isSuccess());
- assertNull(response.getData());
+ assertEquals(mockResponse, response.getData());
}
}
diff --git
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/service/ClusterServiceTest.java
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/service/ClusterServiceTest.java
index 6bd070dd..573cb9bd 100644
---
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/service/ClusterServiceTest.java
+++
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/service/ClusterServiceTest.java
@@ -21,7 +21,7 @@ package org.apache.bigtop.manager.server.service;
import org.apache.bigtop.manager.dao.po.ClusterPO;
import org.apache.bigtop.manager.dao.repository.ClusterDao;
-import org.apache.bigtop.manager.dao.repository.RepoDao;
+import org.apache.bigtop.manager.dao.repository.ServiceDao;
import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
import org.apache.bigtop.manager.server.exception.ApiException;
import org.apache.bigtop.manager.server.model.dto.ClusterDTO;
@@ -49,7 +49,7 @@ public class ClusterServiceTest {
private ClusterDao clusterDao;
@Mock
- private RepoDao repoDao;
+ private ServiceDao serviceDao;
@InjectMocks
private ClusterService clusterService = new ClusterServiceImpl();
@@ -73,6 +73,7 @@ public class ClusterServiceTest {
assertThrows(ApiException.class, () ->
clusterService.get(1L)).getEx());
when(clusterDao.findDetailsById(any())).thenReturn(clusterPO);
+ when(serviceDao.countByClusterId(any())).thenReturn(1);
assert clusterService.get(1L).getName().equals(CLUSTER_NAME);
ClusterDTO clusterDTO = new ClusterDTO();
diff --git
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/utils/ProxyUtilsTest.java
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/utils/ProxyUtilsTest.java
deleted file mode 100644
index aa39edd3..00000000
---
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/utils/ProxyUtilsTest.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 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 org.junit.jupiter.api.Test;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import java.util.ArrayList;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-public class ProxyUtilsTest {
-
- @Test
- // Test getDoubleSafely with normal case
- public void testGetDoubleSafelyHappyPath() throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- String jsonString = "{\"values\":[1.1, 2.2, 3.3]}";
- JsonNode parentNode = mapper.readTree(jsonString);
- assertEquals(2.2, ProxyUtils.getDoubleSafely(parentNode, "values", 1));
- }
-
- @Test
- // Test getDoubleSafely with null node case
- public void testGetDoubleSafelyNullNode() {
- ObjectMapper mapper = new ObjectMapper();
- JsonNode parentNode = mapper.createObjectNode();
- assertEquals(0.0, ProxyUtils.getDoubleSafely(parentNode, "values", 1));
- }
-
- @Test
- // Test getDoubleSafely with non-array node case
- public void testGetDoubleSafelyNotArrayNode() throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- String jsonString = "{\"values\":1.1}";
- JsonNode parentNode = mapper.readTree(jsonString);
- assertEquals(0.0, ProxyUtils.getDoubleSafely(parentNode, "values", 1));
- }
-
- @Test
- // Test getDoubleSafely with index out of bounds case
- public void testGetDoubleSafelyIndexOutOfBound() throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- String jsonString = "{\"values\":[1.1, 2.2, 3.3]}";
- JsonNode parentNode = mapper.readTree(jsonString);
- assertEquals(0.0, ProxyUtils.getDoubleSafely(parentNode, "values", 5));
- }
-
- @Test
- // Test getLongSafely with normal case
- public void testGetLongSafelyHappyPath() throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- String jsonString = "{\"values\":[1, 2, 3]}";
- JsonNode parentNode = mapper.readTree(jsonString);
- assertEquals(2L, ProxyUtils.getLongSafely(parentNode, "values", 1));
- }
-
- @Test
- // Test getLongSafely with null node case
- public void testGetLongSafelyNullNode() {
- ObjectMapper mapper = new ObjectMapper();
- JsonNode parentNode = mapper.createObjectNode();
- assertEquals(0L, ProxyUtils.getLongSafely(parentNode, "values", 1));
- }
-
- @Test
- // Test getLongSafely with non-array node case
- public void testGetLongSafelyNotArrayNode() throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- String jsonString = "{\"values\":1}";
- JsonNode parentNode = mapper.readTree(jsonString);
- assertEquals(0L, ProxyUtils.getLongSafely(parentNode, "values", 1));
- }
-
- @Test
- // Test getLongSafely with index out of bounds case
- public void testGetLongSafelyIndexOutOfBound() throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- String jsonString = "{\"values\":[1, 2, 3]}";
- JsonNode parentNode = mapper.readTree(jsonString);
- assertEquals(0L, ProxyUtils.getLongSafely(parentNode, "values", 5));
- }
-
- @Test
- // Test array2node(double[] array) with normal case
- public void testArray2NodeDoubleArrayHappyPath() {
- double[] array = {1.123456789, 2.23456789, 3.3456789, 4.456789,
5.56789, 6.6789};
- JsonNode node = ProxyUtils.array2node(array);
- assertEquals("1.123457", node.get(0).asText());
- assertEquals("2.234568", node.get(1).asText());
- assertEquals("3.345679", node.get(2).asText());
- assertEquals("4.456789", node.get(3).asText());
- assertEquals("5.567890", node.get(4).asText());
- assertEquals("6.678900", node.get(5).asText());
- }
-
- @Test
- // Test array2node(long[] array) with normal case
- public void testArray2NodeLongArrayHappyPath() {
- long[] array = {1, 2, 3, 4, 5, 6};
- JsonNode node = ProxyUtils.array2node(array);
- assertEquals(1L, node.get(0).asLong());
- assertEquals(2L, node.get(1).asLong());
- assertEquals(3L, node.get(2).asLong());
- assertEquals(4L, node.get(3).asLong());
- assertEquals(5L, node.get(4).asLong());
- assertEquals(6L, node.get(5).asLong());
- }
-
- @Test
- // Test array2node(long[] array1, long[] array2) with normal case
- public void testArray2NodeTwoLongArraysHappyPath() {
- long[] array1 = {1, 2, 3, 4, 5, 6};
- long[] array2 = {2, 4, 6, 8, 10, 12};
- JsonNode node = ProxyUtils.array2node(array1, array2);
- assertEquals("0.500000", node.get(0).asText());
- assertEquals("0.500000", node.get(1).asText());
- assertEquals("0.500000", node.get(2).asText());
- assertEquals("0.500000", node.get(3).asText());
- assertEquals("0.500000", node.get(4).asText());
- assertEquals("0.500000", node.get(5).asText());
- }
-
- @Test
- // Test array2node(long[] array1, long[] array2) with array2 containing
zero case
- public void testArray2NodeTwoLongArraysWithZero() {
- long[] array1 = {1, 2, 3, 4, 5, 6};
- long[] array2 = {0, 4, 0, 8, 10, 0};
- JsonNode node = ProxyUtils.array2node(array1, array2);
- assertEquals("0.000000", node.get(0).asText());
- assertEquals("0.500000", node.get(1).asText());
- assertEquals("0.000000", node.get(2).asText());
- assertEquals("0.500000", node.get(3).asText());
- assertEquals("0.500000", node.get(4).asText());
- assertEquals("0.000000", node.get(5).asText());
- }
-
- @Test
- // Test array2node(long[][] array1, long[][] array2, int num) with normal
case
- public void testArray2NodeTwoLong2DArraysHappyPath() {
- long[][] array1 = {{1, 2, 3, 4, 5, 6}, {2, 3, 4, 5, 6, 7}};
- long[][] array2 = {{2, 4, 6, 8, 10, 12}, {3, 5, 6, 8, 10, 12}};
- JsonNode node = ProxyUtils.array2node(array1, array2, 2);
- assertEquals("0.400000", node.get(0).asText());
- assertEquals("0.444444", node.get(1).asText());
- assertEquals("0.416667", node.get(2).asText());
- assertEquals("0.437500", node.get(3).asText());
- assertEquals("0.450000", node.get(4).asText());
- assertEquals("0.458333", node.get(5).asText());
- }
-
- @Test
- // Test array2node(long[][] array1, long[][] array2, int num) with array2
containing zero case
- public void testArray2NodeTwoLong2DArraysWithZero() {
- long[][] array1 = {{1, 2, 3, 4, 5, 6}, {2, 3, 4, 5, 6, 7}};
- long[][] array2 = {{2, 4, 0, 8, 10, 0}, {3, 5, 0, 8, 10, 0}};
- JsonNode node = ProxyUtils.array2node(array1, array2, 2);
- assertEquals("0.400000", node.get(0).asText());
- assertEquals("0.444444", node.get(1).asText());
- assertEquals("0.000000", node.get(2).asText());
- assertEquals("0.437500", node.get(3).asText());
- assertEquals("0.450000", node.get(4).asText());
- assertEquals("0.000000", node.get(5).asText());
- }
-
- @Test
- // Test getTimeStampsList with normal case
- public void testGetTimeStampsListHappyPath() {
- ArrayList<Long> timestamps = ProxyUtils.getTimeStampsList(10);
- assertEquals(7, timestamps.size());
- // Here we cannot precisely assert the value of each timestamp as they
depend on the current time, but we can
- // assert the number of timestamps
- }
-
- @Test
- // Test Number2Param with normal case
- public void testNumber2ParamHappyPath() {
- assertEquals("10m", ProxyUtils.Number2Param(10));
- }
-
- @Test
- // Test processInternal with normal case
- public void testProcessInternalHappyPath() {
- assertEquals(600, ProxyUtils.processInternal("10m"));
- assertEquals(3600, ProxyUtils.processInternal("1h"));
- assertEquals(120, ProxyUtils.processInternal("2m"));
- }
-
- @Test
- // Test processInternal with illegal input case
- public void testProcessInternalIllegalInput() {
- Exception exception = assertThrows(NumberFormatException.class, () -> {
- ProxyUtils.processInternal("abc");
- });
- assertNotNull(exception);
- }
-}