告警设置、告警上报

This commit is contained in:
qiminbao
2025-09-11 18:33:14 +08:00
parent 2c23692f01
commit 2c29156748
12 changed files with 657 additions and 67 deletions
@@ -1,6 +1,10 @@
package com.tongran.agent.client.core.config;
import com.tongran.agent.client.core.eo.AlarmEO;
import com.tongran.agent.client.core.eo.NativeNetworkInterfaceEO;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -22,7 +26,7 @@ public class GlobalConfig {
public static String CLIENT_ID;
/**
* 交换机
* 交换机信息
*/
public static String SWITCH_COMMUNITY; //团名
public static String SWITCH_IP; //交换机IP
@@ -40,7 +44,7 @@ public class GlobalConfig {
public static boolean isCollect = false;
public static Map<String, Long> taskIds = new ConcurrentHashMap<>();
/**
* 系统监控
* 采集系统监控
*/
public static boolean cpuCollect = false; //cpu采集
public static long cpuInterval = 300; //cpu采集间隔
@@ -53,7 +57,7 @@ public class GlobalConfig {
public static boolean dockerCollect = false; //docker采集
public static long dockerInterval = 300; //docker采集间隔
/**
* 系统其他监控
* 采集系统其他监控
*/
public static boolean systemSwapSizeFreeCollect = false; //交换卷/文件的可用空间(字节)采集
public static long systemSwapSizeFreeInterval = 300; //交换卷/文件的可用空间(字节)采集间隔
@@ -90,7 +94,7 @@ public class GlobalConfig {
public static boolean procNumCollect = false; //进程数采集
public static long procNumInterval = 300; //进程数采集间隔
/**
* 交换机监控
* 采集交换机监控
*/
public static boolean switchNetCollect = false; //交换机网络采集
public static long switchNetInterval = 300; //交换机网络采集间隔
@@ -103,7 +107,7 @@ public class GlobalConfig {
public static boolean switchFanCollect = false; //风扇采集
public static long switchFanInterval = 300; //风扇采集间隔
/**
* 交换机其他监控
* 采集交换机其他监控
*/
public static boolean switchSysDescrCollect = false; //系统描述采集
public static long switchSysDescrInterval = 300; //系统描述采集间隔
@@ -135,6 +139,28 @@ public class GlobalConfig {
public static long switchHwCurrentPowerInterval = 300; //系统实时功率(mW)采集间隔
/**
* 告警
*/
public static boolean IS_ALARM = false;
public static long ALARM_INTERVAL = 120;
public static List<AlarmEO> ALARM_LIST; //告警设置信息
/**
* 告警监控
*/
public static boolean systemCpuUti = false; //CPU使用率
public static boolean memoryUtilization = false; //内存利用率
public static boolean systemSwapSizePercent = false; //可用交换空间百分比
public static boolean systemUsersNum = false; //登录用户数
public static boolean vfsFsUtil = false; //挂载点的空间利用率
public static boolean netIfStatus = false; //网络运行状态UP变down
public static boolean netUtil = false; //网络带宽使用率
public static boolean containerMemUtil = false; //容器内存使用率
public static boolean extraPorts = false; //多余端口
/**
* 所有网络接口
*/
public static List<NativeNetworkInterfaceEO> NET_LIST;
}
@@ -38,6 +38,8 @@ public enum MsgEnum {
系统其他上报("OTHER_SYSTEM"),
告警上报("ALARM"),
开启系统采集("SYSTEM_COLLECT_START"),
开启系统采集应答("SYSTEM_COLLECT_START_RSP"),
@@ -0,0 +1,25 @@
package com.tongran.agent.client.core.eo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AlarmEO {
//告警内容类型
private String type;
//是否开启标识:默认false
private boolean collect;
//告警阈值
private String threshold;
//比较类型:0、大于;1、大于且等于;2、小于;3、小于且等于;
private int compareType;
}
@@ -0,0 +1,16 @@
package com.tongran.agent.client.core.eo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class NativeNetworkInterfaceEO {
private String name;
private String displayName;
private boolean up;
}
@@ -0,0 +1,22 @@
package com.tongran.agent.client.core.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@Data
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "告警信息")
public class AlarmVO {
@Schema(description = "告警内容类型")
private String type;
private String result;
@Schema(description = "时间戳")
private long timestamp;
}
@@ -7,6 +7,7 @@ import com.alibaba.fastjson2.TypeReference;
import com.tongran.agent.client.core.config.GlobalConfig;
import com.tongran.agent.client.core.enums.MsgEnum;
import com.tongran.agent.client.core.eo.AgentVersionUpdateEO;
import com.tongran.agent.client.core.eo.AlarmEO;
import com.tongran.agent.client.core.eo.ScriptPolicyEO;
import com.tongran.agent.client.netty.annotation.AgentDispatcher;
import com.tongran.agent.client.netty.basics.AgentHandler;
@@ -19,6 +20,7 @@ import com.tongran.agent.client.scheduler.service.Java8FileDownloader;
import com.tongran.agent.client.scheduler.task.SpecificTimeRequest;
import com.tongran.agent.client.scheduler.task.SpecificTimeTaskService;
import com.tongran.agent.client.service.AgentService;
import com.tongran.agent.client.utils.AgentDataUtil;
import com.tongran.agent.client.utils.AgentUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
@@ -201,63 +203,24 @@ public class AgentEndpoint {
public class AlarmSetHandler implements AgentHandler {
@Override
public UpMsgResponse upHandle(String data, String clientId) {
// //更改全局变量
// JSONObject jsonObject = JSONObject.parseObject(data);
// if(jsonObject.containsKey("switchBoard")){
// String switchBoard = jsonObject.getString("switchBoard");
// jsonObject = JSONObject.parseObject(switchBoard);
// if(jsonObject.containsKey("community")){
// GlobalConfig.SWITCH_COMMUNITY = jsonObject.getString("community");
// }
// if(jsonObject.containsKey("ip")){
// GlobalConfig.SWITCH_IP = jsonObject.getString("ip");
// }
// if(jsonObject.containsKey("port")){
// GlobalConfig.SWITCH_PORT = jsonObject.getInteger("port");
// }
// if(jsonObject.containsKey("netOID")){
// String netOID = jsonObject.getString("netOID");
// LinkedHashMap<String, String> map = JSON.parseObject(netOID, new TypeReference<LinkedHashMap<String, String>>() {});
// GlobalConfig.SWITCH_NET_OID = map;
// }
// if(jsonObject.containsKey("moduleOID")){
// String moduleOID = jsonObject.getString("moduleOID");
// LinkedHashMap<String, String> map = JSON.parseObject(moduleOID, new TypeReference<LinkedHashMap<String, String>>() {});
// GlobalConfig.SWITCH_MODULE_OID = map;
// }
// if(jsonObject.containsKey("mpuOID")){
// String mpuOID = jsonObject.getString("mpuOID");
// LinkedHashMap<String, String> map = JSON.parseObject(mpuOID, new TypeReference<LinkedHashMap<String, String>>() {});
// GlobalConfig.SWITCH_MPU_OID = map;
// }
// if(jsonObject.containsKey("pwrOID")){
// String pwrOID = jsonObject.getString("pwrOID");
// LinkedHashMap<String, String> map = JSON.parseObject(pwrOID, new TypeReference<LinkedHashMap<String, String>>() {});
// GlobalConfig.SWITCH_PWR_OID = map;
// }
// if(jsonObject.containsKey("fanOID")){
// String fanOID = jsonObject.getString("fanOID");
// LinkedHashMap<String, String> map = JSON.parseObject(fanOID, new TypeReference<LinkedHashMap<String, String>>() {});
// GlobalConfig.SWITCH_FAN_OID = map;
// }
// if(jsonObject.containsKey("otherOID")){
// String otherOID = jsonObject.getString("otherOID");
// LinkedHashMap<String, String> map = JSON.parseObject(otherOID, new TypeReference<LinkedHashMap<String, String>>() {});
// GlobalConfig.SWITCH_OTHER_OID = map;
// }
// }
// GlobalConfig.isCollect = true;
// GlobalConfig.CLIENT_ID = clientId;
// //调用采集任务
// try {
// appInitializer.run();
// } catch (Exception e) {
// e.printStackTrace();
// }
// JSONObject json = new JSONObject();
// json.put("resCode",1);
//更改全局变量
JSONObject jsonObject = JSONObject.parseObject(data);
if(jsonObject.containsKey("alarms")){
String alarms = jsonObject.getString("alarms");
GlobalConfig.ALARM_LIST = JSON.parseObject(alarms, new TypeReference<List<AlarmEO>>() {});
if(CollectionUtil.isNotEmpty(GlobalConfig.ALARM_LIST)){
GlobalConfig.IS_ALARM = AgentDataUtil.hasAnyActiveAlarm(GlobalConfig.ALARM_LIST);
}
}
agentService.alarmMonitor();
long timestamp = System.currentTimeMillis();
timestamp = Math.round(timestamp / 1000.0);
JSONObject json = new JSONObject();
json.put("resCode",1);
json.put("resMag","");
json.put("timestamp",timestamp);
return UpMsgResponse.builder().clientId(clientId).dataType(MsgEnum.告警设置应答.getValue())
.content("").build();
.content(json.toString()).build();
}
}
@@ -1,5 +1,6 @@
package com.tongran.agent.client.scheduler.service;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
@@ -12,6 +13,7 @@ import com.tongran.agent.client.netty.model.Message;
import com.tongran.agent.client.service.*;
import com.tongran.agent.client.utils.AgentUtil;
import com.tongran.agent.client.utils.AssertLog;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@@ -34,6 +36,7 @@ public class BusinessTasks {
private final AtomicInteger task7Counter = new AtomicInteger(0);
private final AtomicInteger task8Counter = new AtomicInteger(0);
private final AtomicInteger task9Counter = new AtomicInteger(0);
private final AtomicInteger task10Counter = new AtomicInteger(0);
protected final SessionManager sessionManager;
@@ -69,6 +72,9 @@ public class BusinessTasks {
@Resource
private SystemService systemService;
@Resource
private AlarmService alarmService;
@Resource
private ApplicationProperties properties;
@@ -130,8 +136,11 @@ public class BusinessTasks {
// 判定客户端与服务端是否连接
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
// 发送磁盘信息包
String data = "";
List<DiskVO> list = diskService.diskList(timestamp);
String data = JSONArray.toJSONString(list);
if(CollectionUtil.isNotEmpty(list)){
data = JSONArray.toJSONString(list);
}
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.磁盘上报.getValue()).data(data).build();
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
}
@@ -150,8 +159,11 @@ public class BusinessTasks {
// 判定客户端与服务端是否连接
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
// 发送容器包
String data = "";
List<DockerVO> list = dockerService.dockerList(timestamp);
String data = JSONArray.toJSONString(list);
if(CollectionUtil.isNotEmpty(list)){
data = JSONArray.toJSONString(list);
}
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.容器上报.getValue()).data(data).build();
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
}
@@ -190,8 +202,11 @@ public class BusinessTasks {
// 判定客户端与服务端是否连接
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
// 发送网卡信息包
String data = "";
List<NetVO> list = netService.netList(timestamp);
String data = JSONArray.toJSONString(list);
if(CollectionUtil.isNotEmpty(list)){
data = JSONArray.toJSONString(list);
}
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.网络上报.getValue()).data(data).build();
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
}
@@ -210,8 +225,11 @@ public class BusinessTasks {
// 判定客户端与服务端是否连接
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
// 发送挂载点信息包
String data = "";
List<PointVO> list = diskService.pointList(timestamp);
String data = JSONArray.toJSONString(list);
if(CollectionUtil.isNotEmpty(list)){
data = JSONArray.toJSONString(list);
}
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.挂载上报.getValue()).data(data).build();
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
}
@@ -233,8 +251,11 @@ public class BusinessTasks {
// List<SwitchBoardVO> list = switchBoardService.switchBoardList(timestamp);
// String data = JSONArray.toJSONString(list);
// Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.交换机上报.getValue()).data(data).build();
JSONObject jsonObject = new JSONObject();
String data = switchBoardService.getSwitchDataByType(type);
JSONObject jsonObject = JSONObject.parseObject(data);
if(StringUtils.isNotBlank(data)){
jsonObject = JSONObject.parseObject(data);
}
jsonObject.put("timestamp", timestamp);
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.交换机上报.getValue()).data(jsonObject.toString()).build();
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
@@ -248,6 +269,7 @@ public class BusinessTasks {
@Async("taskExecutor")
public void systemTask(String type) {
long timestamp = System.currentTimeMillis();
timestamp = Math.round(timestamp / 1000.0);
int count = task9Counter.incrementAndGet();
AssertLog.info("系统信息采集定时任务执行 - 时间: {},task #{}", LocalDateTime.now(), count);
// 判定客户端与服务端是否连接
@@ -257,8 +279,11 @@ public class BusinessTasks {
// systemVO.setTimestamp(timestamp);
// String data = JSON.toJSONString(systemVO);
// Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.系统其他上报.getValue()).data(data).build();
JSONObject jsonObject = new JSONObject();
String data = systemService.otherSystem(type);
JSONObject jsonObject = JSONObject.parseObject(data);
if(StringUtils.isNotBlank(data)){
jsonObject = JSONObject.parseObject(data);
}
jsonObject.put("timestamp", timestamp);
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.系统其他上报.getValue()).data(jsonObject.toString()).build();
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
@@ -266,4 +291,26 @@ public class BusinessTasks {
AssertLog.info("系统信息采集定时任务执行 - task #{} completed", count);
}
/**
* 任务10:告警监控任务
*/
@Async("taskExecutor")
public void alarmTask() {
long timestamp = System.currentTimeMillis();
timestamp = Math.round(timestamp / 1000.0);
int count = task10Counter.incrementAndGet();
AssertLog.info("告警监控定时任务执行 - 时间: {},task #{}", LocalDateTime.now(), count);
// 判定客户端与服务端是否连接
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
String data = "";
List<AlarmVO> list = alarmService.alarmMonitor(timestamp);
if(CollectionUtil.isNotEmpty(list)){
data = JSONArray.toJSONString(list);
}
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.告警上报.getValue()).data(data).build();
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
}
AssertLog.info("告警监控定时任务执行 - task #{} completed", count);
}
}
@@ -8,4 +8,6 @@ public interface AgentService {
void switchCollectStart(String data);
void switchCollectStop();
void alarmMonitor();
}
@@ -0,0 +1,9 @@
package com.tongran.agent.client.service;
import com.tongran.agent.client.core.vo.AlarmVO;
import java.util.List;
public interface AlarmService {
List<AlarmVO> alarmMonitor(long timestamp);
}
@@ -377,5 +377,19 @@ public class AgentServiceImpl implements AgentService {
GlobalConfig.switchHwCurrentPowerInterval = 300; //系统实时功率(mW)采集间隔
}
@Override
public void alarmMonitor() {
if(GlobalConfig.IS_ALARM){
//开启告警监控
long milli = AgentUtil.getMillisToNextMinute() + 60000;
dynamicTaskService.scheduleTask("alarmTask",
businessTasks::alarmTask, milli, GlobalConfig.ALARM_INTERVAL*1000L);
}else{
//关闭告警监控
dynamicTaskService.cancelTask("alarmTask");
}
}
}
@@ -0,0 +1,456 @@
package com.tongran.agent.client.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import com.github.dockerjava.transport.DockerHttpClient;
import com.tongran.agent.client.core.config.GlobalConfig;
import com.tongran.agent.client.core.eo.AlarmEO;
import com.tongran.agent.client.core.eo.NativeNetworkInterfaceEO;
import com.tongran.agent.client.core.vo.AlarmVO;
import com.tongran.agent.client.service.AlarmService;
import com.tongran.agent.client.utils.AgentDataUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.NetworkIF;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@Service
public class AlarmServiceImpl implements AlarmService {
@Override
public List<AlarmVO> alarmMonitor(long timestamp) {
List<AlarmVO> alarmVOList = new ArrayList<>();
List<AlarmEO> list = GlobalConfig.ALARM_LIST.stream().filter(a -> a.isCollect() == true).collect(Collectors.toList());
if(CollectionUtil.isNotEmpty(list)){
for (AlarmEO alarmEO : list) {
String type = alarmEO.getType();
String threshold = alarmEO.getThreshold();
int compareType = alarmEO.getCompareType();
AlarmVO alarmVO = AlarmVO.builder().type(type).timestamp(timestamp).build();
switch(type) {
case "systemCpuUti": //CPU使用率
alarmVO.setResult(handleSystemCpuUti(threshold, compareType));
alarmVOList.add(alarmVO);
break;
case "memoryUtilization": //内存利用率
alarmVO.setResult(handleMemoryUtilization(threshold, compareType));
alarmVOList.add(alarmVO);
break;
case "systemSwapSizePercent": //可用交换空间百分比
alarmVO.setResult(handleSystemSwapSizePercent(threshold, compareType));
alarmVOList.add(alarmVO);
break;
case "systemUsersNum": //登录用户数
alarmVO.setResult(handleSystemUsersNum(threshold, compareType));
alarmVOList.add(alarmVO);
break;
case "vfsFsUtil": //挂载点的空间利用率
alarmVO.setResult(handleVfsFsUtil(threshold, compareType));
alarmVOList.add(alarmVO);
break;
case "netUtil": //网络带宽使用率
alarmVO.setResult(handleNetUtil(threshold, compareType));
alarmVOList.add(alarmVO);
break;
case "containerMemUtil": //容器内存使用率
alarmVO.setResult(handleContainerMemUtil(threshold, compareType));
alarmVOList.add(alarmVO);
break;
case "netIfStatus": //网络运行状态UP变down
alarmVO.setResult(handleNetIfStatus());
alarmVOList.add(alarmVO);
break;
case "extraPorts": //多余端口
alarmVO.setResult(handleExtraPorts(threshold));
alarmVOList.add(alarmVO);
break;
default: //其他
break;
}
}
}
return alarmVOList;
}
private String handleSystemCpuUti(String threshold, int compareType){
try {
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
CentralProcessor processor = hal.getProcessor();
long[] prevTicks = processor.getSystemCpuLoadTicks();
try {
TimeUnit.SECONDS.sleep(1); // 等待1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
// 计算使用率
double cpuUsage = processor.getSystemCpuLoadBetweenTicks(prevTicks) * 100;
boolean isFalse = false;
if(StringUtils.isNotBlank(threshold)){
isFalse = compare(cpuUsage, threshold, compareType);
}
if(isFalse){
return "当前CPU使用率:"+cpuUsage +"%";
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
private String handleMemoryUtilization(String threshold, int compareType){
try {
Map<String, Long> memInfo = AgentDataUtil.parseMemInfo();
long total = memInfo.get("MemTotal");
long available = memInfo.getOrDefault("MemAvailable",
memInfo.get("MemFree") +
memInfo.getOrDefault("Buffers", 0L) +
memInfo.getOrDefault("Cached", 0L) +
memInfo.getOrDefault("SReclaimable", 0L));
// 总内存使用率
double totalUsage = (double)(total - available) / total * 100;
boolean isFalse = false;
if(StringUtils.isNotBlank(threshold)){
isFalse = compare(totalUsage, threshold, compareType);
}
if(isFalse){
return "当前内存利用率:"+totalUsage +"%";
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
private String handleSystemSwapSizePercent(String threshold, int compareType){
try {
Map<String, Long> memInfo = AgentDataUtil.parseMemInfo();
long swapTotal = memInfo.getOrDefault("SwapTotal", 0L);
long swapFree = memInfo.getOrDefault("SwapFree", 0L);
double swapSizePercent = (double) swapFree / swapTotal * 100; //可用交换空间百分比
boolean isFalse = false;
if(StringUtils.isNotBlank(threshold)){
isFalse = compare(swapSizePercent, threshold, compareType);
}
if(isFalse){
return "当前可用交换空间百分比:"+swapSizePercent +"%";
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
private String handleSystemUsersNum(String threshold, int compareType){
SystemInfo si = new SystemInfo();
OperatingSystem os = si.getOperatingSystem();
int userNum = os.getSessions().size();
boolean isFalse = false;
if(StringUtils.isNotBlank(threshold)){
isFalse = compare(userNum, threshold, compareType);
}
if(isFalse){
return "当前登录用户数:"+userNum;
}
return "";
}
private String handleVfsFsUtil(String threshold, int compareType){
String result = "";
SystemInfo si = new SystemInfo();
for (OSFileStore fs : si.getOperatingSystem().getFileSystem().getFileStores()) {
String mount = fs.getMount();
long totalSpace = fs.getTotalSpace();
long freeSpace = fs.getFreeSpace();
double usagePercentage = totalSpace > 0 ?
(double) (totalSpace - freeSpace) / totalSpace * 100 : 0;
if(StringUtils.isNotBlank(threshold)){
boolean isFalse = compare(usagePercentage, threshold, compareType);
if(isFalse){
result +="挂载点:"+mount+",当前空间利用率:"+usagePercentage+"%";
}
}
}
return result;
}
private String handleNetUtil(String threshold, int compareType){
String result = "";
try {
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
// 获取所有网络接口
List<NetworkIF> networkIFs = hal.getNetworkIFs();
// 第一次采样
for (NetworkIF net : networkIFs) {
net.updateAttributes();
}
// 等待1秒
TimeUnit.SECONDS.sleep(1);
// 第二次采样并计算速率
for (NetworkIF net : networkIFs) {
// 只显示以太网接口
if (net.getName().startsWith("eth") ||
net.getName().startsWith("en") ||
net.getDisplayName().toLowerCase().contains("ethernet")) {
long prevBytesSent = net.getBytesSent();
net.updateAttributes();
long bytesSent = net.getBytesSent() - prevBytesSent;
// 获取最大带宽
double maxBandwidth = getInterfaceMaxBandwidth(net);
// 计算使用率百分比
double sentUsagePercentage = (bytesToMbps(bytesSent) / maxBandwidth) * 100;
boolean isFalse = false;
if(StringUtils.isNotBlank(threshold)){
isFalse = compare(sentUsagePercentage, threshold, compareType);
}
if(isFalse){
result += "网络接口:"+ net.getName() + ",当前发送流量带宽使用率:" + sentUsagePercentage +"%";
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private String handleContainerMemUtil(String threshold, int compareType){
// 配置Docker客户端
DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost("unix:///var/run/docker.sock")
.withDockerTlsVerify(false) // 根据你的配置调整
.build();
DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
.dockerHost(config.getDockerHost())
.sslConfig(config.getSSLConfig())
.maxConnections(100)
.connectionTimeout(Duration.ofSeconds(30))
.responseTimeout(Duration.ofSeconds(45))
.build();
DockerClient dockerClient = DockerClientImpl.getInstance(config, httpClient);
String result = "";
try {
// 获取正在运行的容器列表
List<Container> containers = dockerClient.listContainersCmd()
.withShowAll(false) // 只显示运行中的容器
.exec();
// 打印容器信息
System.out.println("运行中的Docker容器:");
System.out.println("容器ID\t\t镜像\t\t状态\t\t名称");
for (Container container : containers) {
String id = container.getId().substring(0, 12); // 只显示短ID
String name = container.getNames()[0].replaceFirst("/", "");
// 执行 docker stats 命令(--no-stream 表示只输出一次)
Process process = new ProcessBuilder(
"docker", "stats", "--no-stream", id,
"--format", "'table {{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemPerc}}\t{{.NetIO}}"
).start();
// 读取命令输出
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.trim().split("\\s+");
String memUtil = parts[4]; // 内存使用率
memUtil = memUtil.replace("%","");
if(StringUtils.isNotBlank(memUtil)){
boolean isFalse = false;
if(StringUtils.isNotBlank(threshold)){
isFalse = compare(Double.parseDouble(memUtil), threshold, compareType);
}
if(isFalse){
result += "容器:"+name+",当前内存使用率"+memUtil+"%";
}
}
}
// 等待命令执行完成并获取退出码
int exitCode = process.waitFor();
if (exitCode != 0) {
System.err.println("命令执行失败,退出码: " + exitCode);
}
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
dockerClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
private String handleNetIfStatus(){
String result = "";
try {
List<NativeNetworkInterfaceEO> list = getAllNetworkInterfaces();
if(CollectionUtil.isNotEmpty(GlobalConfig.NET_LIST)){
List<String> natList = list.stream().filter(n -> n.isUp() == false).map(NativeNetworkInterfaceEO::getName).collect(Collectors.toList());
List<NativeNetworkInterfaceEO> temp = GlobalConfig.NET_LIST.stream().filter(n -> n.isUp())
.collect(Collectors.toList());
for (NativeNetworkInterfaceEO n : temp) {
if(natList.contains(n.getName())){
result += "网络接口:"+n.getName()+",运行状态由UP转为DOWN";
}
}
}
GlobalConfig.NET_LIST = list;
} catch (SocketException e) {
System.err.println("获取网络接口信息失败: " + e.getMessage());
}
return result;
}
private String handleExtraPorts(String threshold){
String result = "";
try {
List<Integer> list = scanPortsUsingNmap();
for (Integer port : list) {
boolean flag = verifyPort(port, threshold);
if(!flag){
result += "端口:"+port+"已开放;";
}
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private boolean compare(double value, String threshold, int compareType){
boolean isFalse = false;
switch(compareType) {
case 1: //大于且等于
if(value >= Double.parseDouble(threshold)){
isFalse = true;
}
break;
case 2: //小于
if(value < Double.parseDouble(threshold)){
isFalse = true;
}
break;
case 3: //小于且等于
if(value <= Double.parseDouble(threshold)){
isFalse = true;
}
break;
default: //大于
if(value > Double.parseDouble(threshold)){
isFalse = true;
}
break;
}
return isFalse;
}
private static double bytesToMbps(long bytes) {
return bytes * 8.0 / 1_000_000; // bytes to megabits
}
/**
* 获取接口的理论最大带宽(Mbps)
*/
private double getInterfaceMaxBandwidth(NetworkIF netIf) {
String name = netIf.getName().toLowerCase();
long speed = netIf.getSpeed(); // 获取接口速度(bps
if (speed > 0) {
return speed / 1_000_000.0; // 转换为Mbps
}
// 如果无法获取速度,根据常见接口类型估算
if (name.contains("eth") || name.contains("en") || name.contains("gigabit")) {
return 1000.0; // 千兆以太网
} else if (name.contains("10g") || name.contains("10000")) {
return 10000.0; // 万兆以太网
} else {
return 100.0; // 默认百兆以太网
}
}
/**
* 获取所有网络接口信息
*/
public List<NativeNetworkInterfaceEO> getAllNetworkInterfaces() throws SocketException {
List<NativeNetworkInterfaceEO> interfaces = new ArrayList<>();
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface ni = networkInterfaces.nextElement();
NativeNetworkInterfaceEO interfaceInfo = NativeNetworkInterfaceEO.builder()
.name(ni.getName())
.displayName(ni.getDisplayName())
.up(ni.isUp())
.build();
interfaces.add(interfaceInfo);
}
return interfaces;
}
/**
* 获取所有开放端口
*/
public List<Integer> scanPortsUsingNmap() throws Exception {
List<Integer> openPorts = new ArrayList<>();
Process process = Runtime.getRuntime().exec("nmap -p 1-65535 localhost");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
Pattern pattern = Pattern.compile("\\d+/tcp open"); // Adjust the regex based on nmap output format you expect
while ((line = reader.readLine()) != null) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) { // Assuming the output format is "port/protocol state" where state is "open" for open ports
String portStr = matcher.group(0).split("/")[0]; // Extract the port number part before "/tcp" or "/udp" etc.
openPorts.add(Integer.parseInt(portStr)); // Add the port number to the list of open ports
}
}
reader.close();
return openPorts;
}
public boolean verifyPort(int port, String threshold){
String[] ports = threshold.split(";");
for (int i = 0; i < ports.length; i++) {
String p = ports[i];
int start = 0;
int end = 0;
String[] arr = p.split("-");
start = Integer.parseInt(arr[0]);
if(arr.length == 2){
end = Integer.parseInt(arr[1]);
}
if(start <= port && port <= end){
return true;
}
}
return false;
}
}
@@ -1,9 +1,12 @@
package com.tongran.agent.client.utils;
import com.tongran.agent.client.core.eo.AlarmEO;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AgentDataUtil {
@@ -23,4 +26,9 @@ public class AgentDataUtil {
}
return memInfo;
}
public static boolean hasAnyActiveAlarm(List<AlarmEO> alarmEOList) {
return alarmEOList.stream()
.anyMatch(AlarmEO::isCollect);
}
}