格式化代码
This commit is contained in:
parent
3a1c57b161
commit
70852d88b8
|
|
@ -33,82 +33,94 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
* 获取CPU信息
|
* 获取CPU信息
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String,Object> getCpuInfo(String ip,String conditions) {
|
public Map<String, Object> getCpuInfo(String ip, String conditions) {
|
||||||
Map<String,Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
//Prometheus 服务器地址
|
//Prometheus 服务器地址
|
||||||
String url = serverProperties.getServerUrl();
|
String url = serverProperties.getServerUrl();
|
||||||
//目标主机实例(node-exporter 的地址)
|
//目标主机实例(node-exporter 的地址)
|
||||||
String instance = this.getInstance(ip);
|
String instance = this.getInstance(ip);
|
||||||
//查询CPU利用率
|
//查询CPU利用率
|
||||||
PrometheusHostQueryTypeEnum queryTypeEnum = PrometheusHostQueryTypeEnum.getQueryTypeEnum(conditions);
|
PrometheusHostQueryTypeEnum queryTypeEnum =
|
||||||
|
PrometheusHostQueryTypeEnum.getQueryTypeEnum(conditions);
|
||||||
String exprTime = queryTypeEnum.getExprTime();
|
String exprTime = queryTypeEnum.getExprTime();
|
||||||
String cpuQuery = "100 * (1 - avg(rate(node_cpu_seconds_total{mode=\"idle\", instance=\""+instance+"\"}["+exprTime+"])))";
|
String cpuQuery =
|
||||||
|
"100 * (1 - avg(rate(node_cpu_seconds_total{mode=\"idle\", instance=\"" +
|
||||||
|
instance + "\"}[" + exprTime + "])))";
|
||||||
PrometheusResponse response = webClient.get()
|
PrometheusResponse response = webClient.get()
|
||||||
.uri(buildUri(url,cpuQuery))
|
.uri(buildUri(url, cpuQuery))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(response) &&
|
if (Objects.nonNull(response) &&
|
||||||
Objects.nonNull(response.getData()) &&
|
Objects.nonNull(response.getData()) &&
|
||||||
CollUtil.isNotEmpty(response.getData().getResult())
|
CollUtil.isNotEmpty(response.getData().getResult())
|
||||||
) {
|
) {
|
||||||
PrometheusResponse.Result cpuInfo = response.getData().getResult().get(0);
|
PrometheusResponse.Result cpuInfo = response.getData().getResult().get(0);
|
||||||
if(CollUtil.isNotEmpty(cpuInfo.getValue())) {
|
if (CollUtil.isNotEmpty(cpuInfo.getValue())) {
|
||||||
Date date = new Date(cpuInfo.getValue().get(0).longValue()*1000);
|
Date date = new Date(cpuInfo.getValue().get(0).longValue() * 1000);
|
||||||
Double useRate = BigDecimal.valueOf(cpuInfo.getValue().get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
Double useRate = BigDecimal.valueOf(cpuInfo.getValue().get(1))
|
||||||
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
result.put("date", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
result.put("date", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
||||||
result.put("usageRate", useRate);
|
result.put("usageRate", useRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
} catch (Exception e) {
|
||||||
log.error("获取CPU信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
log.error(
|
||||||
|
"获取CPU信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",
|
||||||
|
e.getMessage());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取CPU信息列表
|
* 获取CPU信息列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String, Object>> getCpuInfoList(String ip,String conditions) {
|
public List<Map<String, Object>> getCpuInfoList(String ip, String conditions) {
|
||||||
List<Map<String, Object>> result = new ArrayList<>();
|
List<Map<String, Object>> result = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
//Prometheus 服务器地址
|
//Prometheus 服务器地址
|
||||||
String url = serverProperties.getServerUrl();
|
String url = serverProperties.getServerUrl();
|
||||||
//目标主机实例(node-exporter 的地址)
|
//目标主机实例(node-exporter 的地址)
|
||||||
String instance = this.getInstance(ip);
|
String instance = this.getInstance(ip);
|
||||||
//查询CPU利用率
|
//查询CPU利用率
|
||||||
PrometheusHostQueryTypeEnum queryTypeEnum = PrometheusHostQueryTypeEnum.getQueryTypeEnum(conditions);
|
PrometheusHostQueryTypeEnum queryTypeEnum =
|
||||||
|
PrometheusHostQueryTypeEnum.getQueryTypeEnum(conditions);
|
||||||
long end = Instant.now().getEpochSecond();
|
long end = Instant.now().getEpochSecond();
|
||||||
long start = end - queryTypeEnum.getLastSecond();
|
long start = end - queryTypeEnum.getLastSecond();
|
||||||
String step = queryTypeEnum.getStep();
|
String step = queryTypeEnum.getStep();
|
||||||
String exprTime = queryTypeEnum.getExprTime();
|
String exprTime = queryTypeEnum.getExprTime();
|
||||||
String cpuQuery = "100 * (1 - avg(rate(node_cpu_seconds_total{mode=\"idle\", instance=\""+instance+"\"}["+exprTime+"])))";
|
String cpuQuery =
|
||||||
|
"100 * (1 - avg(rate(node_cpu_seconds_total{mode=\"idle\", instance=\"" +
|
||||||
|
instance + "\"}[" + exprTime + "])))";
|
||||||
PrometheusResponse response = webClient.get()
|
PrometheusResponse response = webClient.get()
|
||||||
.uri(buildUri(url,cpuQuery,start,end,step))
|
.uri(buildUri(url, cpuQuery, start, end, step))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(response) &&
|
if (Objects.nonNull(response) &&
|
||||||
Objects.nonNull(response.getData()) &&
|
Objects.nonNull(response.getData()) &&
|
||||||
CollUtil.isNotEmpty(response.getData().getResult())
|
CollUtil.isNotEmpty(response.getData().getResult())
|
||||||
) {
|
) {
|
||||||
PrometheusResponse.Result cpuInfoList = response.getData().getResult().get(0);
|
PrometheusResponse.Result cpuInfoList = response.getData().getResult().get(0);
|
||||||
if(CollUtil.isNotEmpty(cpuInfoList.getValues())) {
|
if (CollUtil.isNotEmpty(cpuInfoList.getValues())) {
|
||||||
List<List<Double>> pointDatas = cpuInfoList.getValues();
|
List<List<Double>> pointDatas = cpuInfoList.getValues();
|
||||||
for(List<Double> pointData : pointDatas) {
|
for (List<Double> pointData : pointDatas) {
|
||||||
Map<String,Object> pointDataMap = new HashMap<>();
|
Map<String, Object> pointDataMap = new HashMap<>();
|
||||||
Date date = new Date(pointData.get(0).longValue()*1000);
|
Date date = new Date(pointData.get(0).longValue() * 1000);
|
||||||
Double useRate = BigDecimal.valueOf(pointData.get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
Double useRate = BigDecimal.valueOf(pointData.get(1))
|
||||||
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
pointDataMap.put("date", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
pointDataMap.put("date", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
||||||
pointDataMap.put("usageRate", useRate);
|
pointDataMap.put("usageRate", useRate);
|
||||||
result.add(pointDataMap);
|
result.add(pointDataMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
} catch (Exception e) {
|
||||||
log.error("获取CPU信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
log.error(
|
||||||
|
"获取CPU信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",
|
||||||
|
e.getMessage());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -117,42 +129,45 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
* 获取CPU核心数
|
* 获取CPU核心数
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String,Object> getCpuCoreInfo(String ip) {
|
public Map<String, Object> getCpuCoreInfo(String ip) {
|
||||||
Map<String,Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
//Prometheus 服务器地址
|
//Prometheus 服务器地址
|
||||||
String url = serverProperties.getServerUrl();
|
String url = serverProperties.getServerUrl();
|
||||||
//目标主机实例(node-exporter 的地址)
|
//目标主机实例(node-exporter 的地址)
|
||||||
String instance = this.getInstance(ip);
|
String instance = this.getInstance(ip);
|
||||||
//查询CPU核数
|
//查询CPU核数
|
||||||
String cpuCoreQuery = "count(count by (cpu) (node_cpu_seconds_total{instance=\"" + instance + "\"}))";
|
String cpuCoreQuery =
|
||||||
|
"count(count by (cpu) (node_cpu_seconds_total{instance=\"" + instance + "\"}))";
|
||||||
PrometheusResponse response = webClient.get()
|
PrometheusResponse response = webClient.get()
|
||||||
.uri(buildUri(url,cpuCoreQuery))
|
.uri(buildUri(url, cpuCoreQuery))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(response) &&
|
if (Objects.nonNull(response) &&
|
||||||
Objects.nonNull(response.getData()) &&
|
Objects.nonNull(response.getData()) &&
|
||||||
CollUtil.isNotEmpty(response.getData().getResult())
|
CollUtil.isNotEmpty(response.getData().getResult())
|
||||||
) {
|
) {
|
||||||
PrometheusResponse.Result cpuInfo = response.getData().getResult().get(0);
|
PrometheusResponse.Result cpuInfo = response.getData().getResult().get(0);
|
||||||
if(CollUtil.isNotEmpty(cpuInfo.getValue())) {
|
if (CollUtil.isNotEmpty(cpuInfo.getValue())) {
|
||||||
Integer cpuCores = cpuInfo.getValue().get(1).intValue();
|
Integer cpuCores = cpuInfo.getValue().get(1).intValue();
|
||||||
result.put("cpuCores", cpuCores);
|
result.put("cpuCores", cpuCores);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
} catch (Exception e) {
|
||||||
log.error("获取CPU核心数错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
log.error(
|
||||||
|
"获取CPU核心数错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",
|
||||||
|
e.getMessage());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取内存信息
|
* 获取内存信息
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String,Object> getMemoryInfo(String ip) {
|
public Map<String, Object> getMemoryInfo(String ip) {
|
||||||
Map<String,Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
//Prometheus 服务器地址
|
//Prometheus 服务器地址
|
||||||
String url = serverProperties.getServerUrl();
|
String url = serverProperties.getServerUrl();
|
||||||
|
|
@ -193,28 +208,33 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//使用率
|
//使用率
|
||||||
String usageRateQuery = "(1 - (node_memory_MemAvailable_bytes{instance=\""+instance+"\"} / node_memory_MemTotal_bytes{instance=\""+instance+"\"})) * 100";
|
String usageRateQuery = "(1 - (node_memory_MemAvailable_bytes{instance=\"" + instance +
|
||||||
|
"\"} / node_memory_MemTotal_bytes{instance=\"" + instance + "\"})) * 100";
|
||||||
PrometheusResponse usageRateResponse = webClient.get()
|
PrometheusResponse usageRateResponse = webClient.get()
|
||||||
.uri(buildUri(url,usageRateQuery))
|
.uri(buildUri(url, usageRateQuery))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(usageRateResponse) &&
|
if (Objects.nonNull(usageRateResponse) &&
|
||||||
Objects.nonNull(usageRateResponse.getData()) &&
|
Objects.nonNull(usageRateResponse.getData()) &&
|
||||||
CollUtil.isNotEmpty(usageRateResponse.getData().getResult())
|
CollUtil.isNotEmpty(usageRateResponse.getData().getResult())
|
||||||
) {
|
) {
|
||||||
PrometheusResponse.Result usageRateInfo = usageRateResponse.getData().getResult().get(0);
|
PrometheusResponse.Result usageRateInfo =
|
||||||
if(CollUtil.isNotEmpty(usageRateInfo.getValue())) {
|
usageRateResponse.getData().getResult().get(0);
|
||||||
Date date = new Date(usageRateInfo.getValue().get(0).longValue()*1000);
|
if (CollUtil.isNotEmpty(usageRateInfo.getValue())) {
|
||||||
Double usageRate = BigDecimal.valueOf(usageRateInfo.getValue().get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
Date date = new Date(usageRateInfo.getValue().get(0).longValue() * 1000);
|
||||||
|
Double usageRate = BigDecimal.valueOf(usageRateInfo.getValue().get(1))
|
||||||
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
result.put("date", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
result.put("date", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
||||||
result.put("usageRate", usageRate);
|
result.put("usageRate", usageRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
} catch (Exception e) {
|
||||||
log.error("获取内存信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
log.error(
|
||||||
|
"获取内存信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",
|
||||||
|
e.getMessage());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -223,43 +243,48 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
* @param conditions
|
* @param conditions
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String,Object>> getMemoryInfoList(String ip,String conditions) {
|
public List<Map<String, Object>> getMemoryInfoList(String ip, String conditions) {
|
||||||
List<Map<String, Object>> result = new ArrayList<>();
|
List<Map<String, Object>> result = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
//Prometheus 服务器地址
|
//Prometheus 服务器地址
|
||||||
String url = serverProperties.getServerUrl();
|
String url = serverProperties.getServerUrl();
|
||||||
//目标主机实例(node-exporter 的地址)
|
//目标主机实例(node-exporter 的地址)
|
||||||
String instance = this.getInstance(ip);
|
String instance = this.getInstance(ip);
|
||||||
//使用率
|
//使用率
|
||||||
String usageRateQuery = "(1 - (node_memory_MemAvailable_bytes{instance=\""+instance+"\"} / node_memory_MemTotal_bytes{instance=\""+instance+"\"})) * 100";
|
String usageRateQuery = "(1 - (node_memory_MemAvailable_bytes{instance=\"" + instance +
|
||||||
PrometheusHostQueryTypeEnum queryTypeEnum = PrometheusHostQueryTypeEnum.getQueryTypeEnum(conditions);
|
"\"} / node_memory_MemTotal_bytes{instance=\"" + instance + "\"})) * 100";
|
||||||
|
PrometheusHostQueryTypeEnum queryTypeEnum =
|
||||||
|
PrometheusHostQueryTypeEnum.getQueryTypeEnum(conditions);
|
||||||
long end = Instant.now().getEpochSecond();
|
long end = Instant.now().getEpochSecond();
|
||||||
long start = end - queryTypeEnum.getLastSecond();
|
long start = end - queryTypeEnum.getLastSecond();
|
||||||
String step = queryTypeEnum.getStep();
|
String step = queryTypeEnum.getStep();
|
||||||
PrometheusResponse response = webClient.get()
|
PrometheusResponse response = webClient.get()
|
||||||
.uri(buildUri(url,usageRateQuery,start,end,step))
|
.uri(buildUri(url, usageRateQuery, start, end, step))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(response) &&
|
if (Objects.nonNull(response) &&
|
||||||
Objects.nonNull(response.getData()) &&
|
Objects.nonNull(response.getData()) &&
|
||||||
CollUtil.isNotEmpty(response.getData().getResult())
|
CollUtil.isNotEmpty(response.getData().getResult())
|
||||||
) {
|
) {
|
||||||
PrometheusResponse.Result usageRateList = response.getData().getResult().get(0);
|
PrometheusResponse.Result usageRateList = response.getData().getResult().get(0);
|
||||||
if(CollUtil.isNotEmpty(usageRateList.getValues())) {
|
if (CollUtil.isNotEmpty(usageRateList.getValues())) {
|
||||||
List<List<Double>> pointDatas = usageRateList.getValues();
|
List<List<Double>> pointDatas = usageRateList.getValues();
|
||||||
for(List<Double> pointData : pointDatas) {
|
for (List<Double> pointData : pointDatas) {
|
||||||
Map<String,Object> pointDataMap = new HashMap<>();
|
Map<String, Object> pointDataMap = new HashMap<>();
|
||||||
Date date = new Date(pointData.get(0).longValue()*1000);
|
Date date = new Date(pointData.get(0).longValue() * 1000);
|
||||||
Double useRate = BigDecimal.valueOf(pointData.get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
Double useRate = BigDecimal.valueOf(pointData.get(1))
|
||||||
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
pointDataMap.put("date", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
pointDataMap.put("date", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
||||||
pointDataMap.put("usageRate", useRate);
|
pointDataMap.put("usageRate", useRate);
|
||||||
result.add(pointDataMap);
|
result.add(pointDataMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
} catch (Exception e) {
|
||||||
log.error("获取CPU信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
log.error(
|
||||||
|
"获取CPU信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",
|
||||||
|
e.getMessage());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -279,18 +304,21 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
//查询总内存
|
//查询总内存
|
||||||
String totalMemoryQuery = "node_memory_MemTotal_bytes{instance=\"" + instance + "\"}";
|
String totalMemoryQuery = "node_memory_MemTotal_bytes{instance=\"" + instance + "\"}";
|
||||||
PrometheusResponse totalMemoryResponse = webClient.get()
|
PrometheusResponse totalMemoryResponse = webClient.get()
|
||||||
.uri(buildUri(url,totalMemoryQuery))
|
.uri(buildUri(url, totalMemoryQuery))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(totalMemoryResponse) &&
|
if (Objects.nonNull(totalMemoryResponse) &&
|
||||||
Objects.nonNull(totalMemoryResponse.getData()) &&
|
Objects.nonNull(totalMemoryResponse.getData()) &&
|
||||||
CollUtil.isNotEmpty(totalMemoryResponse.getData().getResult())
|
CollUtil.isNotEmpty(totalMemoryResponse.getData().getResult())
|
||||||
) {
|
) {
|
||||||
PrometheusResponse.Result totalMemoryInfo = totalMemoryResponse.getData().getResult().get(0);
|
PrometheusResponse.Result totalMemoryInfo =
|
||||||
if(CollUtil.isNotEmpty(totalMemoryInfo.getValue())) {
|
totalMemoryResponse.getData().getResult().get(0);
|
||||||
Double totalMemory = BigDecimal.valueOf(totalMemoryInfo.getValue().get(1)/1024/1024/1024).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
if (CollUtil.isNotEmpty(totalMemoryInfo.getValue())) {
|
||||||
result.put("totalMemory",totalMemory);
|
Double totalMemory =
|
||||||
|
BigDecimal.valueOf(totalMemoryInfo.getValue().get(1) / 1024 / 1024 / 1024)
|
||||||
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
|
result.put("totalMemory", totalMemory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -300,58 +328,71 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
* 获取网络信息
|
* 获取网络信息
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String,Object> getNetworkInfo(String ip,String conditions) {
|
public Map<String, Object> getNetworkInfo(String ip, String conditions) {
|
||||||
Map<String,Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
//Prometheus 服务器地址
|
//Prometheus 服务器地址
|
||||||
String url = serverProperties.getServerUrl();
|
String url = serverProperties.getServerUrl();
|
||||||
//目标主机实例(node-exporter 的地址)
|
//目标主机实例(node-exporter 的地址)
|
||||||
String instance = this.getInstance(ip);
|
String instance = this.getInstance(ip);
|
||||||
PrometheusHostQueryTypeEnum queryTypeEnum = PrometheusHostQueryTypeEnum.getQueryTypeEnum(conditions);
|
PrometheusHostQueryTypeEnum queryTypeEnum =
|
||||||
|
PrometheusHostQueryTypeEnum.getQueryTypeEnum(conditions);
|
||||||
String exprTime = queryTypeEnum.getExprTime();
|
String exprTime = queryTypeEnum.getExprTime();
|
||||||
//接收带宽 (Kbps)
|
//接收带宽 (Kbps)
|
||||||
String receiveKbpsQuery = "rate(node_network_receive_bytes_total{instance=\"" + instance + "\", device=\""+serverProperties.getNetworkCardName()+"\"}["+exprTime+"]) * 8 / 1000";
|
String receiveKbpsQuery =
|
||||||
|
"rate(node_network_receive_bytes_total{instance=\"" + instance +
|
||||||
|
"\", device=\"" + serverProperties.getNetworkCardName() + "\"}[" +
|
||||||
|
exprTime + "]) * 8 / 1000";
|
||||||
PrometheusResponse receiveKbpsResponse = webClient.get()
|
PrometheusResponse receiveKbpsResponse = webClient.get()
|
||||||
.uri(buildUri(url,receiveKbpsQuery))
|
.uri(buildUri(url, receiveKbpsQuery))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(receiveKbpsResponse) &&
|
if (Objects.nonNull(receiveKbpsResponse) &&
|
||||||
Objects.nonNull(receiveKbpsResponse.getData()) &&
|
Objects.nonNull(receiveKbpsResponse.getData()) &&
|
||||||
CollUtil.isNotEmpty(receiveKbpsResponse.getData().getResult())
|
CollUtil.isNotEmpty(receiveKbpsResponse.getData().getResult())
|
||||||
) {
|
) {
|
||||||
PrometheusResponse.Result receiveKbpsInfo = receiveKbpsResponse.getData().getResult().get(0);
|
PrometheusResponse.Result receiveKbpsInfo =
|
||||||
if(CollUtil.isNotEmpty(receiveKbpsInfo.getValue())) {
|
receiveKbpsResponse.getData().getResult().get(0);
|
||||||
Date date = new Date(receiveKbpsInfo.getValue().get(0).longValue()*1000);
|
if (CollUtil.isNotEmpty(receiveKbpsInfo.getValue())) {
|
||||||
Double receiveKbps = BigDecimal.valueOf(receiveKbpsInfo.getValue().get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
Date date = new Date(receiveKbpsInfo.getValue().get(0).longValue() * 1000);
|
||||||
|
Double receiveKbps = BigDecimal.valueOf(receiveKbpsInfo.getValue().get(1))
|
||||||
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
result.put("receiveDate", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
result.put("receiveDate", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
||||||
result.put("receiveKbps", receiveKbps);
|
result.put("receiveKbps", receiveKbps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//发送带宽 (Kbps)
|
//发送带宽 (Kbps)
|
||||||
String transmitKbpsQuery = "rate(node_network_transmit_bytes_total{instance=\"" + instance + "\", device=\""+serverProperties.getNetworkCardName()+"\"}["+exprTime+"]) * 8 / 1000";
|
String transmitKbpsQuery =
|
||||||
|
"rate(node_network_transmit_bytes_total{instance=\"" + instance +
|
||||||
|
"\", device=\"" + serverProperties.getNetworkCardName() + "\"}[" +
|
||||||
|
exprTime + "]) * 8 / 1000";
|
||||||
PrometheusResponse transmitKbpsResponse = webClient.get()
|
PrometheusResponse transmitKbpsResponse = webClient.get()
|
||||||
.uri(buildUri(url,transmitKbpsQuery))
|
.uri(buildUri(url, transmitKbpsQuery))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(transmitKbpsResponse) &&
|
if (Objects.nonNull(transmitKbpsResponse) &&
|
||||||
Objects.nonNull(transmitKbpsResponse.getData()) &&
|
Objects.nonNull(transmitKbpsResponse.getData()) &&
|
||||||
CollUtil.isNotEmpty(transmitKbpsResponse.getData().getResult())
|
CollUtil.isNotEmpty(transmitKbpsResponse.getData().getResult())
|
||||||
) {
|
) {
|
||||||
PrometheusResponse.Result transmitKbpsInfo = transmitKbpsResponse.getData().getResult().get(0);
|
PrometheusResponse.Result transmitKbpsInfo =
|
||||||
if(CollUtil.isNotEmpty(transmitKbpsInfo.getValue())) {
|
transmitKbpsResponse.getData().getResult().get(0);
|
||||||
Date date = new Date(transmitKbpsInfo.getValue().get(0).longValue()*1000);
|
if (CollUtil.isNotEmpty(transmitKbpsInfo.getValue())) {
|
||||||
Double transmitKbps = BigDecimal.valueOf(transmitKbpsInfo.getValue().get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
Date date = new Date(transmitKbpsInfo.getValue().get(0).longValue() * 1000);
|
||||||
|
Double transmitKbps = BigDecimal.valueOf(transmitKbpsInfo.getValue().get(1))
|
||||||
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
result.put("transmitDate", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
result.put("transmitDate", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
||||||
result.put("transmitKbps", transmitKbps);
|
result.put("transmitKbps", transmitKbps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
} catch (Exception e) {
|
||||||
log.error("获取网络信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
log.error(
|
||||||
|
"获取网络信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",
|
||||||
|
e.getMessage());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -360,38 +401,44 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, List<Map<String, Object>>> getNetworkInfoList(String ip,String conditions) {
|
public Map<String, List<Map<String, Object>>> getNetworkInfoList(String ip, String conditions) {
|
||||||
Map<String,List<Map<String, Object>>> result = new HashMap<>();
|
Map<String, List<Map<String, Object>>> result = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
//Prometheus 服务器地址
|
//Prometheus 服务器地址
|
||||||
String url = serverProperties.getServerUrl();
|
String url = serverProperties.getServerUrl();
|
||||||
//目标主机实例(node-exporter 的地址)
|
//目标主机实例(node-exporter 的地址)
|
||||||
String instance = this.getInstance(ip);
|
String instance = this.getInstance(ip);
|
||||||
//构建查询参数
|
//构建查询参数
|
||||||
PrometheusHostQueryTypeEnum queryTypeEnum = PrometheusHostQueryTypeEnum.getQueryTypeEnum(conditions);
|
PrometheusHostQueryTypeEnum queryTypeEnum =
|
||||||
|
PrometheusHostQueryTypeEnum.getQueryTypeEnum(conditions);
|
||||||
long end = Instant.now().getEpochSecond();
|
long end = Instant.now().getEpochSecond();
|
||||||
long start = end - queryTypeEnum.getLastSecond();
|
long start = end - queryTypeEnum.getLastSecond();
|
||||||
String step = queryTypeEnum.getStep();
|
String step = queryTypeEnum.getStep();
|
||||||
String exprTime = queryTypeEnum.getExprTime();
|
String exprTime = queryTypeEnum.getExprTime();
|
||||||
//接收带宽 (Kbps)
|
//接收带宽 (Kbps)
|
||||||
String receiveKbpsQuery = "rate(node_network_receive_bytes_total{instance=\"" + instance + "\", device=\""+serverProperties.getNetworkCardName()+"\"}["+exprTime+"]) * 8 / 1000";
|
String receiveKbpsQuery =
|
||||||
|
"rate(node_network_receive_bytes_total{instance=\"" + instance +
|
||||||
|
"\", device=\"" + serverProperties.getNetworkCardName() + "\"}[" +
|
||||||
|
exprTime + "]) * 8 / 1000";
|
||||||
PrometheusResponse receiveKbpsResponse = webClient.get()
|
PrometheusResponse receiveKbpsResponse = webClient.get()
|
||||||
.uri(buildUri(url,receiveKbpsQuery,start,end,step))
|
.uri(buildUri(url, receiveKbpsQuery, start, end, step))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(receiveKbpsResponse) &&
|
if (Objects.nonNull(receiveKbpsResponse) &&
|
||||||
Objects.nonNull(receiveKbpsResponse.getData()) &&
|
Objects.nonNull(receiveKbpsResponse.getData()) &&
|
||||||
CollUtil.isNotEmpty(receiveKbpsResponse.getData().getResult())
|
CollUtil.isNotEmpty(receiveKbpsResponse.getData().getResult())
|
||||||
) {
|
) {
|
||||||
PrometheusResponse.Result receiveKbpsInfo = receiveKbpsResponse.getData().getResult().get(0);
|
PrometheusResponse.Result receiveKbpsInfo =
|
||||||
if(CollUtil.isNotEmpty(receiveKbpsInfo.getValues())) {
|
receiveKbpsResponse.getData().getResult().get(0);
|
||||||
|
if (CollUtil.isNotEmpty(receiveKbpsInfo.getValues())) {
|
||||||
List<Map<String, Object>> receiveDataList = new ArrayList<>();
|
List<Map<String, Object>> receiveDataList = new ArrayList<>();
|
||||||
List<List<Double>> pointDatas = receiveKbpsInfo.getValues();
|
List<List<Double>> pointDatas = receiveKbpsInfo.getValues();
|
||||||
for(List<Double> pointData : pointDatas) {
|
for (List<Double> pointData : pointDatas) {
|
||||||
Map<String,Object> pointDataMap = new HashMap<>();
|
Map<String, Object> pointDataMap = new HashMap<>();
|
||||||
Date date = new Date(pointData.get(0).longValue()*1000);
|
Date date = new Date(pointData.get(0).longValue() * 1000);
|
||||||
Double useRate = BigDecimal.valueOf(pointData.get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
Double useRate = BigDecimal.valueOf(pointData.get(1))
|
||||||
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
pointDataMap.put("receiveDate", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
pointDataMap.put("receiveDate", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
||||||
pointDataMap.put("receiveKbps", useRate);
|
pointDataMap.put("receiveKbps", useRate);
|
||||||
receiveDataList.add(pointDataMap);
|
receiveDataList.add(pointDataMap);
|
||||||
|
|
@ -401,24 +448,29 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
//发送带宽 (Kbps)
|
//发送带宽 (Kbps)
|
||||||
String transmitKbpsQuery = "rate(node_network_transmit_bytes_total{instance=\"" + instance + "\", device=\""+serverProperties.getNetworkCardName()+"\"}["+exprTime+"]) * 8 / 1000";
|
String transmitKbpsQuery =
|
||||||
|
"rate(node_network_transmit_bytes_total{instance=\"" + instance +
|
||||||
|
"\", device=\"" + serverProperties.getNetworkCardName() + "\"}[" +
|
||||||
|
exprTime + "]) * 8 / 1000";
|
||||||
PrometheusResponse transmitKbpsResponse = webClient.get()
|
PrometheusResponse transmitKbpsResponse = webClient.get()
|
||||||
.uri(buildUri(url,transmitKbpsQuery,start,end,step))
|
.uri(buildUri(url, transmitKbpsQuery, start, end, step))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(transmitKbpsResponse) &&
|
if (Objects.nonNull(transmitKbpsResponse) &&
|
||||||
Objects.nonNull(transmitKbpsResponse.getData()) &&
|
Objects.nonNull(transmitKbpsResponse.getData()) &&
|
||||||
CollUtil.isNotEmpty(transmitKbpsResponse.getData().getResult())
|
CollUtil.isNotEmpty(transmitKbpsResponse.getData().getResult())
|
||||||
) {
|
) {
|
||||||
PrometheusResponse.Result transmitKbpsInfo = transmitKbpsResponse.getData().getResult().get(0);
|
PrometheusResponse.Result transmitKbpsInfo =
|
||||||
if(CollUtil.isNotEmpty(transmitKbpsInfo.getValues())) {
|
transmitKbpsResponse.getData().getResult().get(0);
|
||||||
|
if (CollUtil.isNotEmpty(transmitKbpsInfo.getValues())) {
|
||||||
List<Map<String, Object>> transmitDataList = new ArrayList<>();
|
List<Map<String, Object>> transmitDataList = new ArrayList<>();
|
||||||
List<List<Double>> pointDatas = transmitKbpsInfo.getValues();
|
List<List<Double>> pointDatas = transmitKbpsInfo.getValues();
|
||||||
for(List<Double> pointData : pointDatas) {
|
for (List<Double> pointData : pointDatas) {
|
||||||
Map<String,Object> pointDataMap = new HashMap<>();
|
Map<String, Object> pointDataMap = new HashMap<>();
|
||||||
Date date = new Date(pointData.get(0).longValue()*1000);
|
Date date = new Date(pointData.get(0).longValue() * 1000);
|
||||||
Double useRate = BigDecimal.valueOf(pointData.get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
Double useRate = BigDecimal.valueOf(pointData.get(1))
|
||||||
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
pointDataMap.put("receiveDate", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
pointDataMap.put("receiveDate", DateUtil.format(date, "MM/dd HH:mm:ss"));
|
||||||
pointDataMap.put("receiveKbps", useRate);
|
pointDataMap.put("receiveKbps", useRate);
|
||||||
transmitDataList.add(pointDataMap);
|
transmitDataList.add(pointDataMap);
|
||||||
|
|
@ -426,42 +478,51 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
result.put("transmitData", transmitDataList);
|
result.put("transmitData", transmitDataList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
} catch (Exception e) {
|
||||||
log.error("获取网络信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
log.error(
|
||||||
|
"获取网络信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",
|
||||||
|
e.getMessage());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取磁盘使用率
|
* 获取磁盘使用率
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String,Object> getDiskInfo(String ip) {
|
public Map<String, Object> getDiskInfo(String ip) {
|
||||||
Map<String,Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
//Prometheus 服务器地址
|
//Prometheus 服务器地址
|
||||||
String url = serverProperties.getServerUrl();
|
String url = serverProperties.getServerUrl();
|
||||||
//目标主机实例(node-exporter 的地址)
|
//目标主机实例(node-exporter 的地址)
|
||||||
String instance = this.getInstance(ip);
|
String instance = this.getInstance(ip);
|
||||||
//磁盘使用率
|
//磁盘使用率
|
||||||
String diskUsageQuery = "((node_filesystem_size_bytes{instance=\""+instance+"\", device!~\"rootfs\"} - node_filesystem_avail_bytes{instance=\""+instance+"\", device!~\"rootfs\"}) / node_filesystem_size_bytes{instance=\""+instance+"\", device!~\"rootfs\"}) * 100";
|
String diskUsageQuery = "((node_filesystem_size_bytes{instance=\"" + instance +
|
||||||
|
"\", device!~\"rootfs\"} - node_filesystem_avail_bytes{instance=\"" + instance +
|
||||||
|
"\", device!~\"rootfs\"}) / node_filesystem_size_bytes{instance=\"" + instance +
|
||||||
|
"\", device!~\"rootfs\"}) * 100";
|
||||||
PrometheusResponse diskUsageResponse = webClient.get()
|
PrometheusResponse diskUsageResponse = webClient.get()
|
||||||
.uri(buildUri(url,diskUsageQuery))
|
.uri(buildUri(url, diskUsageQuery))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(PrometheusResponse.class)
|
.bodyToMono(PrometheusResponse.class)
|
||||||
.block();
|
.block();
|
||||||
if(Objects.nonNull(diskUsageResponse) &&
|
if (Objects.nonNull(diskUsageResponse) &&
|
||||||
Objects.nonNull(diskUsageResponse.getData()) &&
|
Objects.nonNull(diskUsageResponse.getData()) &&
|
||||||
CollUtil.isNotEmpty(diskUsageResponse.getData().getResult())
|
CollUtil.isNotEmpty(diskUsageResponse.getData().getResult())
|
||||||
) {
|
) {
|
||||||
for (PrometheusResponse.Result responseData :diskUsageResponse.getData().getResult()){
|
for (PrometheusResponse.Result responseData : diskUsageResponse.getData()
|
||||||
|
.getResult()) {
|
||||||
String mountpoint = responseData.getMetric().getMountpoint();
|
String mountpoint = responseData.getMetric().getMountpoint();
|
||||||
Double usageRate = BigDecimal.valueOf(responseData.getValue().get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
Double usageRate = BigDecimal.valueOf(responseData.getValue().get(1))
|
||||||
result.put(mountpoint,usageRate);
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
|
result.put(mountpoint, usageRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
} catch (Exception e) {
|
||||||
log.error("获取磁盘使用率错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
log.error(
|
||||||
|
"获取磁盘使用率错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",
|
||||||
|
e.getMessage());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -478,29 +539,32 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取服务器实例
|
* 获取服务器实例
|
||||||
|
*
|
||||||
* @param ip
|
* @param ip
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getInstance(String ip) {
|
private String getInstance(String ip) {
|
||||||
if(StrUtil.isBlank(ip)){
|
if (StrUtil.isBlank(ip)) {
|
||||||
Map.Entry<String, Integer> first = serverProperties.getInstances().entrySet().stream().findFirst().get();
|
Map.Entry<String, Integer> first =
|
||||||
return first.getKey()+":"+first.getValue();
|
serverProperties.getInstances().entrySet().stream().findFirst().get();
|
||||||
|
return first.getKey() + ":" + first.getValue();
|
||||||
}
|
}
|
||||||
if (!serverProperties.getInstances().containsKey(ip)){
|
if (!serverProperties.getInstances().containsKey(ip)) {
|
||||||
throw new RuntimeException("此ip不在服务器列表中,请检查监控ip列表配置");
|
throw new RuntimeException("此ip不在服务器列表中,请检查监控ip列表配置");
|
||||||
}
|
}
|
||||||
Integer port = serverProperties.getInstances().get(ip);
|
Integer port = serverProperties.getInstances().get(ip);
|
||||||
//return "192.168.186.143"+":"+port;
|
//return "192.168.186.143"+":"+port;
|
||||||
return ip+":"+port;
|
return ip + ":" + port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建URI
|
* 构建URI
|
||||||
|
*
|
||||||
* @param url
|
* @param url
|
||||||
* @param query
|
* @param query
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private URI buildUri(String url,String query){
|
private URI buildUri(String url, String query) {
|
||||||
URI uri = UriComponentsBuilder.fromHttpUrl(url + "/api/v1/query")
|
URI uri = UriComponentsBuilder.fromHttpUrl(url + "/api/v1/query")
|
||||||
.queryParam("query", query)
|
.queryParam("query", query)
|
||||||
.build()
|
.build()
|
||||||
|
|
@ -510,11 +574,12 @@ public class HostMonitorServiceImpl implements HostMonitorService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建URI
|
* 构建URI
|
||||||
|
*
|
||||||
* @param url
|
* @param url
|
||||||
* @param query
|
* @param query
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private URI buildUri(String url,String query,Long start,Long end,String step){
|
private URI buildUri(String url, String query, Long start, Long end, String step) {
|
||||||
String uriAddr = String.format(
|
String uriAddr = String.format(
|
||||||
"%s/api/v1/query_range?query=%s&start=%d&end=%d&step=%s",
|
"%s/api/v1/query_range?query=%s&start=%d&end=%d&step=%s",
|
||||||
url,
|
url,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user