Commit 36eacfa3 by 黄明步

更新服务器资源监控数据接口

parent c60d3495
package com.gxmailu.ocrCloudPlatform.constant;
import lombok.Data;
/**
* prometheus常量信息
*
* @author Hmb
* @since 2024/4/22 10:59
*/
@Data
public class PromConstants {
/**
* prometheus-查询SUCCESS
*/
public static final String SUCCESS = "success";
/**
* prometheus-查询参数
*/
public static final String QUERY = "query";
/**
* Java虚拟机可用的处理器数量
*/
public static final String SYSTEM_CPU_COUNT = "system_cpu_count";
/**
* JVM的CPU利用率
*/
public static final String PROCESS_CPU_COUNT = "process_cpu_usage";
/**
* tomcat_当前活跃会话数
*/
public static final String TOMCAT_SESSIONS_ACTIVE_CURRENT_SESSIONS = "tomcat_sessions_active_current_sessions";
/**
* Java虚拟机的正常运行时间
*/
public static final String PROCESS_UPTIME_SECONDS = "process_uptime_seconds";
/**
* 可供Java虚拟机使用的已提交的内存量
*/
public static final String JVM_MEMORT_COMMITTED_BYTES = "jvm_memory_committed_bytes";
/**
* 自Java虚拟机启动或重置峰值以来的活动线程峰值
*/
public static final String JVM_THREADS_PEAK_THREADS = "jvm_threads_peak_threads";
/**
* 在一个GC之后到下一个GC之前增加年轻代内存池的大小
*/
public static final String JVM_GC_MEMORT_ALLOCATED_BYTES_TOTAL = "jvm_gc_memory_allocated_bytes_total";
/**
* 进程的开始时间
*/
public static final String PROCESS_START_TIME_SECONDS = "process_start_time_seconds";
/**
* 最大内存
*/
public static final String JVM_MEMORT_MAX_BYTES = "jvm_memory_max_bytes";
/**
* 已使用内存
*/
public static final String JVM_MEMORT_USED_BYTES = "jvm_memory_used_bytes";
/**
* 请求次数
*/
public static final String HTTP_SERVER_REQUEST_SECONDS_COUNT = "http_server_requests_seconds_count";
/**
* 请求n次花费的时间
*/
public static final String HTTP_SERVER_REQUEST_SECONDS_SUM = "http_server_requests_seconds_sum";
/**
* 最长一次花了多长时间
*/
public static final String HTTP_SERVER_REQUEST_SECONDS_MAX = "http_server_requests_seconds_max";
/**
* 日志总数
*/
public static final String LOGBACK_EVENTS_TOTAL = "logback_events_total";
/**
* 目录总使用率
*/
public static String DISK_USAGE = "sum(node_filesystem_size_bytes{instance=\"%1$s:9100\"} - node_filesystem_free_bytes{instance=\"%1$s:9100\"}) / sum(node_filesystem_size_bytes{instance=\"%1$s:9100\"}) * 100";
/**
* CPU使用率
*/
public static String CPU_USAGE = "100 - (avg by(instance) (rate(node_cpu_seconds_total{mode=\"idle\",instance=\"%1$s:9100\"}[5m])) * 100)";
/**
* 内存使用率
*/
public static String MEMORY_USAGE = "100 * (1 - (node_memory_MemAvailable_bytes{instance=\"%1$s:9100\"} / node_memory_MemTotal_bytes{instance=\"%1$s:9100\"}))";
/**
* 5分钟平均系统负载
*/
public static String AVG_SYSTEM_LOAD5 = "avg(node_load5{instance=\"%1$s:9100\"}) / count(count(node_cpu_seconds_total{instance=\"%1$s:9100\"}) by (cpu)) * 100";
/**
* GPU使用率
*/
public static String GPU_USAGE = "nvidia_smi_clocks_current_graphics_clock_hz{instance=\"%1$s:9835\"} / nvidia_smi_clocks_max_graphics_clock_hz{instance=\"%1$s:9835\"}";
public static void main(String[] args) {
String instanceValue = "127.0.0.1";
String instanceValue2 = "127.0.0.2";
String format = String.format(DISK_USAGE, instanceValue, instanceValue, instanceValue);
System.out.println(format);
String DISK_USAGE = "sum(node_filesystem_size_bytes{instance=\"%1$s:9100\"} - node_filesystem_free_bytes{instance=\"%1$s:9100\"}) / sum(node_filesystem_size_bytes{instance=\"%1$s:9100\"}) * 100";
String result = String.format(DISK_USAGE, instanceValue2, instanceValue);
System.out.println(result);
}
}
...@@ -39,5 +39,10 @@ public class RedisConstant { ...@@ -39,5 +39,10 @@ public class RedisConstant {
**/ **/
public static final String SLOW_CALL_COUNT = "slow-call:count:"; public static final String SLOW_CALL_COUNT = "slow-call:count:";
/**
* redis key 服务器资源监控信息
*/
public static final String SERVER_MONITORING = "server:monitoring";
} }
...@@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestParam; ...@@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.*;
/** /**
* 统计相关 * 统计相关
...@@ -32,10 +33,10 @@ public class StatController { ...@@ -32,10 +33,10 @@ public class StatController {
@ApiOperation(value = "获取调用信息数据") @ApiOperation(value = "获取调用信息数据")
@ApiImplicitParams(value = { @ApiImplicitParams(value = {
@ApiImplicitParam(name = "startDate",value = "开始日期范围,非必填,为空则默认当日",dataType = "String"), @ApiImplicitParam(name = "startDate", value = "开始日期范围,非必填,为空则默认当日", dataType = "String"),
@ApiImplicitParam(name = "endDate",value = "结束日期范围,非必填",dataType = "String"), @ApiImplicitParam(name = "endDate", value = "结束日期范围,非必填", dataType = "String"),
@ApiImplicitParam(name = "interval",value = "时间间隔,按日查询时可用,可选值[hour|minute|second]",dataType = "String"), @ApiImplicitParam(name = "interval", value = "时间间隔,按日查询时可用,可选值[hour|minute|second]", dataType = "String"),
@ApiImplicitParam(name = "displayType",value = "展示类型,总体量或各法院使用量可选值[detailed|full]",dataType = "String"), @ApiImplicitParam(name = "displayType", value = "展示类型,总体量或各法院使用量可选值[detailed|full]", dataType = "String"),
}) })
@GetMapping("/getBrokenLineData") @GetMapping("/getBrokenLineData")
public Result getBrokenLineData(@RequestParam(value = "startDate", required = false) String startDate, public Result getBrokenLineData(@RequestParam(value = "startDate", required = false) String startDate,
...@@ -45,5 +46,28 @@ public class StatController { ...@@ -45,5 +46,28 @@ public class StatController {
return statService.getBrokenLineData(startDate, endDate, interval, displayType); return statService.getBrokenLineData(startDate, endDate, interval, displayType);
} }
@ApiOperation(value = "获取服务器监控数据")
@ApiImplicitParams(value = {
@ApiImplicitParam(name = "time", value = "秒级别的时间戳,不传该值则默认当前时刻", dataType = "Long")
})
@GetMapping("/getServerMonitoring")
public Result getServerMonitoring(@RequestParam(value = "time", required = false) Long time) {
return statService.getServerMonitoring(time);
}
public static void main(String[] args) {
List<List<String>> listOfLists = new ArrayList<>();
listOfLists.add(Arrays.asList("b", "2", "3"));
listOfLists.add(Arrays.asList("a", "4", "5"));
listOfLists.add(Arrays.asList("d", "6", "7"));
listOfLists.add(Arrays.asList("c", "8", "9"));
System.out.println("原始二维列表:" + listOfLists);
// 对二维列表中的元素进行排序
Collections.sort(listOfLists, Comparator.comparing(list -> list.get(0)));
System.out.println("按第一个元素排序后的二维列表:" + listOfLists);
}
} }
package com.gxmailu.ocrCloudPlatform.entity.prometheus;
import lombok.Data;
import java.util.List;
/**
* @author Hmb
* @since 2024/4/22 10:58
*/
@Data
public class PromDataInfo {
/**
* prometheus监控服务指表参数
*/
private List<?> droppedTargets;
private List<PromResultInfo> activeTargets;
/**
* prometheus监控样本指标参数
*/
private String resultType;
private List<PromMetric> result;
}
package com.gxmailu.ocrCloudPlatform.entity.prometheus;
import lombok.Data;
import java.util.List;
/**
* @author Hmb
* @since 2024/4/22 10:58
*/
@Data
public class PromMetric {
/**
* metric name和描述当前样本特征的labelsets
*/
private PromMetricInfo metric;
/**
* 一个float64的浮点型数据表示当前样本的值。
*/
private List<String> value;
private List<List<String>> values;
}
package com.gxmailu.ocrCloudPlatform.entity.prometheus;
import lombok.Data;
/**
* @author Hmb
* @since 2024/4/22 10:59
*/
@Data
public class PromMetricInfo {
/**
* prometheus指标名称
*/
private String __name__;
/**
* prometheus实例名称
*/
private String instance;
/**
* prometheus任务名称
*/
private String job;
private String application;
private String exception;
private String method;
private String outcome;
private String status;
private String url;
}
package com.gxmailu.ocrCloudPlatform.entity.prometheus;
import lombok.Data;
/**
* @author Hmb
* @since 2024/4/22 10:57
*/
@Data
public class PromResponseInfo {
/**
* 状态
* 成功-- success
*/
private String status;
/**
* prometheus指标属性和值
*/
private PromDataInfo data;
}
package com.gxmailu.ocrCloudPlatform.entity.prometheus;
import lombok.Data;
/**
* prometheus服务指标参数
*
* @author Hmb
* @since 2024/4/22 10:59
*/
@Data
public class PromResultInfo {
/**
* prometheus指标属性
*/
private PromMetricInfo labels;
/**
* prometheus指标值
*/
private String globalUrl;
private String health;
private String lastScrape;
private String lastScrapeDuration;
private String scrapeInterval;
private String scrapePool;
private String scrapeTimeout;
private String scrapeUrl;
}
package com.gxmailu.ocrCloudPlatform.service.impl; package com.gxmailu.ocrCloudPlatform.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.aggregations.CalendarInterval; import co.elastic.clients.elasticsearch._types.aggregations.CalendarInterval;
import co.elastic.clients.elasticsearch._types.aggregations.DateHistogramAggregation; import co.elastic.clients.elasticsearch._types.aggregations.DateHistogramAggregation;
...@@ -11,17 +13,27 @@ import co.elastic.clients.elasticsearch._types.aggregations.DateHistogramBucket; ...@@ -11,17 +13,27 @@ import co.elastic.clients.elasticsearch._types.aggregations.DateHistogramBucket;
import co.elastic.clients.elasticsearch._types.aggregations.SumAggregation; import co.elastic.clients.elasticsearch._types.aggregations.SumAggregation;
import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.json.JsonData; import co.elastic.clients.json.JsonData;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gxmailu.ocrCloudPlatform.constant.PromConstants;
import com.gxmailu.ocrCloudPlatform.constant.RedisConstant;
import com.gxmailu.ocrCloudPlatform.entity.Court; import com.gxmailu.ocrCloudPlatform.entity.Court;
import com.gxmailu.ocrCloudPlatform.entity.ServerInfo;
import com.gxmailu.ocrCloudPlatform.entity.prometheus.PromDataInfo;
import com.gxmailu.ocrCloudPlatform.entity.prometheus.PromMetric;
import com.gxmailu.ocrCloudPlatform.mapper.ServerInfoMapper;
import com.gxmailu.ocrCloudPlatform.service.CourtService; import com.gxmailu.ocrCloudPlatform.service.CourtService;
import com.gxmailu.ocrCloudPlatform.utils.IpUtils; import com.gxmailu.ocrCloudPlatform.utils.IpUtils;
import com.gxmailu.ocrCloudPlatform.utils.PrometheusHttpUtil;
import com.gxmailu.ocrCloudPlatform.vo.BrokenLineData; import com.gxmailu.ocrCloudPlatform.vo.BrokenLineData;
import com.gxmailu.ocrCloudPlatform.vo.Result; import com.gxmailu.ocrCloudPlatform.vo.Result;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -32,6 +44,11 @@ import java.util.stream.Collectors; ...@@ -32,6 +44,11 @@ import java.util.stream.Collectors;
@Service @Service
public class StatService { public class StatService {
@Value("${spring.profiles.active}")
private String active;
@Resource
private ServerInfoMapper serverInfoMapper;
@Resource @Resource
private RedisService redisService; private RedisService redisService;
...@@ -281,4 +298,100 @@ public class StatService { ...@@ -281,4 +298,100 @@ public class StatService {
return resultList; return resultList;
} }
} }
public Result getServerMonitoring(Long time) {
try {
List<ServerInfo> serverInfoList = serverInfoMapper.selectList(Wrappers.lambdaQuery(ServerInfo.class)
.eq(ServerInfo::getNetwork, "0")
.select(ServerInfo::getIp, ServerInfo::getName));
List<List<String>> metricList = new ArrayList<>();
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (ServerInfo serverInfo : serverInfoList) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
List<String> list = new ArrayList<>();
list.add(serverInfo.getName());
String instance = "dev".equals(active) ? "localhost" : serverInfo.getIp();
String diskUsagePromQL = String.format(PromConstants.DISK_USAGE, instance);
String cpuUsagePromQL = String.format(PromConstants.CPU_USAGE, instance);
String memoryUsagePromQL = String.format(PromConstants.MEMORY_USAGE, instance);
String gpuUsagePromQL = String.format(PromConstants.GPU_USAGE, instance);
String systemLoadPromQL = String.format(PromConstants.AVG_SYSTEM_LOAD5, instance);
PromDataInfo diskDataInfo = PrometheusHttpUtil.getQueryDataInfo(diskUsagePromQL, time);
if (null != diskDataInfo) {
if (CollUtil.isNotEmpty(diskDataInfo.getResult())) {
PromMetric promMetric = diskDataInfo.getResult().get(0);
String val = promMetric.getValue().get(1);
list.add(val);
} else {
list.add("0");
}
}
PromDataInfo cpuDataInfo = PrometheusHttpUtil.getQueryDataInfo(cpuUsagePromQL, time);
if (null != cpuDataInfo) {
if (CollUtil.isNotEmpty(cpuDataInfo.getResult())) {
PromMetric promMetric = cpuDataInfo.getResult().get(0);
String val = promMetric.getValue().get(1);
list.add(val);
} else {
list.add("0");
}
}
PromDataInfo memoryDataInfo = PrometheusHttpUtil.getQueryDataInfo(memoryUsagePromQL, time);
if (null != memoryDataInfo) {
if (CollUtil.isNotEmpty(memoryDataInfo.getResult())) {
PromMetric promMetric = memoryDataInfo.getResult().get(0);
String val = promMetric.getValue().get(1);
list.add(val);
} else {
list.add("0");
}
}
PromDataInfo gpuDataInfo = PrometheusHttpUtil.getQueryDataInfo(gpuUsagePromQL, time);
if (null != gpuDataInfo) {
if (CollUtil.isNotEmpty(gpuDataInfo.getResult())) {
PromMetric promMetric = gpuDataInfo.getResult().get(0);
String val = promMetric.getValue().get(1);
list.add(val);
} else {
list.add("0");
}
}
PromDataInfo systemLoadDataInfo = PrometheusHttpUtil.getQueryDataInfo(systemLoadPromQL, time);
if (null != systemLoadDataInfo) {
if (CollUtil.isNotEmpty(systemLoadDataInfo.getResult())) {
PromMetric promMetric = systemLoadDataInfo.getResult().get(0);
String val = promMetric.getValue().get(1);
list.add(val);
} else {
list.add("0");
}
}
metricList.add(list);
});
futures.add(future);
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); // 等待所有查询完成
// 根据每个一维数组的第一个元素进行排序
metricList.sort(Comparator.comparing(list -> list.get(0)));
List<String> metricName = new ArrayList<>(Arrays.asList("metric", "硬盘", "CPU", "内存", "GPU", "近5分钟平均系统负载"));
// 添加到第一个元素
metricList.add(0, metricName);
redisService.set(RedisConstant.SERVER_MONITORING, metricList);
return Result.success("成功", metricList);
} catch (Exception e) {
// 异常处理,返回默认值
log.error("查询服务器资源信息发生异常:" , e);
Object value = redisService.getValue(RedisConstant.SERVER_MONITORING);
List<Object> list = JSONUtil.toList(value.toString(), Object.class);
return Result.error("查询资源信息失败", list);
}
}
} }
package com.gxmailu.ocrCloudPlatform.utils;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.gxmailu.ocrCloudPlatform.constant.PromConstants;
import com.gxmailu.ocrCloudPlatform.entity.prometheus.PromDataInfo;
import com.gxmailu.ocrCloudPlatform.entity.prometheus.PromMetric;
import com.gxmailu.ocrCloudPlatform.entity.prometheus.PromResponseInfo;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Objects;
/**
* @author Hmb
* @since 2024/4/24 17:55
*/
@Slf4j
public class PrometheusHttpUtil {
private static final String QUERY_URL = "http://129.204.37.121:9980/api/v1/query";
private static final String QUERY_RANGE_URL = "http://129.204.37.121:9980/api/v1/query_range";
public static void main(String[] args) {
long start = 1714010400;
long end = 1714010700;
// 范围查询
PromDataInfo memoryDataInfo= PrometheusHttpUtil.getQueryRangeDataInfo(String.format(PromConstants.CPU_USAGE, "localhost"), start, end);
if (null != memoryDataInfo) {
PromMetric promMetric = memoryDataInfo.getResult().get(0);
List<List<String>> values = promMetric.getValues();
for (List<String> value : values) {
String time = value.get(0);
String val = value.get(1);
log.info("{} 内存使用率:{}", time, val);
}
}
}
/**
* 获取prometheus查询结果
*
* @param promQL prometheus查询QL
* @return
*/
public static PromDataInfo getQueryDataInfo(String promQL, Long time) {
time = null != time ? time : System.currentTimeMillis() / 1000;
log.info("请求地址:{},请求PromQL:{},时间戳:{}", QUERY_URL, promQL, time);
JSONObject param = new JSONObject();
param.put(PromConstants.QUERY, promQL);
param.put("time", time);
String http = null;
try {
http = HttpUtil.get(QUERY_URL, param);
} catch (Exception e) {
log.error("请求地址:{},请求PromQL:{},异常信息", QUERY_URL, promQL, e);
}
PromResponseInfo responseInfo = JSON.parseObject(http, PromResponseInfo.class);
if (Objects.isNull(responseInfo)) {
return null;
}
String status = responseInfo.getStatus();
if (StrUtil.isBlank(status) || !PromConstants.SUCCESS.equals(status)) {
return null;
}
return responseInfo.getData();
}
public static PromDataInfo getQueryRangeDataInfo(String promQL, Long start, Long end) {
long step = (end - start) / 300;
log.info("请求地址:{},请求PromQL:{},时间范围:{}-{}", QUERY_RANGE_URL, promQL, start, end);
JSONObject param = new JSONObject();
param.put(PromConstants.QUERY, promQL);
param.put("start", start);
param.put("end", end);
param.put("step", step);
String http = null;
try {
http = HttpUtil.get(QUERY_RANGE_URL, param);
} catch (Exception e) {
log.error("请求地址:{},请求PromQL:{},异常信息", QUERY_RANGE_URL, promQL, e);
}
PromResponseInfo responseInfo = JSON.parseObject(http, PromResponseInfo.class);
if (Objects.isNull(responseInfo)) {
return null;
}
String status = responseInfo.getStatus();
if (StrUtil.isBlank(status) || !PromConstants.SUCCESS.equals(status)) {
return null;
}
return responseInfo.getData();
}
}
...@@ -59,12 +59,14 @@ public class Result { ...@@ -59,12 +59,14 @@ public class Result {
public Result(Integer code, String msg) { public Result(Integer code, String msg) {
this.code = code; this.code = code;
this.message = msg; this.message = msg;
this.time = DateUtil.current();
} }
public Result(Integer code, String msg, Object data) { public Result(Integer code, String msg, Object data) {
this.code = code; this.code = code;
this.message = msg; this.message = msg;
this.data = data; this.data = data;
this.time = DateUtil.current();
} }
public Result(Boolean success, Integer code, String msg) { public Result(Boolean success, Integer code, String msg) {
...@@ -80,6 +82,7 @@ public class Result { ...@@ -80,6 +82,7 @@ public class Result {
this.code = code; this.code = code;
this.message = msg; this.message = msg;
this.data = data; this.data = data;
this.time = DateUtil.current();
} }
public static Result requestError(String msg) { public static Result requestError(String msg) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment