🔨 优化监控逻辑.
This commit is contained in:
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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.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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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());
|
||||||
@@ -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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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
|
* 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;
|
||||||
@@ -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;
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 获取锁并执行同步逻辑
|
// 获取锁并执行同步逻辑
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user