🔨 监控模块.

This commit is contained in:
lijiahangmax
2025-09-24 23:09:58 +08:00
parent eb8d618c2a
commit 1881086e98
227 changed files with 11276 additions and 603 deletions

View File

@@ -23,6 +23,7 @@
package org.dromara.visor.module.asset.api;
import org.dromara.visor.module.asset.entity.dto.host.HostAgentLogDTO;
import org.dromara.visor.module.asset.entity.dto.host.HostBaseDTO;
import java.util.List;
import java.util.Map;
@@ -50,7 +51,15 @@ public interface HostAgentApi {
* @param agentKeyList agentKeyList
* @return nameMap
*/
Map<String, String> getCacheNameByAgentKey(List<String> agentKeyList);
Map<String, String> getNameCacheByAgentKey(List<String> agentKeyList);
/**
* 获取缓存名称
*
* @param agentKey agentKey
* @return nameMap
*/
HostBaseDTO getHostCacheByAgentKey(String agentKey);
/**
* 获取探针版本

View File

@@ -0,0 +1,47 @@
/*
* 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.asset.entity.event;
import cn.orionsec.kit.lang.utils.collect.Lists;
import org.springframework.context.ApplicationEvent;
import java.util.List;
/**
* agent 下线事件
*
* @author Jiahang Li
* @version 1.0.0
* @since 2025/9/19 20:57
*/
public class AgentOfflineEvent extends ApplicationEvent {
public AgentOfflineEvent(String agentKey) {
this(Lists.singleton(agentKey));
}
public AgentOfflineEvent(List<String> agentKeys) {
super(agentKeys);
}
}

View File

@@ -56,10 +56,6 @@
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-log</artifactId>
</dependency>
<dependency>
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-biz-operator-log</artifactId>
</dependency>
<dependency>
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-desensitize</artifactId>
@@ -96,6 +92,14 @@
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-biz-push</artifactId>
</dependency>
<dependency>
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-biz-operator-log</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -26,18 +26,22 @@ import cn.orionsec.kit.lang.define.cache.TimedCache;
import cn.orionsec.kit.lang.define.cache.TimedCacheBuilder;
import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists;
import cn.orionsec.kit.lang.utils.io.Streams;
import org.dromara.visor.common.constant.Const;
import org.dromara.visor.framework.redis.core.utils.RedisStrings;
import org.dromara.visor.module.asset.api.HostAgentApi;
import org.dromara.visor.module.asset.convert.HostAgentLogProviderConvert;
import org.dromara.visor.module.asset.convert.HostProviderConvert;
import org.dromara.visor.module.asset.dao.HostAgentLogDAO;
import org.dromara.visor.module.asset.dao.HostDAO;
import org.dromara.visor.module.asset.define.cache.HostCacheKeyDefine;
import org.dromara.visor.module.asset.entity.domain.HostDO;
import org.dromara.visor.module.asset.entity.dto.host.HostAgentLogDTO;
import org.dromara.visor.module.asset.entity.dto.host.HostBaseDTO;
import org.dromara.visor.module.asset.service.HostAgentService;
import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
@@ -55,9 +59,9 @@ import java.util.stream.Collectors;
@Service
public class HostAgentApiImpl implements HostAgentApi {
private static final TimedCache AGENT_NAME_CACHE = TimedCacheBuilder.create()
.expiredDelay(Const.MS_S_60 * 30)
.checkDelay(Const.MS_S_60)
private static final TimedCache<HostBaseDTO> AGENT_HOST_CACHE = TimedCacheBuilder.<HostBaseDTO>create()
.expireAfter(30 * Const.MS_S_60)
.checkInterval(Const.MS_S_60)
.build();
@Resource
@@ -69,6 +73,11 @@ public class HostAgentApiImpl implements HostAgentApi {
@Resource
private HostAgentService hostAgentService;
@PreDestroy
public void destroyTimedCache() {
Streams.close(AGENT_HOST_CACHE);
}
@Override
public List<HostAgentLogDTO> selectAgentInstallLog(List<Long> hostIdList) {
if (Lists.isEmpty(hostIdList)) {
@@ -94,39 +103,67 @@ public class HostAgentApiImpl implements HostAgentApi {
}
@Override
public Map<String, String> getCacheNameByAgentKey(List<String> agentKeyList) {
public Map<String, String> getNameCacheByAgentKey(List<String> agentKeyList) {
Map<String, String> result = new HashMap<>();
List<String> queryList = new ArrayList<>();
// 查询缓存
for (String agentKey : agentKeyList) {
String name = AGENT_NAME_CACHE.get(agentKey);
if (name != null) {
result.put(agentKey, name);
HostBaseDTO host = AGENT_HOST_CACHE.get(agentKey);
if (host != null) {
result.put(agentKey, host.getName());
} else {
queryList.add(agentKey);
}
}
// 查询数据库
if (!queryList.isEmpty()) {
// 查询数据
hostDAO.of()
.createWrapper()
.select(HostDO::getName, HostDO::getAgentKey)
.in(HostDO::getAgentKey, queryList)
.then()
.list()
.forEach(s -> result.put(s.getAgentKey(), s.getName()));
for (String agentKey : queryList) {
result.putIfAbsent(agentKey, Const.EMPTY);
AGENT_NAME_CACHE.put(agentKey, result.get(agentKey));
}
// 加载缓存
this.loadHostCache(queryList);
// 重新设置返回结果
queryList.forEach(agentKey -> {
HostBaseDTO host = AGENT_HOST_CACHE.get(agentKey);
if (host != null) {
result.put(agentKey, host.getName());
}
});
}
return result;
}
@Override
public HostBaseDTO getHostCacheByAgentKey(String agentKey) {
HostBaseDTO host = AGENT_HOST_CACHE.get(agentKey);
// 加载缓存
if (host == null) {
this.loadHostCache(Lists.singleton(agentKey));
host = AGENT_HOST_CACHE.get(agentKey);
}
return host;
}
@Override
public String getAgentVersion() {
return hostAgentService.getAgentVersion();
}
/**
* 加载主机缓存
*
* @param agentKeys agentKeys
*/
private void loadHostCache(List<String> agentKeys) {
// 查询数据并设置缓存
hostDAO.of()
.createWrapper()
.select(HostDO::getId,
HostDO::getName,
HostDO::getCode,
HostDO::getAddress,
HostDO::getAgentKey)
.in(HostDO::getAgentKey, agentKeys)
.then()
.list(HostProviderConvert.MAPPER::toBase)
.forEach(s -> AGENT_HOST_CACHE.put(s.getAgentKey(), s));
}
}

View File

@@ -33,6 +33,7 @@ import org.dromara.visor.module.asset.entity.dto.host.HostDTO;
import org.dromara.visor.module.asset.entity.dto.host.HostQueryDTO;
import org.dromara.visor.module.asset.entity.request.host.HostQueryRequest;
import org.dromara.visor.module.asset.service.HostService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -53,6 +54,7 @@ public class HostApiImpl implements HostApi {
@Resource
private HostDAO hostDAO;
@Lazy
@Resource
private HostService hostService;

View File

@@ -25,6 +25,7 @@ package org.dromara.visor.module.asset.service.impl;
import cn.orionsec.kit.lang.utils.Booleans;
import cn.orionsec.kit.lang.utils.Valid;
import cn.orionsec.kit.lang.utils.collect.Lists;
import cn.orionsec.kit.spring.SpringHolder;
import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const;
import org.dromara.visor.common.constant.ErrorMessage;
@@ -32,6 +33,7 @@ import org.dromara.visor.module.asset.dao.HostAgentLogDAO;
import org.dromara.visor.module.asset.dao.HostDAO;
import org.dromara.visor.module.asset.entity.domain.HostAgentLogDO;
import org.dromara.visor.module.asset.entity.domain.HostDO;
import org.dromara.visor.module.asset.entity.event.AgentOfflineEvent;
import org.dromara.visor.module.asset.entity.vo.HostOnlineAgentConfigVO;
import org.dromara.visor.module.asset.enums.AgentInstallStatusEnum;
import org.dromara.visor.module.asset.enums.AgentLogStatusEnum;
@@ -41,7 +43,6 @@ import org.dromara.visor.module.asset.handler.host.extra.HostExtraItemEnum;
import org.dromara.visor.module.asset.handler.host.extra.model.HostSpecExtraModel;
import org.dromara.visor.module.asset.service.HostAgentEndpointService;
import org.dromara.visor.module.asset.service.HostExtraService;
import org.dromara.visor.module.monitor.api.MonitorHostApi;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@@ -83,14 +84,12 @@ public class HostAgentEndpointServiceImpl implements HostAgentEndpointService {
@Resource
private HostExtraService hostExtraService;
@Resource
private MonitorHostApi monitorHostApi;
/**
* 初始化主机在线状态
*/
@PostConstruct
public void initHostOnlineStatus() {
log.info("HostAgentEndpointService-initHostOnlineStatus start.");
List<HostDO> hosts = hostDAO.selectList(null);
for (HostDO host : hosts) {
Integer agentOnlineStatus = host.getAgentOnlineStatus();
@@ -98,6 +97,7 @@ public class HostAgentEndpointServiceImpl implements HostAgentEndpointService {
ONLINE_STATUS_CACHE.put(host.getAgentKey(), agentOnlineStatus);
}
}
log.info("HostAgentEndpointService-initHostOnlineStatus end.");
}
@Override
@@ -167,8 +167,8 @@ public class HostAgentEndpointServiceImpl implements HostAgentEndpointService {
.status(AgentLogStatusEnum.SUCCESS.name())
.build();
hostAgentLogDAO.insert(agentLog);
// 设置监控上下文为已下线
monitorHostApi.setAgentOffline(Lists.singleton(agentKey));
// 发送已下线事件
SpringHolder.publishEvent(new AgentOfflineEvent(agentKey));
}
@Override
@@ -248,9 +248,9 @@ public class HostAgentEndpointServiceImpl implements HostAgentEndpointService {
if (!logList.isEmpty()) {
hostAgentLogDAO.insertBatch(logList);
}
// 设置监控上下文为已下线
// 发送已下线事件
if (AgentOnlineStatusEnum.OFFLINE.equals(status)) {
monitorHostApi.setAgentOffline(agentKeyList);
SpringHolder.publishEvent(new AgentOfflineEvent(agentKeyList));
}
}