🔨 优化监控逻辑.
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* 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.TimedCacheBuilder;
|
||||
@@ -29,15 +29,11 @@ import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.visor.common.constant.Const;
|
||||
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.MonitorMetricsDAO;
|
||||
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.MonitorHostConfigDTO;
|
||||
import org.dromara.visor.module.monitor.entity.dto.MonitorHostContextDTO;
|
||||
import org.dromara.visor.module.monitor.entity.dto.MonitorMetricsContextDTO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
@@ -47,7 +43,7 @@ import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 监控上下文
|
||||
* 监控探针上下文
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
@@ -55,23 +51,13 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MonitorContext {
|
||||
public class MonitorAgentContext {
|
||||
|
||||
/**
|
||||
* 监控主机缓存
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -88,9 +74,6 @@ public class MonitorContext {
|
||||
.checkInterval(Const.MS_S_60)
|
||||
.build();
|
||||
|
||||
@Resource
|
||||
private MonitorMetricsDAO monitorMetricsDAO;
|
||||
|
||||
@Resource
|
||||
private MonitorHostDAO monitorHostDAO;
|
||||
|
||||
@@ -103,10 +86,6 @@ public class MonitorContext {
|
||||
log.info("MonitorContext-init hosts start.");
|
||||
this.loadMonitorHost();
|
||||
log.info("MonitorContext-init hosts end.");
|
||||
// 初始化监控指标
|
||||
log.info("MonitorContext-init metrics start.");
|
||||
this.loadMonitorMetrics();
|
||||
log.info("MonitorContext-init metrics end.");
|
||||
}
|
||||
|
||||
@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()));
|
||||
}
|
||||
|
||||
// ----------------------- 监控主机 ----------------------
|
||||
|
||||
/**
|
||||
@@ -194,7 +162,7 @@ public class MonitorContext {
|
||||
* @param metrics 指标
|
||||
*/
|
||||
public void setAgentMetrics(String agentKey, AgentMetricsDataDTO metrics) {
|
||||
// 设置指标数据
|
||||
// 设置指标数据
|
||||
LATEST_METRICS_CACHE.put(agentKey, metrics);
|
||||
// 更新心跳时间
|
||||
AGENT_LAST_ACTIVE_TIME.put(agentKey, System.currentTimeMillis());
|
||||
@@ -237,72 +205,4 @@ public class MonitorContext {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.web.core.annotation.DemoDisableApi;
|
||||
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.engine.MonitorContext;
|
||||
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.vo.MonitorHostMetricsDataVO;
|
||||
@@ -68,7 +68,7 @@ public class MonitorHostController {
|
||||
private MonitorHostService monitorHostService;
|
||||
|
||||
@Resource
|
||||
private MonitorContext monitorContext;
|
||||
private MonitorAgentContext monitorAgentContext;
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@PostMapping("/query")
|
||||
@@ -84,7 +84,7 @@ public class MonitorHostController {
|
||||
@Parameter(name = "agentKey", description = "agentKey", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('monitor:monitor-host:query')")
|
||||
public AgentMetricsDataDTO getMonitorHostOverride(@RequestParam("agentKey") String agentKey) {
|
||||
return monitorContext.getAgentMetrics(agentKey);
|
||||
return monitorAgentContext.getAgentMetrics(agentKey);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
*/
|
||||
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.request.alarm.AlarmPolicyRuleCreateRequest;
|
||||
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.handler.alarm.model.AlarmEngineRule;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* 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.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.AlarmPolicyRuleDO;
|
||||
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 javax.annotation.PostConstruct;
|
||||
@@ -20,7 +20,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* 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.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.io.Streams;
|
||||
import cn.orionsec.kit.lang.utils.time.Dates;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.visor.common.constant.Const;
|
||||
import org.dromara.visor.common.entity.PushUser;
|
||||
import org.dromara.visor.common.enums.BooleanBit;
|
||||
import org.dromara.visor.framework.biz.push.core.utils.PushUtils;
|
||||
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.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.entity.domain.AlarmEventDO;
|
||||
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.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.annotation.Resource;
|
||||
@@ -57,62 +57,50 @@ import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 告警引擎
|
||||
* 告警引擎基类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2025/8/21 17:26
|
||||
* @since 2025/10/13 10:12
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AlarmEngine {
|
||||
public abstract class BaseAlarmEngine implements IAlarmEngine {
|
||||
|
||||
/**
|
||||
* 告警触发状态缓存 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)
|
||||
.checkInterval(Const.MS_S_60)
|
||||
.build();
|
||||
|
||||
@Resource
|
||||
private AlarmEngineContext alarmEngineContext;
|
||||
protected AlarmEngineContext alarmEngineContext;
|
||||
|
||||
@Resource
|
||||
private MonitorContext monitorContext;
|
||||
protected MonitorAgentContext monitorAgentContext;
|
||||
|
||||
@Resource
|
||||
private AlarmEventService alarmEventService;
|
||||
protected MonitorMetricsContext monitorMetricsContext;
|
||||
|
||||
@Resource
|
||||
private HostAgentApi hostAgentApi;
|
||||
protected AlarmEventService alarmEventService;
|
||||
|
||||
@Resource
|
||||
private SystemUserApi systemUserApi;
|
||||
protected SystemUserApi systemUserApi;
|
||||
|
||||
@PreDestroy
|
||||
public void destroyTimedCache() {
|
||||
Streams.close(TRIGGER_STATE_CACHE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查并且告警
|
||||
*
|
||||
* @param agentKey agentKey
|
||||
* @param prevMetrics prevMetrics
|
||||
* @param newMetrics newMetrics
|
||||
*/
|
||||
@Override
|
||||
public void checkAndAlarm(String agentKey,
|
||||
AgentMetricsDataDTO prevMetrics,
|
||||
AgentMetricsDataDTO newMetrics) {
|
||||
// 获取主机信息
|
||||
MonitorHostContextDTO monitorHost = monitorContext.getMonitorHost(agentKey);
|
||||
if (monitorHost == null) {
|
||||
return;
|
||||
}
|
||||
// 检查策略是否开启
|
||||
Long policyId = monitorHost.getPolicyId();
|
||||
if (policyId == null || AlarmSwitchEnum.isOff(monitorHost.getAlarmSwitch())) {
|
||||
// 获取告警策略
|
||||
Long policyId = this.getAlarmPolicyId(agentKey);
|
||||
if (policyId == null) {
|
||||
return;
|
||||
}
|
||||
// 获取对应的策略
|
||||
@@ -132,7 +120,7 @@ public class AlarmEngine {
|
||||
// 检查指标
|
||||
AlarmEventTriggerDTO event = this.checkAndAlarm(agentKey,
|
||||
prevMetrics, newMetrics, agentMetrics, metricsField,
|
||||
policy, monitorHost);
|
||||
policy);
|
||||
if (event != null) {
|
||||
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 metricsField metricsField
|
||||
* @param policy policy
|
||||
* @param monitorHost monitorHost
|
||||
* @return event
|
||||
*/
|
||||
private AlarmEventTriggerDTO checkAndAlarm(String agentKey,
|
||||
AgentMetricsDataDTO prevMetrics,
|
||||
AgentMetricsDataDTO newMetrics,
|
||||
AgentMetricsDTO agentMetrics,
|
||||
String metricsField,
|
||||
AlarmEnginePolicy policy,
|
||||
MonitorHostContextDTO monitorHost) {
|
||||
Long timestamp = newMetrics.getTimestamp();
|
||||
protected AlarmEventTriggerDTO checkAndAlarm(String agentKey,
|
||||
AgentMetricsDataDTO prevMetrics,
|
||||
AgentMetricsDataDTO newMetrics,
|
||||
AgentMetricsDTO agentMetrics,
|
||||
String metricsField,
|
||||
AlarmEnginePolicy policy) {
|
||||
Long alarmTimestamp = newMetrics.getTimestamp();
|
||||
// 指标id
|
||||
Long metricsId = monitorContext.getMonitorMetricsId(agentMetrics.getType(), metricsField);
|
||||
Long metricsId = monitorMetricsContext.getMonitorMetricsId(agentMetrics.getType(), metricsField);
|
||||
if (metricsId == null) {
|
||||
return null;
|
||||
}
|
||||
// 指标值
|
||||
BigDecimal metricsValue;
|
||||
metricsValue = agentMetrics.getValues().getBigDecimal(metricsField);
|
||||
BigDecimal metricsValue = agentMetrics.getValues().getBigDecimal(metricsField);
|
||||
if (metricsValue == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -200,14 +193,30 @@ public class AlarmEngine {
|
||||
return null;
|
||||
}
|
||||
// 检查是否在静默期
|
||||
boolean inSilence = this.checkAndSetInSilencePeriod(agentKey, timestamp, matchedRule);
|
||||
boolean inSilence = this.checkAndSetInSilencePeriod(agentKey, alarmTimestamp, matchedRule);
|
||||
if (inSilence) {
|
||||
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
|
||||
*
|
||||
@@ -216,9 +225,9 @@ public class AlarmEngine {
|
||||
* @param metricsValue metricsValue
|
||||
* @return rule
|
||||
*/
|
||||
private AlarmEngineRule matchTaggedAgentMetricsRule(List<AlarmEngineRule> rules,
|
||||
Map<String, String> metricsTags,
|
||||
BigDecimal metricsValue) {
|
||||
protected AlarmEngineRule matchTaggedAgentMetricsRule(List<AlarmEngineRule> rules,
|
||||
Map<String, String> metricsTags,
|
||||
BigDecimal metricsValue) {
|
||||
AlarmEngineRule matchedRule = null;
|
||||
// context 根据 level 排序了
|
||||
for (AlarmEngineRule rule : rules) {
|
||||
@@ -265,7 +274,7 @@ public class AlarmEngine {
|
||||
* @param metricsValue metricsValue
|
||||
* @return rule
|
||||
*/
|
||||
private AlarmEngineRule matchAgentMetricsRule(List<AlarmEngineRule> rules, BigDecimal metricsValue) {
|
||||
protected AlarmEngineRule matchAgentMetricsRule(List<AlarmEngineRule> rules, BigDecimal metricsValue) {
|
||||
AlarmEngineRule matchedRule = null;
|
||||
// context 根据 level 排序了
|
||||
for (AlarmEngineRule rule : rules) {
|
||||
@@ -289,13 +298,13 @@ public class AlarmEngine {
|
||||
* @param rule rule
|
||||
* @param metricValue metricValue
|
||||
*/
|
||||
private boolean checkAlarmCondition(AlarmEngineRule rule, BigDecimal metricValue) {
|
||||
protected boolean checkAlarmCondition(AlarmEngineRule rule, BigDecimal metricValue) {
|
||||
// 获取指标值
|
||||
if (metricValue == null) {
|
||||
return false;
|
||||
}
|
||||
// 获取指标单位
|
||||
MonitorMetricsContextDTO metrics = monitorContext.getMonitorMetrics(rule.getMetricsId());
|
||||
MonitorMetricsContextDTO metrics = monitorMetricsContext.getMonitorMetrics(rule.getMetricsId());
|
||||
MetricsUnitEnum unit = Optional.ofNullable(metrics)
|
||||
.map(MonitorMetricsContextDTO::getUnit)
|
||||
.map(MetricsUnitEnum::of)
|
||||
@@ -310,13 +319,8 @@ public class AlarmEngine {
|
||||
}
|
||||
// 将阈值转换为原始值
|
||||
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
|
||||
* @return eval
|
||||
*/
|
||||
private boolean evaluateCondition(AlarmTriggerConditionEnum condition,
|
||||
BigDecimal metricValue,
|
||||
BigDecimal threshold) {
|
||||
switch (condition) {
|
||||
protected boolean evaluateCondition(String condition,
|
||||
BigDecimal metricValue,
|
||||
BigDecimal threshold) {
|
||||
// 触发条件
|
||||
AlarmTriggerConditionEnum triggerCondition = AlarmTriggerConditionEnum.of(condition);
|
||||
switch (triggerCondition) {
|
||||
case GT:
|
||||
return metricValue.compareTo(threshold) > 0;
|
||||
case GE:
|
||||
@@ -356,10 +362,10 @@ public class AlarmEngine {
|
||||
* @param rule rule
|
||||
* @return result
|
||||
*/
|
||||
private boolean checkConsecutiveCount(String agentKey,
|
||||
AgentMetricsDataDTO prevMetrics,
|
||||
AgentMetricsDataDTO newMetrics,
|
||||
AlarmEngineRule rule) {
|
||||
protected boolean checkConsecutiveCount(String agentKey,
|
||||
AgentMetricsDataDTO prevMetrics,
|
||||
AgentMetricsDataDTO newMetrics,
|
||||
AlarmEngineRule rule) {
|
||||
// 获取规则连续触发次数
|
||||
Integer ruleConsecutiveCount = Objects1.def(rule.getConsecutiveCount(), 1);
|
||||
// 获取指标连续触发次数
|
||||
@@ -393,8 +399,8 @@ public class AlarmEngine {
|
||||
* @param prevMetrics prevMetrics
|
||||
* @return isConsecutiveTrigger
|
||||
*/
|
||||
private boolean isConsecutiveTrigger(AlarmTriggerStateDTO triggerState,
|
||||
AgentMetricsDataDTO prevMetrics) {
|
||||
protected boolean isConsecutiveTrigger(AlarmTriggerStateDTO triggerState,
|
||||
AgentMetricsDataDTO prevMetrics) {
|
||||
if (prevMetrics == null || triggerState == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -404,14 +410,14 @@ public class AlarmEngine {
|
||||
/**
|
||||
* 检查并且设置静默期
|
||||
*
|
||||
* @param agentKey agentKey
|
||||
* @param timestamp timestamp
|
||||
* @param rule rule
|
||||
* @param agentKey agentKey
|
||||
* @param alarmTimestamp alarmTimestamp
|
||||
* @param rule rule
|
||||
* @return inSilence
|
||||
*/
|
||||
private boolean checkAndSetInSilencePeriod(String agentKey,
|
||||
Long timestamp,
|
||||
AlarmEngineRule rule) {
|
||||
protected boolean checkAndSetInSilencePeriod(String agentKey,
|
||||
Long alarmTimestamp,
|
||||
AlarmEngineRule rule) {
|
||||
Integer silencePeriod = Objects1.def(rule.getSilencePeriod(), 0);
|
||||
// 无静默期则触发
|
||||
if (silencePeriod <= 0) {
|
||||
@@ -427,75 +433,11 @@ public class AlarmEngine {
|
||||
.noPrefix()
|
||||
.timeout(silencePeriod, TimeUnit.MINUTES)
|
||||
.build();
|
||||
RedisStrings.set(key, timestamp);
|
||||
RedisStrings.set(key, alarmTimestamp);
|
||||
}
|
||||
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
|
||||
* @return alarmInfo
|
||||
*/
|
||||
private String buildAlarmInfo(MonitorMetricsContextDTO metrics,
|
||||
AlarmEngineRule rule,
|
||||
MetricsUnitEnum unit,
|
||||
BigDecimal metricsValue,
|
||||
Integer consecutiveCount) {
|
||||
protected String buildAlarmInfo(MonitorMetricsContextDTO metrics,
|
||||
AlarmEngineRule rule,
|
||||
MetricsUnitEnum unit,
|
||||
BigDecimal metricsValue,
|
||||
Integer consecutiveCount) {
|
||||
return metrics.getName()
|
||||
+ Const.SPACE + AlarmTriggerConditionEnum.of(rule.getTriggerCondition()).getCondition()
|
||||
+ Const.SPACE + unit.format(rule.getThreshold(), new MetricsUnitEnum.FormatOptions(2, metrics.getSuffix()))
|
||||
@@ -525,7 +467,7 @@ public class AlarmEngine {
|
||||
* @param rule rule
|
||||
* @return cacheKey
|
||||
*/
|
||||
private String getTriggerStateCacheKey(String agentKey, AlarmEngineRule rule) {
|
||||
protected String getTriggerStateCacheKey(String agentKey, AlarmEngineRule rule) {
|
||||
return agentKey + ":" + rule.getId();
|
||||
}
|
||||
|
||||
@@ -535,7 +477,7 @@ public class AlarmEngine {
|
||||
* @param policy policy
|
||||
* @param alarmEvents alarmEvents
|
||||
*/
|
||||
private void notifyAlarmPolicyChannels(AlarmEnginePolicy policy, List<AlarmEventTriggerDTO> alarmEvents) {
|
||||
protected void notifyAlarmPolicyChannels(AlarmEnginePolicy policy, List<AlarmEventTriggerDTO> alarmEvents) {
|
||||
List<Long> notifyIdList = policy.getNotifyIdList();
|
||||
if (Lists.isEmpty(notifyIdList)) {
|
||||
return;
|
||||
@@ -549,7 +491,7 @@ public class AlarmEngine {
|
||||
// 构建参数
|
||||
List<Map<String, Object>> paramsList = new ArrayList<>();
|
||||
for (AlarmEventTriggerDTO event : alarmEvents) {
|
||||
MonitorMetricsContextDTO metrics = monitorContext.getMonitorMetrics(event.getMetricsId());
|
||||
MonitorMetricsContextDTO metrics = monitorMetricsContext.getMonitorMetrics(event.getMetricsId());
|
||||
MetricsUnitEnum unit = MetricsUnitEnum.of(metrics.getUnit());
|
||||
AlarmLevelEnum level = AlarmLevelEnum.of(event.getAlarmLevel());
|
||||
AlarmTriggerConditionEnum triggerCondition = AlarmTriggerConditionEnum.of(event.getTriggerCondition());
|
||||
@@ -590,4 +532,4 @@ public class AlarmEngine {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -20,40 +20,28 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.dromara.visor.module.monitor.engine;
|
||||
package org.dromara.visor.module.monitor.handler.alarm;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.visor.module.monitor.entity.dto.AgentMetricsDataDTO;
|
||||
|
||||
/**
|
||||
* 告警触发状态 - 轻量级缓存对象
|
||||
* 用于减少内存占用,只保存必要的触发状态信息
|
||||
* 告警引擎
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/6/3 18:00
|
||||
* @since 2025/10/13 10:22
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AlarmTriggerState {
|
||||
public interface IAlarmEngine {
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
* 检查并且告警
|
||||
*
|
||||
* @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;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* 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 lombok.AllArgsConstructor;
|
||||
@@ -20,7 +20,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* 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 lombok.AllArgsConstructor;
|
||||
@@ -23,7 +23,7 @@
|
||||
package org.dromara.visor.module.monitor.listener;
|
||||
|
||||
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.stereotype.Component;
|
||||
|
||||
@@ -41,13 +41,13 @@ import java.util.List;
|
||||
public class AgentOfflineEventListener implements ApplicationListener<AgentOfflineEvent> {
|
||||
|
||||
@Resource
|
||||
private MonitorContext monitorContext;
|
||||
private MonitorAgentContext monitorAgentContext;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onApplicationEvent(AgentOfflineEvent event) {
|
||||
List<String> agentKeys = (List<String>) event.getSource();
|
||||
agentKeys.forEach(monitorContext::setAgentOffline);
|
||||
agentKeys.forEach(monitorAgentContext::setAgentOffline);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.AlarmPolicyRuleDAO;
|
||||
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.AlarmPolicyRuleDO;
|
||||
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.vo.AlarmPolicyRuleVO;
|
||||
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.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -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.MonitorHostDAO;
|
||||
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.dto.AlarmPolicyAlarmCountDTO;
|
||||
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.AlarmPolicyUpdateRequest;
|
||||
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.AlarmPolicyNotifyService;
|
||||
import org.dromara.visor.module.monitor.service.AlarmPolicyRuleService;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
package org.dromara.visor.module.monitor.service.impl;
|
||||
|
||||
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.collect.Lists;
|
||||
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.entity.dto.host.HostDTO;
|
||||
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.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.dto.AgentMetricsDataDTO;
|
||||
import org.dromara.visor.module.monitor.entity.dto.HostMetaDTO;
|
||||
import org.dromara.visor.module.monitor.entity.dto.MonitorHostConfigDTO;
|
||||
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.utils.MetricsUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
@@ -79,18 +80,19 @@ public class MonitorAgentEndpointServiceImpl implements MonitorAgentEndpointServ
|
||||
private SystemUserApi systemUserApi;
|
||||
|
||||
@Resource
|
||||
private MonitorContext monitorContext;
|
||||
private MonitorAgentContext monitorAgentContext;
|
||||
|
||||
@Keep
|
||||
@Resource
|
||||
private AlarmEngine alarmEngine;
|
||||
private IAlarmEngine metricsAlarmEngine;
|
||||
|
||||
@Override
|
||||
@Async("metricsExecutor")
|
||||
public void addMetrics(String agentKey, AgentMetricsDataDTO newMetrics) {
|
||||
log.info("MonitorAgentEndpointService.addMetrics start agentKey: {}", agentKey);
|
||||
// 设置数据缓存
|
||||
AgentMetricsDataDTO prevMetrics = monitorContext.getAgentMetrics(agentKey);
|
||||
monitorContext.setAgentMetrics(agentKey, newMetrics);
|
||||
AgentMetricsDataDTO prevMetrics = monitorAgentContext.getAgentMetrics(agentKey);
|
||||
monitorAgentContext.setAgentMetrics(agentKey, newMetrics);
|
||||
// 数据点
|
||||
List<Point> points = newMetrics.getMetrics()
|
||||
.stream()
|
||||
@@ -102,7 +104,7 @@ public class MonitorAgentEndpointServiceImpl implements MonitorAgentEndpointServ
|
||||
// 写入数据点
|
||||
InfluxdbUtils.writePoints(points);
|
||||
// 告警
|
||||
alarmEngine.checkAndAlarm(agentKey, prevMetrics, newMetrics);
|
||||
metricsAlarmEngine.checkAndAlarm(agentKey, prevMetrics, newMetrics);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -149,7 +151,7 @@ public class MonitorAgentEndpointServiceImpl implements MonitorAgentEndpointServ
|
||||
}
|
||||
// 重新加载监控主机上下文
|
||||
if (newConfig != null) {
|
||||
monitorContext.reloadMonitorHost(agentKey);
|
||||
monitorAgentContext.reloadMonitorHost(agentKey);
|
||||
}
|
||||
};
|
||||
// 获取锁并执行同步逻辑
|
||||
|
||||
@@ -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.infra.api.SystemUserApi;
|
||||
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.dao.AlarmPolicyDAO;
|
||||
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.MonitorHostDO;
|
||||
import org.dromara.visor.module.monitor.entity.dto.*;
|
||||
@@ -102,7 +102,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
|
||||
private MonitorMetricsService monitorMetricsService;
|
||||
|
||||
@Resource
|
||||
private MonitorContext monitorContext;
|
||||
private MonitorAgentContext monitorAgentContext;
|
||||
|
||||
@Override
|
||||
public DataGrid<MonitorHostVO> getMonitorHostPage(MonitorHostQueryRequest request) {
|
||||
@@ -308,7 +308,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
|
||||
monitorHostDAO.setPolicyIdWithNullById(id);
|
||||
}
|
||||
// 重新加载监控主机上下文
|
||||
monitorContext.reloadMonitorHost(host.getAgentKey());
|
||||
monitorAgentContext.reloadMonitorHost(host.getAgentKey());
|
||||
log.info("MonitorHostService-updateMonitorHostById effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
@@ -334,7 +334,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
|
||||
log.info("MonitorHostService-updateMonitorHostAlarmSwitch effect: {}", effect);
|
||||
// 更新缓存
|
||||
for (HostDTO host : hostList) {
|
||||
monitorContext.reloadMonitorHost(host.getAgentKey());
|
||||
monitorAgentContext.reloadMonitorHost(host.getAgentKey());
|
||||
}
|
||||
return effect;
|
||||
}
|
||||
@@ -350,7 +350,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
|
||||
// 删除
|
||||
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);
|
||||
return effect;
|
||||
}
|
||||
@@ -394,7 +394,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
|
||||
List<String> fields = request.getFields();
|
||||
// 获取配置信息
|
||||
List<MonitorHostConfigDTO> configList = agentKeys.stream()
|
||||
.map(monitorContext::getMonitorHost)
|
||||
.map(monitorAgentContext::getMonitorHost)
|
||||
.map(MonitorHostContextDTO::getConfig)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
@@ -446,7 +446,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
|
||||
* @return data
|
||||
*/
|
||||
public MonitorHostMetricsDataVO getHostMetricsData(String agentKey, MonitorHostConfigDTO config) {
|
||||
AgentMetricsDataDTO metrics = monitorContext.getAgentMetrics(agentKey);
|
||||
AgentMetricsDataDTO metrics = monitorAgentContext.getAgentMetrics(agentKey);
|
||||
// 无数据
|
||||
if (metrics == null) {
|
||||
return MonitorHostMetricsDataVO.noData(agentKey);
|
||||
@@ -454,7 +454,7 @@ public class MonitorHostServiceImpl implements MonitorHostService {
|
||||
// 从缓存中获取配置
|
||||
if (config == null) {
|
||||
config = Optional.of(agentKey)
|
||||
.map(monitorContext::getMonitorHost)
|
||||
.map(monitorAgentContext::getMonitorHost)
|
||||
.map(MonitorHostContextDTO::getConfig)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@@ -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.redis.core.utils.RedisMaps;
|
||||
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.dao.MonitorMetricsDAO;
|
||||
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.dto.MonitorMetricsCacheDTO;
|
||||
import org.dromara.visor.module.monitor.entity.dto.MonitorMetricsContextDTO;
|
||||
@@ -70,7 +70,7 @@ public class MonitorMetricsServiceImpl implements MonitorMetricsService {
|
||||
private AlarmPolicyRuleService alarmPolicyRuleService;
|
||||
|
||||
@Resource
|
||||
private MonitorContext monitorContext;
|
||||
private MonitorMetricsContext monitorMetricsContext;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -88,7 +88,7 @@ public class MonitorMetricsServiceImpl implements MonitorMetricsService {
|
||||
// 设置日志参数
|
||||
OperatorLogs.add(OperatorLogs.ID, id);
|
||||
// 重新加载本地缓存
|
||||
monitorContext.reloadMonitorMetrics(id);
|
||||
monitorMetricsContext.reloadMonitorMetrics(id);
|
||||
log.info("MonitorMetricsService-createMonitorMetrics id: {}, effect: {}", id, effect);
|
||||
return id;
|
||||
}
|
||||
@@ -112,7 +112,7 @@ public class MonitorMetricsServiceImpl implements MonitorMetricsService {
|
||||
// 删除缓存
|
||||
RedisMaps.delete(MonitorMetricsCacheKeyDefine.MONITOR_METRICS);
|
||||
// 重新加载本地缓存
|
||||
monitorContext.reloadMonitorMetrics(id);
|
||||
monitorMetricsContext.reloadMonitorMetrics(id);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public class MonitorMetricsServiceImpl implements MonitorMetricsService {
|
||||
|
||||
@Override
|
||||
public String getMetricName(String measurement, String value) {
|
||||
MonitorMetricsContextDTO metrics = monitorContext.getMonitorMetrics(measurement, value);
|
||||
MonitorMetricsContextDTO metrics = monitorMetricsContext.getMonitorMetrics(measurement, value);
|
||||
if (metrics == null) {
|
||||
return value;
|
||||
}
|
||||
@@ -172,7 +172,7 @@ public class MonitorMetricsServiceImpl implements MonitorMetricsService {
|
||||
// 删除缓存
|
||||
RedisMaps.delete(MonitorMetricsCacheKeyDefine.MONITOR_METRICS, id);
|
||||
// 重新加载本地缓存
|
||||
monitorContext.reloadMonitorMetrics(id);
|
||||
monitorMetricsContext.reloadMonitorMetrics(id);
|
||||
// 设置日志参数
|
||||
OperatorLogs.add(OperatorLogs.NAME, record.getName());
|
||||
log.info("MonitorMetricsService-deleteMonitorMetricsById id: {}, effect: {}", id, effect);
|
||||
|
||||
Reference in New Issue
Block a user