🔨 优化监控逻辑.

This commit is contained in:
lijiahangmax
2025-10-13 17:39:00 +08:00
parent ea98592012
commit 8929aa2f74
16 changed files with 429 additions and 314 deletions

View File

@@ -20,7 +20,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.visor.module.monitor.engine; package org.dromara.visor.module.monitor.context;
import cn.orionsec.kit.lang.define.cache.TimedCache; import cn.orionsec.kit.lang.define.cache.TimedCache;
import cn.orionsec.kit.lang.define.cache.TimedCacheBuilder; import cn.orionsec.kit.lang.define.cache.TimedCacheBuilder;
@@ -29,15 +29,11 @@ import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import org.dromara.visor.module.monitor.convert.MonitorHostConvert; import org.dromara.visor.module.monitor.convert.MonitorHostConvert;
import org.dromara.visor.module.monitor.convert.MonitorMetricsConvert;
import org.dromara.visor.module.monitor.dao.MonitorHostDAO; import org.dromara.visor.module.monitor.dao.MonitorHostDAO;
import org.dromara.visor.module.monitor.dao.MonitorMetricsDAO;
import org.dromara.visor.module.monitor.entity.domain.MonitorHostDO; import org.dromara.visor.module.monitor.entity.domain.MonitorHostDO;
import org.dromara.visor.module.monitor.entity.domain.MonitorMetricsDO;
import org.dromara.visor.module.monitor.entity.dto.AgentMetricsDataDTO; import org.dromara.visor.module.monitor.entity.dto.AgentMetricsDataDTO;
import org.dromara.visor.module.monitor.entity.dto.MonitorHostConfigDTO; import org.dromara.visor.module.monitor.entity.dto.MonitorHostConfigDTO;
import org.dromara.visor.module.monitor.entity.dto.MonitorHostContextDTO; import org.dromara.visor.module.monitor.entity.dto.MonitorHostContextDTO;
import org.dromara.visor.module.monitor.entity.dto.MonitorMetricsContextDTO;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
@@ -47,7 +43,7 @@ import java.util.List;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
* 监控上下文 * 监控探针上下文
* *
* @author Jiahang Li * @author Jiahang Li
* @version 1.0.0 * @version 1.0.0
@@ -55,23 +51,13 @@ import java.util.concurrent.ConcurrentHashMap;
*/ */
@Slf4j @Slf4j
@Component @Component
public class MonitorContext { public class MonitorAgentContext {
/** /**
* 监控主机缓存 * 监控主机缓存
*/ */
private static final ConcurrentHashMap<String, MonitorHostContextDTO> MONITOR_HOST_CACHE = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<String, MonitorHostContextDTO> MONITOR_HOST_CACHE = new ConcurrentHashMap<>();
/**
* 监控指标缓存
*/
private static final ConcurrentHashMap<Long, MonitorMetricsContextDTO> MONITOR_METRICS_CACHE = new ConcurrentHashMap<>();
/**
* 监控指标引用缓存
*/
private static final ConcurrentHashMap<String, Long> MONITOR_METRICS_KEY_REL = new ConcurrentHashMap<>();
/** /**
* 最后心跳时间缓存 3min * 最后心跳时间缓存 3min
*/ */
@@ -88,9 +74,6 @@ public class MonitorContext {
.checkInterval(Const.MS_S_60) .checkInterval(Const.MS_S_60)
.build(); .build();
@Resource
private MonitorMetricsDAO monitorMetricsDAO;
@Resource @Resource
private MonitorHostDAO monitorHostDAO; private MonitorHostDAO monitorHostDAO;
@@ -103,10 +86,6 @@ public class MonitorContext {
log.info("MonitorContext-init hosts start."); log.info("MonitorContext-init hosts start.");
this.loadMonitorHost(); this.loadMonitorHost();
log.info("MonitorContext-init hosts end."); log.info("MonitorContext-init hosts end.");
// 初始化监控指标
log.info("MonitorContext-init metrics start.");
this.loadMonitorMetrics();
log.info("MonitorContext-init metrics end.");
} }
@PreDestroy @PreDestroy
@@ -128,17 +107,6 @@ public class MonitorContext {
} }
} }
/**
* 加载监控指标
*/
public void loadMonitorMetrics() {
MONITOR_METRICS_CACHE.clear();
// 查询全部指标
List<MonitorMetricsDO> metrics = monitorMetricsDAO.selectList(null);
metrics.forEach(s -> MONITOR_METRICS_CACHE.put(s.getId(), MonitorMetricsConvert.MAPPER.toContext(s)));
metrics.forEach(s -> MONITOR_METRICS_KEY_REL.put(this.getMonitorMetricsKey(s.getMeasurement(), s.getValue()), s.getId()));
}
// ----------------------- 监控主机 ---------------------- // ----------------------- 监控主机 ----------------------
/** /**
@@ -237,72 +205,4 @@ public class MonitorContext {
return AGENT_LAST_ACTIVE_TIME.get(agentKey) != null; return AGENT_LAST_ACTIVE_TIME.get(agentKey) != null;
} }
// ----------------------- 监控指标 ----------------------
/**
* 重新加载监控指标
*
* @param id id
*/
public void reloadMonitorMetrics(Long id) {
// 删除指标缓存
MONITOR_METRICS_CACHE.remove(id);
// 删除指标引用
MONITOR_METRICS_KEY_REL.entrySet().removeIf(entry -> entry.getValue().equals(id));
// 重新加载指标
MonitorMetricsDO metrics = monitorMetricsDAO.selectById(id);
if (metrics == null) {
return;
}
MONITOR_METRICS_CACHE.put(metrics.getId(), MonitorMetricsConvert.MAPPER.toContext(metrics));
MONITOR_METRICS_KEY_REL.put(this.getMonitorMetricsKey(metrics.getMeasurement(), metrics.getValue()), metrics.getId());
}
/**
* 获取监控指标
*
* @param id id
* @return cache
*/
public MonitorMetricsContextDTO getMonitorMetrics(Long id) {
return MONITOR_METRICS_CACHE.get(id);
}
/**
* 获取监控指标
*
* @param measurement measurement
* @param field field
* @return cache
*/
public MonitorMetricsContextDTO getMonitorMetrics(String measurement, String field) {
Long id = MONITOR_METRICS_KEY_REL.get(this.getMonitorMetricsKey(measurement, field));
if (id == null) {
return null;
}
return MONITOR_METRICS_CACHE.get(id);
}
/**
* 获取监控指标 id
*
* @param measurement measurement
* @param field field
* @return id
*/
public Long getMonitorMetricsId(String measurement, String field) {
return MONITOR_METRICS_KEY_REL.get(this.getMonitorMetricsKey(measurement, field));
}
/**
* 获取监控指标 key
*
* @param measurement measurement
* @param field field
* @return key
*/
private String getMonitorMetricsKey(String measurement, String field) {
return measurement + "_" + field;
}
} }

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2023 - present Dromara, All rights reserved.
*
* https://visor.dromara.org
* https://visor.dromara.org.cn
* https://visor.orionsec.cn
*
* Members:
* Jiahang Li - ljh1553488six@139.com - author
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.visor.module.monitor.context;
import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.module.monitor.convert.MonitorMetricsConvert;
import org.dromara.visor.module.monitor.dao.MonitorMetricsDAO;
import org.dromara.visor.module.monitor.entity.domain.MonitorMetricsDO;
import org.dromara.visor.module.monitor.entity.dto.MonitorMetricsContextDTO;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
* 监控指标上下文
*
* @author Jiahang Li
* @version 1.0.0
* @since 2025/10/12 19:39
*/
@Slf4j
@Component
public class MonitorMetricsContext {
/**
* 监控指标缓存
*/
private static final ConcurrentHashMap<Long, MonitorMetricsContextDTO> MONITOR_METRICS_CACHE = new ConcurrentHashMap<>();
/**
* 监控指标引用缓存
*/
private static final ConcurrentHashMap<String, Long> MONITOR_METRICS_KEY_REL = new ConcurrentHashMap<>();
@Resource
private MonitorMetricsDAO monitorMetricsDAO;
/**
* 初始化监控上下文
*/
@PostConstruct
public void initMonitorContext() {
// 初始化监控指标
log.info("MetricsContext-init start.");
this.loadMonitorMetrics();
log.info("MetricsContext-init end.");
}
/**
* 加载监控指标
*/
public void loadMonitorMetrics() {
MONITOR_METRICS_CACHE.clear();
// 查询全部指标
List<MonitorMetricsDO> metrics = monitorMetricsDAO.selectList(null);
metrics.forEach(s -> MONITOR_METRICS_CACHE.put(s.getId(), MonitorMetricsConvert.MAPPER.toContext(s)));
metrics.forEach(s -> MONITOR_METRICS_KEY_REL.put(this.getMonitorMetricsKey(s.getMeasurement(), s.getValue()), s.getId()));
}
// ----------------------- 监控指标 ----------------------
/**
* 重新加载监控指标
*
* @param id id
*/
public void reloadMonitorMetrics(Long id) {
// 删除指标缓存
MONITOR_METRICS_CACHE.remove(id);
// 删除指标引用
MONITOR_METRICS_KEY_REL.entrySet().removeIf(entry -> entry.getValue().equals(id));
// 重新加载指标
MonitorMetricsDO metrics = monitorMetricsDAO.selectById(id);
if (metrics == null) {
return;
}
MONITOR_METRICS_CACHE.put(metrics.getId(), MonitorMetricsConvert.MAPPER.toContext(metrics));
MONITOR_METRICS_KEY_REL.put(this.getMonitorMetricsKey(metrics.getMeasurement(), metrics.getValue()), metrics.getId());
}
/**
* 获取监控指标
*
* @param id id
* @return cache
*/
public MonitorMetricsContextDTO getMonitorMetrics(Long id) {
return MONITOR_METRICS_CACHE.get(id);
}
/**
* 获取监控指标
*
* @param measurement measurement
* @param field field
* @return cache
*/
public MonitorMetricsContextDTO getMonitorMetrics(String measurement, String field) {
Long id = MONITOR_METRICS_KEY_REL.get(this.getMonitorMetricsKey(measurement, field));
if (id == null) {
return null;
}
return MONITOR_METRICS_CACHE.get(id);
}
/**
* 获取监控指标 id
*
* @param measurement measurement
* @param field field
* @return id
*/
public Long getMonitorMetricsId(String measurement, String field) {
return MONITOR_METRICS_KEY_REL.get(this.getMonitorMetricsKey(measurement, field));
}
/**
* 获取监控指标 key
*
* @param measurement measurement
* @param field field
* @return key
*/
private String getMonitorMetricsKey(String measurement, String field) {
return measurement + "_" + field;
}
}

View File

@@ -35,8 +35,8 @@ import org.dromara.visor.framework.log.core.annotation.IgnoreLog;
import org.dromara.visor.framework.log.core.enums.IgnoreLogMode; import org.dromara.visor.framework.log.core.enums.IgnoreLogMode;
import org.dromara.visor.framework.web.core.annotation.DemoDisableApi; import org.dromara.visor.framework.web.core.annotation.DemoDisableApi;
import org.dromara.visor.framework.web.core.annotation.RestWrapper; import org.dromara.visor.framework.web.core.annotation.RestWrapper;
import org.dromara.visor.module.monitor.context.MonitorAgentContext;
import org.dromara.visor.module.monitor.define.operator.MonitorHostOperatorType; import org.dromara.visor.module.monitor.define.operator.MonitorHostOperatorType;
import org.dromara.visor.module.monitor.engine.MonitorContext;
import org.dromara.visor.module.monitor.entity.dto.AgentMetricsDataDTO; import org.dromara.visor.module.monitor.entity.dto.AgentMetricsDataDTO;
import org.dromara.visor.module.monitor.entity.request.host.*; import org.dromara.visor.module.monitor.entity.request.host.*;
import org.dromara.visor.module.monitor.entity.vo.MonitorHostMetricsDataVO; import org.dromara.visor.module.monitor.entity.vo.MonitorHostMetricsDataVO;
@@ -68,7 +68,7 @@ public class MonitorHostController {
private MonitorHostService monitorHostService; private MonitorHostService monitorHostService;
@Resource @Resource
private MonitorContext monitorContext; private MonitorAgentContext monitorAgentContext;
@IgnoreLog(IgnoreLogMode.RET) @IgnoreLog(IgnoreLogMode.RET)
@PostMapping("/query") @PostMapping("/query")
@@ -84,7 +84,7 @@ public class MonitorHostController {
@Parameter(name = "agentKey", description = "agentKey", required = true) @Parameter(name = "agentKey", description = "agentKey", required = true)
@PreAuthorize("@ss.hasPermission('monitor:monitor-host:query')") @PreAuthorize("@ss.hasPermission('monitor:monitor-host:query')")
public AgentMetricsDataDTO getMonitorHostOverride(@RequestParam("agentKey") String agentKey) { public AgentMetricsDataDTO getMonitorHostOverride(@RequestParam("agentKey") String agentKey) {
return monitorContext.getAgentMetrics(agentKey); return monitorAgentContext.getAgentMetrics(agentKey);
} }
@IgnoreLog(IgnoreLogMode.RET) @IgnoreLog(IgnoreLogMode.RET)

View File

@@ -22,11 +22,11 @@
*/ */
package org.dromara.visor.module.monitor.convert; package org.dromara.visor.module.monitor.convert;
import org.dromara.visor.module.monitor.engine.AlarmEngineRule;
import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyRuleDO; import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyRuleDO;
import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyRuleCreateRequest; import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyRuleCreateRequest;
import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyRuleUpdateRequest; import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyRuleUpdateRequest;
import org.dromara.visor.module.monitor.entity.vo.AlarmPolicyRuleVO; import org.dromara.visor.module.monitor.entity.vo.AlarmPolicyRuleVO;
import org.dromara.visor.module.monitor.handler.alarm.model.AlarmEngineRule;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping; import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;

View File

@@ -20,7 +20,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.visor.module.monitor.engine; package org.dromara.visor.module.monitor.handler.alarm;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
@@ -37,6 +37,8 @@ import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyDO;
import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyNotifyDO; import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyNotifyDO;
import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyRuleDO; import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyRuleDO;
import org.dromara.visor.module.monitor.enums.AlarmSwitchEnum; import org.dromara.visor.module.monitor.enums.AlarmSwitchEnum;
import org.dromara.visor.module.monitor.handler.alarm.model.AlarmEnginePolicy;
import org.dromara.visor.module.monitor.handler.alarm.model.AlarmEngineRule;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;

View File

@@ -20,7 +20,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.visor.module.monitor.engine; package org.dromara.visor.module.monitor.handler.alarm;
import cn.orionsec.kit.lang.define.cache.TimedCache; import cn.orionsec.kit.lang.define.cache.TimedCache;
import cn.orionsec.kit.lang.define.cache.TimedCacheBuilder; import cn.orionsec.kit.lang.define.cache.TimedCacheBuilder;
@@ -32,23 +32,23 @@ import cn.orionsec.kit.lang.utils.collect.Lists;
import cn.orionsec.kit.lang.utils.collect.Maps; import cn.orionsec.kit.lang.utils.collect.Maps;
import cn.orionsec.kit.lang.utils.io.Streams; import cn.orionsec.kit.lang.utils.io.Streams;
import cn.orionsec.kit.lang.utils.time.Dates; import cn.orionsec.kit.lang.utils.time.Dates;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import org.dromara.visor.common.entity.PushUser; import org.dromara.visor.common.entity.PushUser;
import org.dromara.visor.common.enums.BooleanBit; import org.dromara.visor.common.enums.BooleanBit;
import org.dromara.visor.framework.biz.push.core.utils.PushUtils; import org.dromara.visor.framework.biz.push.core.utils.PushUtils;
import org.dromara.visor.framework.redis.core.utils.RedisStrings; import org.dromara.visor.framework.redis.core.utils.RedisStrings;
import org.dromara.visor.module.asset.api.HostAgentApi;
import org.dromara.visor.module.asset.entity.dto.host.HostBaseDTO;
import org.dromara.visor.module.infra.api.SystemUserApi; import org.dromara.visor.module.infra.api.SystemUserApi;
import org.dromara.visor.module.monitor.convert.AlarmEventConvert; import org.dromara.visor.module.monitor.context.MonitorAgentContext;
import org.dromara.visor.module.monitor.context.MonitorMetricsContext;
import org.dromara.visor.module.monitor.define.cache.AlarmPolicyCacheKeyDefine; import org.dromara.visor.module.monitor.define.cache.AlarmPolicyCacheKeyDefine;
import org.dromara.visor.module.monitor.entity.domain.AlarmEventDO;
import org.dromara.visor.module.monitor.entity.dto.*; import org.dromara.visor.module.monitor.entity.dto.*;
import org.dromara.visor.module.monitor.enums.*; import org.dromara.visor.module.monitor.enums.AlarmLevelEnum;
import org.dromara.visor.module.monitor.enums.AlarmTriggerConditionEnum;
import org.dromara.visor.module.monitor.enums.MetricsUnitEnum;
import org.dromara.visor.module.monitor.handler.alarm.model.AlarmEnginePolicy;
import org.dromara.visor.module.monitor.handler.alarm.model.AlarmEngineRule;
import org.dromara.visor.module.monitor.service.AlarmEventService; import org.dromara.visor.module.monitor.service.AlarmEventService;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import javax.annotation.Resource; import javax.annotation.Resource;
@@ -57,62 +57,50 @@ import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* 告警引擎 * 告警引擎基类
* *
* @author Jiahang Li * @author Jiahang Li
* @version 1.0.0 * @version 1.0.0
* @since 2025/8/21 17:26 * @since 2025/10/13 10:12
*/ */
@Slf4j @Slf4j
@Component public abstract class BaseAlarmEngine implements IAlarmEngine {
public class AlarmEngine {
/** /**
* 告警触发状态缓存 10min * 告警触发状态缓存 10min
*/ */
private static final TimedCache<AlarmTriggerStateDTO> TRIGGER_STATE_CACHE = TimedCacheBuilder.<AlarmTriggerStateDTO>create() protected static final TimedCache<AlarmTriggerStateDTO> TRIGGER_STATE_CACHE = TimedCacheBuilder.<AlarmTriggerStateDTO>create()
.expireAfter(10 * Const.MS_S_60) .expireAfter(10 * Const.MS_S_60)
.checkInterval(Const.MS_S_60) .checkInterval(Const.MS_S_60)
.build(); .build();
@Resource @Resource
private AlarmEngineContext alarmEngineContext; protected AlarmEngineContext alarmEngineContext;
@Resource @Resource
private MonitorContext monitorContext; protected MonitorAgentContext monitorAgentContext;
@Resource @Resource
private AlarmEventService alarmEventService; protected MonitorMetricsContext monitorMetricsContext;
@Resource @Resource
private HostAgentApi hostAgentApi; protected AlarmEventService alarmEventService;
@Resource @Resource
private SystemUserApi systemUserApi; protected SystemUserApi systemUserApi;
@PreDestroy @PreDestroy
public void destroyTimedCache() { public void destroyTimedCache() {
Streams.close(TRIGGER_STATE_CACHE); Streams.close(TRIGGER_STATE_CACHE);
} }
/** @Override
* 检查并且告警
*
* @param agentKey agentKey
* @param prevMetrics prevMetrics
* @param newMetrics newMetrics
*/
public void checkAndAlarm(String agentKey, public void checkAndAlarm(String agentKey,
AgentMetricsDataDTO prevMetrics, AgentMetricsDataDTO prevMetrics,
AgentMetricsDataDTO newMetrics) { AgentMetricsDataDTO newMetrics) {
// 获取主机信息 // 获取告警策略
MonitorHostContextDTO monitorHost = monitorContext.getMonitorHost(agentKey); Long policyId = this.getAlarmPolicyId(agentKey);
if (monitorHost == null) { if (policyId == null) {
return;
}
// 检查策略是否开启
Long policyId = monitorHost.getPolicyId();
if (policyId == null || AlarmSwitchEnum.isOff(monitorHost.getAlarmSwitch())) {
return; return;
} }
// 获取对应的策略 // 获取对应的策略
@@ -132,7 +120,7 @@ public class AlarmEngine {
// 检查指标 // 检查指标
AlarmEventTriggerDTO event = this.checkAndAlarm(agentKey, AlarmEventTriggerDTO event = this.checkAndAlarm(agentKey,
prevMetrics, newMetrics, agentMetrics, metricsField, prevMetrics, newMetrics, agentMetrics, metricsField,
policy, monitorHost); policy);
if (event != null) { if (event != null) {
alarmEvents.add(event); alarmEvents.add(event);
} }
@@ -147,6 +135,14 @@ public class AlarmEngine {
} }
} }
/**
* 获取告警策略 id
*
* @param agentKey agentKey
* @return policyId
*/
protected abstract Long getAlarmPolicyId(String agentKey);
/** /**
* 检查并且告警 * 检查并且告警
* *
@@ -156,25 +152,22 @@ public class AlarmEngine {
* @param agentMetrics agentMetrics * @param agentMetrics agentMetrics
* @param metricsField metricsField * @param metricsField metricsField
* @param policy policy * @param policy policy
* @param monitorHost monitorHost
* @return event * @return event
*/ */
private AlarmEventTriggerDTO checkAndAlarm(String agentKey, protected AlarmEventTriggerDTO checkAndAlarm(String agentKey,
AgentMetricsDataDTO prevMetrics, AgentMetricsDataDTO prevMetrics,
AgentMetricsDataDTO newMetrics, AgentMetricsDataDTO newMetrics,
AgentMetricsDTO agentMetrics, AgentMetricsDTO agentMetrics,
String metricsField, String metricsField,
AlarmEnginePolicy policy, AlarmEnginePolicy policy) {
MonitorHostContextDTO monitorHost) { Long alarmTimestamp = newMetrics.getTimestamp();
Long timestamp = newMetrics.getTimestamp();
// 指标id // 指标id
Long metricsId = monitorContext.getMonitorMetricsId(agentMetrics.getType(), metricsField); Long metricsId = monitorMetricsContext.getMonitorMetricsId(agentMetrics.getType(), metricsField);
if (metricsId == null) { if (metricsId == null) {
return null; return null;
} }
// 指标值 // 指标值
BigDecimal metricsValue; BigDecimal metricsValue = agentMetrics.getValues().getBigDecimal(metricsField);
metricsValue = agentMetrics.getValues().getBigDecimal(metricsField);
if (metricsValue == null) { if (metricsValue == null) {
return null; return null;
} }
@@ -200,14 +193,30 @@ public class AlarmEngine {
return null; return null;
} }
// 检查是否在静默期 // 检查是否在静默期
boolean inSilence = this.checkAndSetInSilencePeriod(agentKey, timestamp, matchedRule); boolean inSilence = this.checkAndSetInSilencePeriod(agentKey, alarmTimestamp, matchedRule);
if (inSilence) { if (inSilence) {
return null; return null;
} }
// 创建告警事件 // 创建告警事件
return this.createAlarmEvent(agentKey, monitorHost, timestamp, agentMetrics, metricsValue, matchedRule); return this.createAlarmEvent(agentKey, alarmTimestamp, agentMetrics, metricsValue, matchedRule);
} }
/**
* 创建告警事件
*
* @param agentKey agentKey
* @param alarmTimestamp alarmTimestamp
* @param agentMetrics agentMetrics
* @param metricsValue metricsValue
* @param rule rule
* @return event
*/
protected abstract AlarmEventTriggerDTO createAlarmEvent(String agentKey,
Long alarmTimestamp,
AgentMetricsDTO agentMetrics,
BigDecimal metricsValue,
AlarmEngineRule rule);
/** /**
* 获取到第一个匹配到达阈值的规则 包含 tag * 获取到第一个匹配到达阈值的规则 包含 tag
* *
@@ -216,9 +225,9 @@ public class AlarmEngine {
* @param metricsValue metricsValue * @param metricsValue metricsValue
* @return rule * @return rule
*/ */
private AlarmEngineRule matchTaggedAgentMetricsRule(List<AlarmEngineRule> rules, protected AlarmEngineRule matchTaggedAgentMetricsRule(List<AlarmEngineRule> rules,
Map<String, String> metricsTags, Map<String, String> metricsTags,
BigDecimal metricsValue) { BigDecimal metricsValue) {
AlarmEngineRule matchedRule = null; AlarmEngineRule matchedRule = null;
// context 根据 level 排序了 // context 根据 level 排序了
for (AlarmEngineRule rule : rules) { for (AlarmEngineRule rule : rules) {
@@ -265,7 +274,7 @@ public class AlarmEngine {
* @param metricsValue metricsValue * @param metricsValue metricsValue
* @return rule * @return rule
*/ */
private AlarmEngineRule matchAgentMetricsRule(List<AlarmEngineRule> rules, BigDecimal metricsValue) { protected AlarmEngineRule matchAgentMetricsRule(List<AlarmEngineRule> rules, BigDecimal metricsValue) {
AlarmEngineRule matchedRule = null; AlarmEngineRule matchedRule = null;
// context 根据 level 排序了 // context 根据 level 排序了
for (AlarmEngineRule rule : rules) { for (AlarmEngineRule rule : rules) {
@@ -289,13 +298,13 @@ public class AlarmEngine {
* @param rule rule * @param rule rule
* @param metricValue metricValue * @param metricValue metricValue
*/ */
private boolean checkAlarmCondition(AlarmEngineRule rule, BigDecimal metricValue) { protected boolean checkAlarmCondition(AlarmEngineRule rule, BigDecimal metricValue) {
// 获取指标值 // 获取指标值
if (metricValue == null) { if (metricValue == null) {
return false; return false;
} }
// 获取指标单位 // 获取指标单位
MonitorMetricsContextDTO metrics = monitorContext.getMonitorMetrics(rule.getMetricsId()); MonitorMetricsContextDTO metrics = monitorMetricsContext.getMonitorMetrics(rule.getMetricsId());
MetricsUnitEnum unit = Optional.ofNullable(metrics) MetricsUnitEnum unit = Optional.ofNullable(metrics)
.map(MonitorMetricsContextDTO::getUnit) .map(MonitorMetricsContextDTO::getUnit)
.map(MetricsUnitEnum::of) .map(MetricsUnitEnum::of)
@@ -310,13 +319,8 @@ public class AlarmEngine {
} }
// 将阈值转换为原始值 // 将阈值转换为原始值
threshold = unit.getThresholdOriginalValue(threshold); threshold = unit.getThresholdOriginalValue(threshold);
// 触发条件
AlarmTriggerConditionEnum condition = AlarmTriggerConditionEnum.of(rule.getTriggerCondition());
if (condition == null) {
return false;
}
// 判断是否达到触发条件 // 判断是否达到触发条件
return this.evaluateCondition(condition, metricValue, threshold); return this.evaluateCondition(rule.getTriggerCondition(), metricValue, threshold);
} }
/** /**
@@ -327,10 +331,12 @@ public class AlarmEngine {
* @param threshold threshold * @param threshold threshold
* @return eval * @return eval
*/ */
private boolean evaluateCondition(AlarmTriggerConditionEnum condition, protected boolean evaluateCondition(String condition,
BigDecimal metricValue, BigDecimal metricValue,
BigDecimal threshold) { BigDecimal threshold) {
switch (condition) { // 触发条件
AlarmTriggerConditionEnum triggerCondition = AlarmTriggerConditionEnum.of(condition);
switch (triggerCondition) {
case GT: case GT:
return metricValue.compareTo(threshold) > 0; return metricValue.compareTo(threshold) > 0;
case GE: case GE:
@@ -356,10 +362,10 @@ public class AlarmEngine {
* @param rule rule * @param rule rule
* @return result * @return result
*/ */
private boolean checkConsecutiveCount(String agentKey, protected boolean checkConsecutiveCount(String agentKey,
AgentMetricsDataDTO prevMetrics, AgentMetricsDataDTO prevMetrics,
AgentMetricsDataDTO newMetrics, AgentMetricsDataDTO newMetrics,
AlarmEngineRule rule) { AlarmEngineRule rule) {
// 获取规则连续触发次数 // 获取规则连续触发次数
Integer ruleConsecutiveCount = Objects1.def(rule.getConsecutiveCount(), 1); Integer ruleConsecutiveCount = Objects1.def(rule.getConsecutiveCount(), 1);
// 获取指标连续触发次数 // 获取指标连续触发次数
@@ -393,8 +399,8 @@ public class AlarmEngine {
* @param prevMetrics prevMetrics * @param prevMetrics prevMetrics
* @return isConsecutiveTrigger * @return isConsecutiveTrigger
*/ */
private boolean isConsecutiveTrigger(AlarmTriggerStateDTO triggerState, protected boolean isConsecutiveTrigger(AlarmTriggerStateDTO triggerState,
AgentMetricsDataDTO prevMetrics) { AgentMetricsDataDTO prevMetrics) {
if (prevMetrics == null || triggerState == null) { if (prevMetrics == null || triggerState == null) {
return false; return false;
} }
@@ -404,14 +410,14 @@ public class AlarmEngine {
/** /**
* 检查并且设置静默期 * 检查并且设置静默期
* *
* @param agentKey agentKey * @param agentKey agentKey
* @param timestamp timestamp * @param alarmTimestamp alarmTimestamp
* @param rule rule * @param rule rule
* @return inSilence * @return inSilence
*/ */
private boolean checkAndSetInSilencePeriod(String agentKey, protected boolean checkAndSetInSilencePeriod(String agentKey,
Long timestamp, Long alarmTimestamp,
AlarmEngineRule rule) { AlarmEngineRule rule) {
Integer silencePeriod = Objects1.def(rule.getSilencePeriod(), 0); Integer silencePeriod = Objects1.def(rule.getSilencePeriod(), 0);
// 无静默期则触发 // 无静默期则触发
if (silencePeriod <= 0) { if (silencePeriod <= 0) {
@@ -427,75 +433,11 @@ public class AlarmEngine {
.noPrefix() .noPrefix()
.timeout(silencePeriod, TimeUnit.MINUTES) .timeout(silencePeriod, TimeUnit.MINUTES)
.build(); .build();
RedisStrings.set(key, timestamp); RedisStrings.set(key, alarmTimestamp);
} }
return inSilence; return inSilence;
} }
/**
* 创建告警事件
*
* @param agentKey agentKey
* @param monitorHost monitorHost
* @param timestamp timestamp
* @param agentMetrics agentMetrics
* @param metricsValue metricsValue
* @param rule rule
* @return event
*/
private AlarmEventTriggerDTO createAlarmEvent(String agentKey,
MonitorHostContextDTO monitorHost,
Long timestamp,
AgentMetricsDTO agentMetrics,
BigDecimal metricsValue,
AlarmEngineRule rule) {
// 查询主机信息
HostBaseDTO host = hostAgentApi.getHostCacheByAgentKey(agentKey);
if (host == null) {
host = new HostBaseDTO();
}
// 获取指标
MonitorMetricsContextDTO metrics = monitorContext.getMonitorMetrics(rule.getMetricsId());
// 指标单位
MetricsUnitEnum unit = MetricsUnitEnum.of(metrics.getUnit());
// 获取连续触发次数
Integer consecutiveCount = Optional.ofNullable(TRIGGER_STATE_CACHE.get(this.getTriggerStateCacheKey(agentKey, rule)))
.map(AlarmTriggerStateDTO::getConsecutiveCount)
.orElse(1);
// 构建告警信息
String alarmInfo = this.buildAlarmInfo(metrics, rule, unit, metricsValue, consecutiveCount);
// 创建告警事件记录
Map<String, String> tags = agentMetrics.getTags();
AlarmEventDO alarmEvent = AlarmEventDO.builder()
.agentKey(agentKey)
.hostId(host.getId())
.hostName(host.getName())
.hostAddress(host.getAddress())
.policyId(rule.getPolicyId())
.policyRuleId(rule.getId())
.metricsId(rule.getMetricsId())
.metricsMeasurement(metrics.getMeasurement())
.alarmTags(tags == null ? Const.EMPTY_OBJECT : JSON.toJSONString(tags))
.alarmValue(metricsValue)
.alarmThreshold(unit.getThresholdOriginalValue(rule.getThreshold()))
.alarmInfo(alarmInfo)
.alarmLevel(rule.getLevel())
.triggerCondition(rule.getTriggerCondition())
.consecutiveCount(consecutiveCount)
.falseAlarm(BooleanBit.FALSE.getValue())
.handleStatus(AlarmHandleStatusEnum.NEW.name())
.handleUserId(monitorHost.getOwnerUserId())
.handleUsername(monitorHost.getOwnerUsername())
.createTime(new Date(timestamp))
.updateTime(new Date(timestamp))
.build();
// 保存告警事件
alarmEventService.createAlarmEvent(alarmEvent);
// 填充其他参数
return AlarmEventConvert.MAPPER.toTrigger(alarmEvent);
}
/** /**
* 构建告警信息 * 构建告警信息
* *
@@ -506,11 +448,11 @@ public class AlarmEngine {
* @param consecutiveCount consecutiveCount * @param consecutiveCount consecutiveCount
* @return alarmInfo * @return alarmInfo
*/ */
private String buildAlarmInfo(MonitorMetricsContextDTO metrics, protected String buildAlarmInfo(MonitorMetricsContextDTO metrics,
AlarmEngineRule rule, AlarmEngineRule rule,
MetricsUnitEnum unit, MetricsUnitEnum unit,
BigDecimal metricsValue, BigDecimal metricsValue,
Integer consecutiveCount) { Integer consecutiveCount) {
return metrics.getName() return metrics.getName()
+ Const.SPACE + AlarmTriggerConditionEnum.of(rule.getTriggerCondition()).getCondition() + Const.SPACE + AlarmTriggerConditionEnum.of(rule.getTriggerCondition()).getCondition()
+ Const.SPACE + unit.format(rule.getThreshold(), new MetricsUnitEnum.FormatOptions(2, metrics.getSuffix())) + Const.SPACE + unit.format(rule.getThreshold(), new MetricsUnitEnum.FormatOptions(2, metrics.getSuffix()))
@@ -525,7 +467,7 @@ public class AlarmEngine {
* @param rule rule * @param rule rule
* @return cacheKey * @return cacheKey
*/ */
private String getTriggerStateCacheKey(String agentKey, AlarmEngineRule rule) { protected String getTriggerStateCacheKey(String agentKey, AlarmEngineRule rule) {
return agentKey + ":" + rule.getId(); return agentKey + ":" + rule.getId();
} }
@@ -535,7 +477,7 @@ public class AlarmEngine {
* @param policy policy * @param policy policy
* @param alarmEvents alarmEvents * @param alarmEvents alarmEvents
*/ */
private void notifyAlarmPolicyChannels(AlarmEnginePolicy policy, List<AlarmEventTriggerDTO> alarmEvents) { protected void notifyAlarmPolicyChannels(AlarmEnginePolicy policy, List<AlarmEventTriggerDTO> alarmEvents) {
List<Long> notifyIdList = policy.getNotifyIdList(); List<Long> notifyIdList = policy.getNotifyIdList();
if (Lists.isEmpty(notifyIdList)) { if (Lists.isEmpty(notifyIdList)) {
return; return;
@@ -549,7 +491,7 @@ public class AlarmEngine {
// 构建参数 // 构建参数
List<Map<String, Object>> paramsList = new ArrayList<>(); List<Map<String, Object>> paramsList = new ArrayList<>();
for (AlarmEventTriggerDTO event : alarmEvents) { for (AlarmEventTriggerDTO event : alarmEvents) {
MonitorMetricsContextDTO metrics = monitorContext.getMonitorMetrics(event.getMetricsId()); MonitorMetricsContextDTO metrics = monitorMetricsContext.getMonitorMetrics(event.getMetricsId());
MetricsUnitEnum unit = MetricsUnitEnum.of(metrics.getUnit()); MetricsUnitEnum unit = MetricsUnitEnum.of(metrics.getUnit());
AlarmLevelEnum level = AlarmLevelEnum.of(event.getAlarmLevel()); AlarmLevelEnum level = AlarmLevelEnum.of(event.getAlarmLevel());
AlarmTriggerConditionEnum triggerCondition = AlarmTriggerConditionEnum.of(event.getTriggerCondition()); AlarmTriggerConditionEnum triggerCondition = AlarmTriggerConditionEnum.of(event.getTriggerCondition());

View File

@@ -20,40 +20,28 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.visor.module.monitor.engine; package org.dromara.visor.module.monitor.handler.alarm;
import lombok.AllArgsConstructor; import org.dromara.visor.module.monitor.entity.dto.AgentMetricsDataDTO;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* 告警触发状态 - 轻量级缓存对象 * 告警引擎
* 用于减少内存占用只保存必要的触发状态信息
* *
* @author Jiahang Li * @author Jiahang Li
* @version 1.0.0 * @version 1.0.0
* @since 2024/6/3 18:00 * @since 2025/10/13 10:22
*/ */
@Data public interface IAlarmEngine {
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AlarmTriggerState {
/** /**
* 时间戳 * 检查并且告警
*
* @param agentKey agentKey
* @param prevMetrics prevMetrics
* @param newMetrics newMetrics
*/ */
private Long timestamp; void checkAndAlarm(String agentKey,
AgentMetricsDataDTO prevMetrics,
/** AgentMetricsDataDTO newMetrics);
* 是否触发告警
*/
private Boolean triggered;
/**
* 规则键
*/
private String ruleKey;
} }

View File

@@ -0,0 +1,129 @@
/*
* Copyright (c) 2023 - present Dromara, All rights reserved.
*
* https://visor.dromara.org
* https://visor.dromara.org.cn
* https://visor.orionsec.cn
*
* Members:
* Jiahang Li - ljh1553488six@139.com - author
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.visor.module.monitor.handler.alarm;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const;
import org.dromara.visor.common.enums.BooleanBit;
import org.dromara.visor.module.asset.api.HostAgentApi;
import org.dromara.visor.module.asset.entity.dto.host.HostBaseDTO;
import org.dromara.visor.module.monitor.convert.AlarmEventConvert;
import org.dromara.visor.module.monitor.entity.domain.AlarmEventDO;
import org.dromara.visor.module.monitor.entity.dto.*;
import org.dromara.visor.module.monitor.enums.AlarmHandleStatusEnum;
import org.dromara.visor.module.monitor.enums.AlarmSwitchEnum;
import org.dromara.visor.module.monitor.enums.MetricsUnitEnum;
import org.dromara.visor.module.monitor.handler.alarm.model.AlarmEngineRule;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import java.util.Optional;
/**
* 告警引擎
*
* @author Jiahang Li
* @version 1.0.0
* @since 2025/8/21 17:26
*/
@Slf4j
@Component("metricsAlarmEngine")
public class MetricsAlarmEngine extends BaseAlarmEngine {
@Resource
protected HostAgentApi hostAgentApi;
@Override
protected Long getAlarmPolicyId(String agentKey) {
// 获取主机信息
MonitorHostContextDTO monitorHost = monitorAgentContext.getMonitorHost(agentKey);
if (monitorHost == null) {
return null;
}
// 检查策略是否开启
Long policyId = monitorHost.getPolicyId();
if (policyId == null || AlarmSwitchEnum.isOff(monitorHost.getAlarmSwitch())) {
return null;
}
return policyId;
}
@Override
protected AlarmEventTriggerDTO createAlarmEvent(String agentKey,
Long alarmTimestamp,
AgentMetricsDTO agentMetrics,
BigDecimal metricsValue,
AlarmEngineRule rule) {
MonitorHostContextDTO monitorHost = monitorAgentContext.getMonitorHost(agentKey);
// 查询主机信息
HostBaseDTO host = hostAgentApi.getHostCacheByAgentKey(agentKey);
if (host == null) {
host = new HostBaseDTO();
}
// 获取指标
MonitorMetricsContextDTO metrics = monitorMetricsContext.getMonitorMetrics(rule.getMetricsId());
// 指标单位
MetricsUnitEnum unit = MetricsUnitEnum.of(metrics.getUnit());
// 获取连续触发次数
Integer consecutiveCount = Optional.ofNullable(TRIGGER_STATE_CACHE.get(this.getTriggerStateCacheKey(agentKey, rule)))
.map(AlarmTriggerStateDTO::getConsecutiveCount)
.orElse(1);
// 构建告警信息
String alarmInfo = this.buildAlarmInfo(metrics, rule, unit, metricsValue, consecutiveCount);
// 创建告警事件记录
Map<String, String> tags = agentMetrics.getTags();
AlarmEventDO alarmEvent = AlarmEventDO.builder()
.agentKey(agentKey)
.hostId(host.getId())
.hostName(host.getName())
.hostAddress(host.getAddress())
.policyId(rule.getPolicyId())
.policyRuleId(rule.getId())
.metricsId(rule.getMetricsId())
.metricsMeasurement(metrics.getMeasurement())
.alarmTags(tags == null ? Const.EMPTY_OBJECT : JSON.toJSONString(tags))
.alarmValue(metricsValue)
.alarmThreshold(unit.getThresholdOriginalValue(rule.getThreshold()))
.alarmInfo(alarmInfo)
.alarmLevel(rule.getLevel())
.triggerCondition(rule.getTriggerCondition())
.consecutiveCount(consecutiveCount)
.falseAlarm(BooleanBit.FALSE.getValue())
.handleStatus(AlarmHandleStatusEnum.NEW.name())
.handleUserId(monitorHost.getOwnerUserId())
.handleUsername(monitorHost.getOwnerUsername())
.createTime(new Date(alarmTimestamp))
.updateTime(new Date(alarmTimestamp))
.build();
// 保存告警事件
alarmEventService.createAlarmEvent(alarmEvent);
// 填充其他参数
return AlarmEventConvert.MAPPER.toTrigger(alarmEvent);
}
}

View File

@@ -20,7 +20,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.visor.module.monitor.engine; package org.dromara.visor.module.monitor.handler.alarm.model;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;

View File

@@ -20,7 +20,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.visor.module.monitor.engine; package org.dromara.visor.module.monitor.handler.alarm.model;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;

View File

@@ -23,7 +23,7 @@
package org.dromara.visor.module.monitor.listener; package org.dromara.visor.module.monitor.listener;
import org.dromara.visor.module.asset.entity.event.AgentOfflineEvent; import org.dromara.visor.module.asset.entity.event.AgentOfflineEvent;
import org.dromara.visor.module.monitor.engine.MonitorContext; import org.dromara.visor.module.monitor.context.MonitorAgentContext;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -41,13 +41,13 @@ import java.util.List;
public class AgentOfflineEventListener implements ApplicationListener<AgentOfflineEvent> { public class AgentOfflineEventListener implements ApplicationListener<AgentOfflineEvent> {
@Resource @Resource
private MonitorContext monitorContext; private MonitorAgentContext monitorAgentContext;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void onApplicationEvent(AgentOfflineEvent event) { public void onApplicationEvent(AgentOfflineEvent event) {
List<String> agentKeys = (List<String>) event.getSource(); List<String> agentKeys = (List<String>) event.getSource();
agentKeys.forEach(monitorContext::setAgentOffline); agentKeys.forEach(monitorAgentContext::setAgentOffline);
} }
} }

View File

@@ -35,7 +35,6 @@ import org.dromara.visor.module.monitor.convert.AlarmPolicyRuleConvert;
import org.dromara.visor.module.monitor.dao.AlarmPolicyDAO; import org.dromara.visor.module.monitor.dao.AlarmPolicyDAO;
import org.dromara.visor.module.monitor.dao.AlarmPolicyRuleDAO; import org.dromara.visor.module.monitor.dao.AlarmPolicyRuleDAO;
import org.dromara.visor.module.monitor.dao.MonitorMetricsDAO; import org.dromara.visor.module.monitor.dao.MonitorMetricsDAO;
import org.dromara.visor.module.monitor.engine.AlarmEngineContext;
import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyDO; import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyDO;
import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyRuleDO; import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyRuleDO;
import org.dromara.visor.module.monitor.entity.domain.MonitorMetricsDO; import org.dromara.visor.module.monitor.entity.domain.MonitorMetricsDO;
@@ -44,6 +43,7 @@ import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyRuleUpda
import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyRuleUpdateSwitchRequest; import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyRuleUpdateSwitchRequest;
import org.dromara.visor.module.monitor.entity.vo.AlarmPolicyRuleVO; import org.dromara.visor.module.monitor.entity.vo.AlarmPolicyRuleVO;
import org.dromara.visor.module.monitor.enums.AlarmSwitchEnum; import org.dromara.visor.module.monitor.enums.AlarmSwitchEnum;
import org.dromara.visor.module.monitor.handler.alarm.AlarmEngineContext;
import org.dromara.visor.module.monitor.service.AlarmPolicyRuleService; import org.dromara.visor.module.monitor.service.AlarmPolicyRuleService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;

View File

@@ -38,7 +38,6 @@ import org.dromara.visor.module.monitor.dao.AlarmPolicyNotifyDAO;
import org.dromara.visor.module.monitor.dao.AlarmPolicyRuleDAO; import org.dromara.visor.module.monitor.dao.AlarmPolicyRuleDAO;
import org.dromara.visor.module.monitor.dao.MonitorHostDAO; import org.dromara.visor.module.monitor.dao.MonitorHostDAO;
import org.dromara.visor.module.monitor.define.cache.AlarmPolicyCacheKeyDefine; import org.dromara.visor.module.monitor.define.cache.AlarmPolicyCacheKeyDefine;
import org.dromara.visor.module.monitor.engine.AlarmEngineContext;
import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyDO; import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyDO;
import org.dromara.visor.module.monitor.entity.dto.AlarmPolicyAlarmCountDTO; import org.dromara.visor.module.monitor.entity.dto.AlarmPolicyAlarmCountDTO;
import org.dromara.visor.module.monitor.entity.dto.AlarmPolicyCacheDTO; import org.dromara.visor.module.monitor.entity.dto.AlarmPolicyCacheDTO;
@@ -49,6 +48,7 @@ import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyCreateRe
import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyQueryRequest; import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyQueryRequest;
import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyUpdateRequest; import org.dromara.visor.module.monitor.entity.request.alarm.AlarmPolicyUpdateRequest;
import org.dromara.visor.module.monitor.entity.vo.AlarmPolicyVO; import org.dromara.visor.module.monitor.entity.vo.AlarmPolicyVO;
import org.dromara.visor.module.monitor.handler.alarm.AlarmEngineContext;
import org.dromara.visor.module.monitor.service.AlarmEventService; import org.dromara.visor.module.monitor.service.AlarmEventService;
import org.dromara.visor.module.monitor.service.AlarmPolicyNotifyService; import org.dromara.visor.module.monitor.service.AlarmPolicyNotifyService;
import org.dromara.visor.module.monitor.service.AlarmPolicyRuleService; import org.dromara.visor.module.monitor.service.AlarmPolicyRuleService;

View File

@@ -23,6 +23,7 @@
package org.dromara.visor.module.monitor.service.impl; package org.dromara.visor.module.monitor.service.impl;
import cn.orionsec.kit.lang.able.Executable; import cn.orionsec.kit.lang.able.Executable;
import cn.orionsec.kit.lang.annotation.Keep;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import cn.orionsec.kit.lang.utils.collect.Maps; import cn.orionsec.kit.lang.utils.collect.Maps;
@@ -38,14 +39,14 @@ import org.dromara.visor.framework.influxdb.core.utils.InfluxdbUtils;
import org.dromara.visor.module.asset.api.HostApi; import org.dromara.visor.module.asset.api.HostApi;
import org.dromara.visor.module.asset.entity.dto.host.HostDTO; import org.dromara.visor.module.asset.entity.dto.host.HostDTO;
import org.dromara.visor.module.infra.api.SystemUserApi; import org.dromara.visor.module.infra.api.SystemUserApi;
import org.dromara.visor.module.monitor.context.MonitorAgentContext;
import org.dromara.visor.module.monitor.dao.MonitorHostDAO; import org.dromara.visor.module.monitor.dao.MonitorHostDAO;
import org.dromara.visor.module.monitor.engine.AlarmEngine;
import org.dromara.visor.module.monitor.engine.MonitorContext;
import org.dromara.visor.module.monitor.entity.domain.MonitorHostDO; import org.dromara.visor.module.monitor.entity.domain.MonitorHostDO;
import org.dromara.visor.module.monitor.entity.dto.AgentMetricsDataDTO; import org.dromara.visor.module.monitor.entity.dto.AgentMetricsDataDTO;
import org.dromara.visor.module.monitor.entity.dto.HostMetaDTO; import org.dromara.visor.module.monitor.entity.dto.HostMetaDTO;
import org.dromara.visor.module.monitor.entity.dto.MonitorHostConfigDTO; import org.dromara.visor.module.monitor.entity.dto.MonitorHostConfigDTO;
import org.dromara.visor.module.monitor.enums.AlarmSwitchEnum; import org.dromara.visor.module.monitor.enums.AlarmSwitchEnum;
import org.dromara.visor.module.monitor.handler.alarm.IAlarmEngine;
import org.dromara.visor.module.monitor.service.MonitorAgentEndpointService; import org.dromara.visor.module.monitor.service.MonitorAgentEndpointService;
import org.dromara.visor.module.monitor.utils.MetricsUtils; import org.dromara.visor.module.monitor.utils.MetricsUtils;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
@@ -79,18 +80,19 @@ public class MonitorAgentEndpointServiceImpl implements MonitorAgentEndpointServ
private SystemUserApi systemUserApi; private SystemUserApi systemUserApi;
@Resource @Resource
private MonitorContext monitorContext; private MonitorAgentContext monitorAgentContext;
@Keep
@Resource @Resource
private AlarmEngine alarmEngine; private IAlarmEngine metricsAlarmEngine;
@Override @Override
@Async("metricsExecutor") @Async("metricsExecutor")
public void addMetrics(String agentKey, AgentMetricsDataDTO newMetrics) { public void addMetrics(String agentKey, AgentMetricsDataDTO newMetrics) {
log.info("MonitorAgentEndpointService.addMetrics start agentKey: {}", agentKey); log.info("MonitorAgentEndpointService.addMetrics start agentKey: {}", agentKey);
// 设置数据缓存 // 设置数据缓存
AgentMetricsDataDTO prevMetrics = monitorContext.getAgentMetrics(agentKey); AgentMetricsDataDTO prevMetrics = monitorAgentContext.getAgentMetrics(agentKey);
monitorContext.setAgentMetrics(agentKey, newMetrics); monitorAgentContext.setAgentMetrics(agentKey, newMetrics);
// 数据点 // 数据点
List<Point> points = newMetrics.getMetrics() List<Point> points = newMetrics.getMetrics()
.stream() .stream()
@@ -102,7 +104,7 @@ public class MonitorAgentEndpointServiceImpl implements MonitorAgentEndpointServ
// 写入数据点 // 写入数据点
InfluxdbUtils.writePoints(points); InfluxdbUtils.writePoints(points);
// 告警 // 告警
alarmEngine.checkAndAlarm(agentKey, prevMetrics, newMetrics); metricsAlarmEngine.checkAndAlarm(agentKey, prevMetrics, newMetrics);
} }
@Override @Override
@@ -149,7 +151,7 @@ public class MonitorAgentEndpointServiceImpl implements MonitorAgentEndpointServ
} }
// 重新加载监控主机上下文 // 重新加载监控主机上下文
if (newConfig != null) { if (newConfig != null) {
monitorContext.reloadMonitorHost(agentKey); monitorAgentContext.reloadMonitorHost(agentKey);
} }
}; };
// 获取锁并执行同步逻辑 // 获取锁并执行同步逻辑

View File

@@ -48,10 +48,10 @@ import org.dromara.visor.module.asset.entity.dto.host.HostQueryDTO;
import org.dromara.visor.module.asset.enums.AgentOnlineStatusEnum; import org.dromara.visor.module.asset.enums.AgentOnlineStatusEnum;
import org.dromara.visor.module.infra.api.SystemUserApi; import org.dromara.visor.module.infra.api.SystemUserApi;
import org.dromara.visor.module.monitor.constant.MetricsConst; import org.dromara.visor.module.monitor.constant.MetricsConst;
import org.dromara.visor.module.monitor.context.MonitorAgentContext;
import org.dromara.visor.module.monitor.convert.MonitorHostConvert; import org.dromara.visor.module.monitor.convert.MonitorHostConvert;
import org.dromara.visor.module.monitor.dao.AlarmPolicyDAO; import org.dromara.visor.module.monitor.dao.AlarmPolicyDAO;
import org.dromara.visor.module.monitor.dao.MonitorHostDAO; import org.dromara.visor.module.monitor.dao.MonitorHostDAO;
import org.dromara.visor.module.monitor.engine.MonitorContext;
import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyDO; import org.dromara.visor.module.monitor.entity.domain.AlarmPolicyDO;
import org.dromara.visor.module.monitor.entity.domain.MonitorHostDO; import org.dromara.visor.module.monitor.entity.domain.MonitorHostDO;
import org.dromara.visor.module.monitor.entity.dto.*; import org.dromara.visor.module.monitor.entity.dto.*;
@@ -102,7 +102,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
private MonitorMetricsService monitorMetricsService; private MonitorMetricsService monitorMetricsService;
@Resource @Resource
private MonitorContext monitorContext; private MonitorAgentContext monitorAgentContext;
@Override @Override
public DataGrid<MonitorHostVO> getMonitorHostPage(MonitorHostQueryRequest request) { public DataGrid<MonitorHostVO> getMonitorHostPage(MonitorHostQueryRequest request) {
@@ -308,7 +308,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
monitorHostDAO.setPolicyIdWithNullById(id); monitorHostDAO.setPolicyIdWithNullById(id);
} }
// 重新加载监控主机上下文 // 重新加载监控主机上下文
monitorContext.reloadMonitorHost(host.getAgentKey()); monitorAgentContext.reloadMonitorHost(host.getAgentKey());
log.info("MonitorHostService-updateMonitorHostById effect: {}", effect); log.info("MonitorHostService-updateMonitorHostById effect: {}", effect);
return effect; return effect;
} }
@@ -334,7 +334,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
log.info("MonitorHostService-updateMonitorHostAlarmSwitch effect: {}", effect); log.info("MonitorHostService-updateMonitorHostAlarmSwitch effect: {}", effect);
// 更新缓存 // 更新缓存
for (HostDTO host : hostList) { for (HostDTO host : hostList) {
monitorContext.reloadMonitorHost(host.getAgentKey()); monitorAgentContext.reloadMonitorHost(host.getAgentKey());
} }
return effect; return effect;
} }
@@ -350,7 +350,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
// 删除 // 删除
int effect = monitorHostDAO.deleteByHostIdList(hostIdList); int effect = monitorHostDAO.deleteByHostIdList(hostIdList);
// 删除缓存 // 删除缓存
hosts.forEach(s -> monitorContext.removeMonitorHost(s.getAgentKey())); hosts.forEach(s -> monitorAgentContext.removeMonitorHost(s.getAgentKey()));
log.info("MonitorHostService.deleteByHostIdList finish effect: {}", effect); log.info("MonitorHostService.deleteByHostIdList finish effect: {}", effect);
return effect; return effect;
} }
@@ -394,7 +394,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
List<String> fields = request.getFields(); List<String> fields = request.getFields();
// 获取配置信息 // 获取配置信息
List<MonitorHostConfigDTO> configList = agentKeys.stream() List<MonitorHostConfigDTO> configList = agentKeys.stream()
.map(monitorContext::getMonitorHost) .map(monitorAgentContext::getMonitorHost)
.map(MonitorHostContextDTO::getConfig) .map(MonitorHostContextDTO::getConfig)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.collect(Collectors.toList()); .collect(Collectors.toList());
@@ -446,7 +446,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
* @return data * @return data
*/ */
public MonitorHostMetricsDataVO getHostMetricsData(String agentKey, MonitorHostConfigDTO config) { public MonitorHostMetricsDataVO getHostMetricsData(String agentKey, MonitorHostConfigDTO config) {
AgentMetricsDataDTO metrics = monitorContext.getAgentMetrics(agentKey); AgentMetricsDataDTO metrics = monitorAgentContext.getAgentMetrics(agentKey);
// 无数据 // 无数据
if (metrics == null) { if (metrics == null) {
return MonitorHostMetricsDataVO.noData(agentKey); return MonitorHostMetricsDataVO.noData(agentKey);
@@ -454,7 +454,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
// 从缓存中获取配置 // 从缓存中获取配置
if (config == null) { if (config == null) {
config = Optional.of(agentKey) config = Optional.of(agentKey)
.map(monitorContext::getMonitorHost) .map(monitorAgentContext::getMonitorHost)
.map(MonitorHostContextDTO::getConfig) .map(MonitorHostContextDTO::getConfig)
.orElse(null); .orElse(null);
} }

View File

@@ -31,10 +31,10 @@ import org.dromara.visor.common.utils.Assert;
import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs; import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs;
import org.dromara.visor.framework.redis.core.utils.RedisMaps; import org.dromara.visor.framework.redis.core.utils.RedisMaps;
import org.dromara.visor.framework.redis.core.utils.barrier.CacheBarriers; import org.dromara.visor.framework.redis.core.utils.barrier.CacheBarriers;
import org.dromara.visor.module.monitor.context.MonitorMetricsContext;
import org.dromara.visor.module.monitor.convert.MonitorMetricsConvert; import org.dromara.visor.module.monitor.convert.MonitorMetricsConvert;
import org.dromara.visor.module.monitor.dao.MonitorMetricsDAO; import org.dromara.visor.module.monitor.dao.MonitorMetricsDAO;
import org.dromara.visor.module.monitor.define.cache.MonitorMetricsCacheKeyDefine; import org.dromara.visor.module.monitor.define.cache.MonitorMetricsCacheKeyDefine;
import org.dromara.visor.module.monitor.engine.MonitorContext;
import org.dromara.visor.module.monitor.entity.domain.MonitorMetricsDO; import org.dromara.visor.module.monitor.entity.domain.MonitorMetricsDO;
import org.dromara.visor.module.monitor.entity.dto.MonitorMetricsCacheDTO; import org.dromara.visor.module.monitor.entity.dto.MonitorMetricsCacheDTO;
import org.dromara.visor.module.monitor.entity.dto.MonitorMetricsContextDTO; import org.dromara.visor.module.monitor.entity.dto.MonitorMetricsContextDTO;
@@ -70,7 +70,7 @@ public class MonitorMetricsServiceImpl implements MonitorMetricsService {
private AlarmPolicyRuleService alarmPolicyRuleService; private AlarmPolicyRuleService alarmPolicyRuleService;
@Resource @Resource
private MonitorContext monitorContext; private MonitorMetricsContext monitorMetricsContext;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@@ -88,7 +88,7 @@ public class MonitorMetricsServiceImpl implements MonitorMetricsService {
// 设置日志参数 // 设置日志参数
OperatorLogs.add(OperatorLogs.ID, id); OperatorLogs.add(OperatorLogs.ID, id);
// 重新加载本地缓存 // 重新加载本地缓存
monitorContext.reloadMonitorMetrics(id); monitorMetricsContext.reloadMonitorMetrics(id);
log.info("MonitorMetricsService-createMonitorMetrics id: {}, effect: {}", id, effect); log.info("MonitorMetricsService-createMonitorMetrics id: {}, effect: {}", id, effect);
return id; return id;
} }
@@ -112,7 +112,7 @@ public class MonitorMetricsServiceImpl implements MonitorMetricsService {
// 删除缓存 // 删除缓存
RedisMaps.delete(MonitorMetricsCacheKeyDefine.MONITOR_METRICS); RedisMaps.delete(MonitorMetricsCacheKeyDefine.MONITOR_METRICS);
// 重新加载本地缓存 // 重新加载本地缓存
monitorContext.reloadMonitorMetrics(id); monitorMetricsContext.reloadMonitorMetrics(id);
return effect; return effect;
} }
@@ -151,7 +151,7 @@ public class MonitorMetricsServiceImpl implements MonitorMetricsService {
@Override @Override
public String getMetricName(String measurement, String value) { public String getMetricName(String measurement, String value) {
MonitorMetricsContextDTO metrics = monitorContext.getMonitorMetrics(measurement, value); MonitorMetricsContextDTO metrics = monitorMetricsContext.getMonitorMetrics(measurement, value);
if (metrics == null) { if (metrics == null) {
return value; return value;
} }
@@ -172,7 +172,7 @@ public class MonitorMetricsServiceImpl implements MonitorMetricsService {
// 删除缓存 // 删除缓存
RedisMaps.delete(MonitorMetricsCacheKeyDefine.MONITOR_METRICS, id); RedisMaps.delete(MonitorMetricsCacheKeyDefine.MONITOR_METRICS, id);
// 重新加载本地缓存 // 重新加载本地缓存
monitorContext.reloadMonitorMetrics(id); monitorMetricsContext.reloadMonitorMetrics(id);
// 设置日志参数 // 设置日志参数
OperatorLogs.add(OperatorLogs.NAME, record.getName()); OperatorLogs.add(OperatorLogs.NAME, record.getName());
log.info("MonitorMetricsService-deleteMonitorMetricsById id: {}, effect: {}", id, effect); log.info("MonitorMetricsService-deleteMonitorMetricsById id: {}, effect: {}", id, effect);