优化告警日志、消息推送

This commit is contained in:
gaoyutao
2025-11-13 13:02:58 +08:00
parent 2910280746
commit 50d817091e
3 changed files with 135 additions and 64 deletions
@@ -53,6 +53,8 @@ public class MessageHandler {
// 心跳告警
private static final String HEARTBEAT_ALERT_PREFIX = "heartbeat:alert:";
String HEARTBEAT_RECOVERY_COUNT_PREFIX = "heartbeat:recovery:count:";
String HEARTBEAT_COUNT_PREFIX = "heartbeat:count:";
private static final long HEARTBEAT_TIMEOUT = 30000; // 3分钟超时
@@ -889,54 +891,120 @@ public class MessageHandler {
String clientId = message.getClientId();
String version = heartbeat.getVersion();
log.debug("处理心跳消息,客户端ID: {}, 时间: {}", clientId, heartbeat.getTimestamp());
// 添加逻辑节点标识
RmResourceRegistrationRemote updateData = new RmResourceRegistrationRemote();
updateData.setClientId(message.getClientId());
updateData.setLogicalNodeId(heartbeat.getLogicalNode());
updateData.setOnlineStatus("1");
updateData.setAgentVersion(version);
updateData.setOnboardTime(DateUtils.getNowDate());
remoteRevenueConfigService.innerUpdateRegist(updateData, SecurityConstants.INNER);
// agent更新结果存储
RmAgentManagement query = new RmAgentManagement();
query.setClientId(clientId);
List<RmAgentManagement> agentManagements = rmAgentManagementService.selectRmAgentManagementList(query);
if(!agentManagements.isEmpty()){
RmAgentManagement rmAgentManagement = agentManagements.get(0);
if(!StringUtils.equals(rmAgentManagement.getAgentVersion(), version)){
// 存储更新结果
RmAgentManagement updateResultData = new RmAgentManagement();
updateResultData.setId(rmAgentManagement.getId());
updateResultData.setAgentVersion(version);
updateResultData.setLastUpdateTime(DateUtils.getNowDate());
updateResultData.setLastUpdateResult("1");
rmAgentManagementService.updateRmAgentManagementByHardwareSn(updateResultData);
}
}
// 使用Redis存储状态
String statusKey = HEARTBEAT_STATUS_PREFIX + clientId;
String timeKey = HEARTBEAT_TIME_PREFIX + clientId;
String recoveryCountKey = HEARTBEAT_RECOVERY_COUNT_PREFIX + clientId;
String heartbeatCountKey = HEARTBEAT_COUNT_PREFIX + clientId; // 新增心跳次数统计key
try {
// 记录处理前状态(调试用)
String prevStatus = redisTemplate.opsForValue().get(statusKey);
String prevTime = redisTemplate.opsForValue().get(timeKey);
log.debug("客户端ID: {} 处理前状态 - status: {}, time: {}", clientId, prevStatus, prevTime);
String prevHeartbeatCount = redisTemplate.opsForValue().get(heartbeatCountKey);
log.debug("客户端ID: {} 处理前状态 - status: {}, time: {}, heartbeatCount: {}",
clientId, prevStatus, prevTime, prevHeartbeatCount);
// 使用事务确保原子性操作
redisTemplate.execute(new SessionCallback<Object>() {
List<Object> transactionResults = redisTemplate.execute(new SessionCallback<List<Object>>() {
@Override
public Object execute(RedisOperations operations) throws DataAccessException {
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.multi();
// 获取当前心跳次数
Object currentCountObj = operations.opsForValue().get(heartbeatCountKey);
int currentCount = 0;
if (currentCountObj != null) {
try {
currentCount = Integer.parseInt(currentCountObj.toString());
} catch (NumberFormatException e) {
currentCount = 0;
}
}
// 心跳次数+1
int newHeartbeatCount = currentCount + 1;
// 重置丢失计数为0,设置最后心跳时间
operations.opsForValue().set(statusKey, "0");
operations.opsForValue().set(timeKey, String.valueOf(System.currentTimeMillis()));
operations.opsForValue().set(heartbeatCountKey, String.valueOf(newHeartbeatCount));
return operations.exec();
}
});
log.debug("客户端ID: {} 心跳处理完成,重置状态和时间", clientId);
// 从事务结果中获取新的心跳次数
int newHeartbeatCount = 0;
if (transactionResults != null && !transactionResults.isEmpty()) {
// 获取set操作的结果,最后一个set的值就是新的心跳次数
try {
Object lastResult = transactionResults.get(transactionResults.size() - 1);
if (lastResult instanceof String) {
newHeartbeatCount = Integer.parseInt((String) lastResult);
}
} catch (Exception e) {
log.warn("获取事务结果失败,使用备用方式获取心跳次数", e);
// 备用方案:直接从Redis获取
String countStr = redisTemplate.opsForValue().get(heartbeatCountKey);
if (countStr != null) {
newHeartbeatCount = Integer.parseInt(countStr);
}
}
}
log.debug("客户端ID: {} 心跳处理完成,重置状态和时间,当前心跳次数: {}", clientId, newHeartbeatCount);
// 只有达到3次心跳才执行数据库操作
if (newHeartbeatCount >= 3) {
log.debug("客户端ID: {} 达到3次心跳,开始执行数据库操作", clientId);
// 添加逻辑节点标识
RmResourceRegistrationRemote updateData = new RmResourceRegistrationRemote();
updateData.setClientId(message.getClientId());
updateData.setLogicalNodeId(heartbeat.getLogicalNode());
updateData.setOnlineStatus("1");
updateData.setAgentVersion(version);
updateData.setOnboardTime(DateUtils.getNowDate());
remoteRevenueConfigService.innerUpdateRegist(updateData, SecurityConstants.INNER);
// agent更新结果存储
RmAgentManagement query = new RmAgentManagement();
query.setClientId(clientId);
List<RmAgentManagement> agentManagements = rmAgentManagementService.selectRmAgentManagementList(query);
if(!agentManagements.isEmpty()){
RmAgentManagement rmAgentManagement = agentManagements.get(0);
if(!StringUtils.equals(rmAgentManagement.getAgentVersion(), version)){
// 存储更新结果
RmAgentManagement updateResultData = new RmAgentManagement();
updateResultData.setId(rmAgentManagement.getId());
updateResultData.setAgentVersion(version);
updateResultData.setLastUpdateTime(DateUtils.getNowDate());
updateResultData.setLastUpdateResult("1");
rmAgentManagementService.updateRmAgentManagementByHardwareSn(updateResultData);
}
}
// 交换机在线状态改为在线
if(newHeartbeatCount == 3){
RmSwitchManagementRemote rmSwitchManagementRemote = new RmSwitchManagementRemote();
rmSwitchManagementRemote.setClientId(clientId);
R<List<RmSwitchManagementRemote>> rmSwitchManagementRemoteListR = remoteRevenueConfigService.getSwitchNameByClientId(rmSwitchManagementRemote, SecurityConstants.INNER);
if(rmSwitchManagementRemoteListR != null &&
rmSwitchManagementRemoteListR.getData()!=null &&
!rmSwitchManagementRemoteListR.getData().isEmpty()){
RmSwitchManagementRemote switchUpdate = new RmSwitchManagementRemote();
switchUpdate.setClientId(clientId);
switchUpdate.setOnlineStatus("1");
remoteRevenueConfigService.updateSwitchMsgByClientId(switchUpdate, SecurityConstants.INNER);
}
}
// 可选:达到3次后重置计数,或者继续累加
// redisTemplate.delete(heartbeatCountKey);
} else {
log.debug("客户端ID: {} 当前心跳次数: {},未达到3次,跳过数据库操作", clientId, newHeartbeatCount);
}
// 检查是否之前有告警状态
if (Boolean.TRUE.equals(redisTemplate.hasKey(HEARTBEAT_ALERT_PREFIX + clientId))) {
@@ -1108,32 +1176,34 @@ public class MessageHandler {
rmAlarmLog.setAlarmTime(DateUtils.getNowDate());
rmAlarmLog.setAlarmType("1");
// 查询此告警是否存在
RmAlarmLog query = new RmAlarmLog();
query.setClientId(clientId);
query.setAlarmType(AlarmTypeEnum.服务器下线.getCode());
List<RmAlarmLog> alarmLog = rmAlarmLogService.selectRmAlarmLogList(query);
if(alarmLog != null && !alarmLog.isEmpty()){
rmAlarmLogService.updateRmAlarmLog(rmAlarmLog);
}else{
rmAlarmLogService.insertRmAlarmLog(rmAlarmLog);
// 拿到消息模板
RmAlarmPushConfig rmAlarmPushConfig = new RmAlarmPushConfig();
rmAlarmPushConfig.setPushMethod(PushMethodEnum.企业微信.getCode());
rmAlarmPushConfig.setPushAlarmTypes(AlarmTypeEnum.服务器下线.getCode());
List<RmAlarmPushConfig> alarmConfigList = rmAlarmPushConfigService.selectRmAlarmPushConfigList(rmAlarmPushConfig);
if(alarmConfigList != null && !alarmConfigList.isEmpty()){
for (RmAlarmPushConfig alarmPushConfig : alarmConfigList) {
String contentTemplate = alarmPushConfig.getMessageContent();
String webhookUrl = alarmPushConfig.getPushAddress();
Map<String, Object> alarmMap = new HashMap<>();
alarmMap.put("告警时间", rmAlarmLog.getAlarmTime());
alarmMap.put("管理网-公网IP", rmAlarmLog.getMgmPublicIp());
alarmMap.put("告警类型", AlarmTypeEnum.服务器下线.getMsg());
alarmMap.put("告警设备", rmAlarmLog.getClientId());
alarmMap.put("告警内容", rmAlarmLog.getAlarmContent());
// 推送消息到企业微信
WeChatWorkBot.sendTemplateMessage(webhookUrl, contentTemplate, alarmMap);
}
// RmAlarmLog query = new RmAlarmLog();
// query.setClientId(clientId);
// query.setAlarmType(AlarmTypeEnum.服务器下线.getCode());
// List<RmAlarmLog> alarmLog = rmAlarmLogService.selectRmAlarmLogList(query);
// if(alarmLog != null && !alarmLog.isEmpty()){
// rmAlarmLogService.updateRmAlarmLog(rmAlarmLog);
// }
rmAlarmLogService.insertRmAlarmLog(rmAlarmLog);
// 拿到消息模板
RmAlarmPushConfig rmAlarmPushConfig = new RmAlarmPushConfig();
rmAlarmPushConfig.setPushMethod(PushMethodEnum.企业微信.getCode());
rmAlarmPushConfig.setPushAlarmTypes(AlarmTypeEnum.服务器下线.getCode());
List<RmAlarmPushConfig> alarmConfigList = rmAlarmPushConfigService.selectRmAlarmPushConfigList(rmAlarmPushConfig);
if(alarmConfigList != null && !alarmConfigList.isEmpty()){
for (RmAlarmPushConfig alarmPushConfig : alarmConfigList) {
String contentTemplate = alarmPushConfig.getMessageContent();
String webhookUrl = alarmPushConfig.getPushAddress();
String[] phones = alarmPushConfig.getContactPhones().split(",");
String content = rmAlarmLog.getAlarmContent();
Map<String, Object> alarmMap = new HashMap<>();
alarmMap.put("告警时间", rmAlarmLog.getAlarmTime());
alarmMap.put("管理网-公网IP", rmAlarmLog.getMgmPublicIp());
alarmMap.put("告警类型", AlarmTypeEnum.服务器下线.getMsg());
alarmMap.put("告警设备", rmAlarmLog.getClientId());
alarmMap.put("告警内容", content);
// 推送消息到企业微信
WeChatWorkBot.sendTemplateMessage(webhookUrl, contentTemplate, alarmMap, content, phones, false);
}
}