feat:数据库统计 fix:bugs

This commit is contained in:
nieziyan 2023-11-30 19:44:51 +08:00
parent 5f4d2f1d41
commit ccf4d796ef
14 changed files with 119 additions and 54 deletions

View File

@ -1,9 +1,11 @@
package org.jeecg.common.util; package org.jeecg.common.util;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
@ -18,7 +20,11 @@ public class JDBCUtil {
dataSource.setDriverClassName(driver); dataSource.setDriverClassName(driver);
dataSource.setUsername(user); dataSource.setUsername(user);
dataSource.setPassword(pass); dataSource.setPassword(pass);
return new JdbcTemplate(dataSource); // 测试数据源是否可以连接成功
boolean connection = isConnection(dataSource);
if (connection)
return new JdbcTemplate(dataSource);
return null;
} }
public static boolean isConnection(String url, String driver, String user, String pass){ public static boolean isConnection(String url, String driver, String user, String pass){
@ -35,4 +41,16 @@ public class JDBCUtil {
return false; return false;
} }
} }
public static boolean isConnection(DriverManagerDataSource dataSource){
// try-with-resources 无须显式关闭Connection资源
try (Connection connection = dataSource.getConnection()) {
return true;
} catch (SQLException e) {
String url = "--";
if (ObjectUtil.isNotNull(dataSource)) url = dataSource.getUrl();
log.error("JDBCUtil.isConnection():数据源["+ url +"]连接失败: {}", e.getMessage());
return false;
}
}
} }

View File

@ -15,7 +15,9 @@ public class ServerDto implements Serializable {
private String hostId; private String hostId;
private boolean online; private boolean online; // 旧状态值 弃用
private String status; // 新状态值
private String serverInfo; private String serverInfo;

View File

@ -41,7 +41,6 @@ public class EmailStatusManager {
while (true){ while (true){
try { try {
emailService.status2Redis(); emailService.status2Redis();
TimeUnit.MILLISECONDS.sleep(sleepTime);
} catch (Exception e) { } catch (Exception e) {
log.error("EmailStatusManager.run()异常: {}", e.getMessage()); log.error("EmailStatusManager.run()异常: {}", e.getMessage());
}finally { }finally {

View File

@ -3,6 +3,7 @@ package org.jeecg.modules;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.SpringContextUtils; import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.modules.service.ISysDatabaseService; import org.jeecg.modules.service.ISysDatabaseService;
import org.jeecg.modules.service.ISysServerService;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -20,6 +21,8 @@ public class ServerStatusManager {
private long sleepTime; private long sleepTime;
private ISysServerService serverService;
private ServerStatusThread(){ private ServerStatusThread(){
init(); init();
} }
@ -28,7 +31,7 @@ public class ServerStatusManager {
public void run() { public void run() {
while (true) { while (true) {
try { try {
serverService.status2Redis();
} catch (Exception e) { } catch (Exception e) {
log.error("ServerStatusManager.run()异常: {}", e.getMessage()); log.error("ServerStatusManager.run()异常: {}", e.getMessage());
}finally { }finally {
@ -43,6 +46,7 @@ public class ServerStatusManager {
private void init(){ private void init(){
sleepTime = 30 * 60 * 1000; // 睡眠时间30min sleepTime = 30 * 60 * 1000; // 睡眠时间30min
serverService = SpringContextUtils.getBean(ISysServerService.class);
} }
} }
} }

View File

@ -29,8 +29,8 @@ public class AlarmItemController extends JeecgController<AlarmItem, IAlarmItemSe
@GetMapping("alarmItems") @GetMapping("alarmItems")
@ApiOperation(value = "服务器所有监控项",notes = "服务器所有监控项") @ApiOperation(value = "服务器所有监控项",notes = "服务器所有监控项")
public Result<?> alarmItems(@RequestParam String hostId){ public Result<?> alarmItems(@RequestParam String sourceId){
List<AlarmItem> alarmItems = service.alarmItems(hostId); List<AlarmItem> alarmItems = service.alarmItems(sourceId);
Map<String, String> itemIds = alarmItems.stream() Map<String, String> itemIds = alarmItems.stream()
.collect(Collectors.toMap(AlarmItem::getName, AlarmItem::getId)); .collect(Collectors.toMap(AlarmItem::getName, AlarmItem::getId));
return Result.OK(itemIds); return Result.OK(itemIds);

View File

@ -0,0 +1,22 @@
package org.jeecg.modules.exceptionhandler;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.controller.SystemMonitorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice(assignableTypes = SystemMonitorController.class)
@Slf4j
public class MonitorExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<Result<?>> handleException(Exception e) {
log.error("运管服务调用异常: {}", e.getMessage());
return ResponseEntity.status(HttpStatus.OK)
.body(Result.error("Management system is abnormal, data cannot be displayed"));
}
}

View File

@ -3,6 +3,9 @@ package org.jeecg.modules.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.base.entity.postgre.AlarmItem; import org.jeecg.modules.base.entity.postgre.AlarmItem;
import java.util.List;
public interface AlarmItemMapper extends BaseMapper<AlarmItem> { public interface AlarmItemMapper extends BaseMapper<AlarmItem> {
List<AlarmItem> alarmItems(String sourceId);
} }

View File

@ -2,4 +2,12 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.mapper.AlarmItemMapper"> <mapper namespace="org.jeecg.modules.mapper.AlarmItemMapper">
<select id="alarmItems" resultType="org.jeecg.modules.base.entity.postgre.AlarmItem">
SELECT
i.*
FROM
alarm_item i
INNER JOIN sys_server s ON i.host_id = s.host_id
WHERE s.ID = #{sourceId}
</select>
</mapper> </mapper>

View File

@ -50,7 +50,7 @@
i.id AS cpuUsedItemId i.id AS cpuUsedItemId
FROM FROM
sys_server s sys_server s
LEFT JOIN alarm_item i ON s.ID = i.source_id AND i.NAME = #{itemName} LEFT JOIN alarm_item i ON s.host_id = i.host_id AND i.NAME = #{itemName}
ORDER BY ORDER BY
s.status DESC, s.status DESC,
s.NAME ASC s.NAME ASC

View File

@ -10,7 +10,7 @@ import java.util.List;
public interface IAlarmItemService extends IService<AlarmItem> { public interface IAlarmItemService extends IService<AlarmItem> {
boolean syncServerItem(); boolean syncServerItem();
List<AlarmItem> alarmItems(String hostId); List<AlarmItem> alarmItems(String sourceId);
List<ItemDto> allItems(String sourceType, String sourceId); List<ItemDto> allItems(String sourceType, String sourceId);
} }

View File

@ -94,23 +94,21 @@ public class AlarmItemServiceImpl extends ServiceImpl<AlarmItemMapper, AlarmItem
@Transactional @Transactional
public boolean syncServerItem() { public boolean syncServerItem() {
try { try {
// 获取所有监控服务器信息(不包括数据库服务)
List<Host> hosts = monitorAlarm.listApp(MonitorConstant.SERVER_APP).getResult().getRecords();
// 获取所有服务器信息 // 获取所有服务器信息
List<SysServer> servers = serverService.list(); List<SysServer> servers = serverService.list();
List<String> hostIds = servers.stream().map(SysServer::getHostId).filter(StrUtil::isNotBlank) List<String> hostIds = servers.stream().map(SysServer::getHostId).filter(StrUtil::isNotBlank)
.collect(Collectors.toList()); .collect(Collectors.toList());
// 获取所有监控服务器信息(不包括数据库服务) // 收集监控服务器列表中当前系统录入的服务器 并将收集所有监控项
List<Host> hosts = monitorAlarm.listApp(MonitorConstant.SERVER_APP).getResult().getRecords(); List<Item> items = hosts.stream().filter(host -> CollUtil.contains(hostIds, host.getHostId()))
// 收集监控服务器列表中当前系统录入的服务器 .flatMap(host -> host.getItems().values().stream())
hosts = hosts.stream().filter(host -> CollUtil.contains(hostIds, host.getHostId()))
.collect(Collectors.toList()); .collect(Collectors.toList());
List<AlarmItem> alarmItems = new ArrayList<>(); List<AlarmItem> alarmItems = new ArrayList<>();
for (Host host : hosts) { for (Item item : items) {
List<Item> items = ListUtil.toList(host.getItems().values()); AlarmItem alarmItem = BeanUtil.copyProperties(item, AlarmItem.class);
for (Item item : items) { alarmItem.setId(item.getItemId());
AlarmItem alarmItem = BeanUtil.copyProperties(item, AlarmItem.class); alarmItems.add(alarmItem);
alarmItem.setId(item.getItemId());
alarmItems.add(alarmItem);
}
} }
return saveOrUpdateBatch(alarmItems); return saveOrUpdateBatch(alarmItems);
}catch (Exception e){ }catch (Exception e){
@ -120,17 +118,13 @@ public class AlarmItemServiceImpl extends ServiceImpl<AlarmItemMapper, AlarmItem
} }
/** /**
* @param hostId * @param sourceId
* *
* 返回指定服务器的所有监控项 * 返回指定服务器的所有监控项
*/ */
@Override @Override
public List<AlarmItem> alarmItems(String hostId) { public List<AlarmItem> alarmItems(String sourceId) {
if (StrUtil.isBlank(hostId)) return baseMapper.alarmItems(sourceId);
return new ArrayList<>();
LambdaQueryWrapper<AlarmItem> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(AlarmItem::getHostId, hostId);
return list(wrapper);
} }
/* /*

View File

@ -228,6 +228,7 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
String dbPassword = sysDatabase.getDbPassword(); String dbPassword = sysDatabase.getDbPassword();
String dbType = sysDatabase.getDbType(); String dbType = sysDatabase.getDbType();
JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword); JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword);
if(ObjectUtil.isNull(template)) return dbNames;
DbType dbTypeE = DbType.typeOf(dbType); DbType dbTypeE = DbType.typeOf(dbType);
if (ObjectUtil.isNull(dbTypeE)) if (ObjectUtil.isNull(dbTypeE))
return dbNames; return dbNames;
@ -263,6 +264,7 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
String dbType = sysDatabase.getDbType(); String dbType = sysDatabase.getDbType();
DBRowMapper dbRowMapper = new DBRowMapper(); DBRowMapper dbRowMapper = new DBRowMapper();
JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword); JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword);
if(ObjectUtil.isNull(template)) return dbInfos;
DbType dbTypeE = DbType.typeOf(dbType); DbType dbTypeE = DbType.typeOf(dbType);
if (ObjectUtil.isNull(dbTypeE)) if (ObjectUtil.isNull(dbTypeE))
return dbInfos; return dbInfos;
@ -299,6 +301,7 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
String dbPassword = sysDatabase.getDbPassword(); String dbPassword = sysDatabase.getDbPassword();
RowMapper<SpaceInfo> mapper = new SpaceRowMapper(); RowMapper<SpaceInfo> mapper = new SpaceRowMapper();
JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword); JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword);
if(ObjectUtil.isNull(template)) return spaceInfos;
spaceInfos = template.query(DBSQL.SPACE_OR, mapper); spaceInfos = template.query(DBSQL.SPACE_OR, mapper);
} }
return spaceInfos; return spaceInfos;
@ -334,9 +337,11 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
if (StrUtil.contains(dbUrl, dbNameOld)) if (StrUtil.contains(dbUrl, dbNameOld))
dbUrl = StrUtil.replace(dbUrl, dbNameOld, dbName); dbUrl = StrUtil.replace(dbUrl, dbNameOld, dbName);
} }
List<DBInfo> dbInfos = new ArrayList<>();
JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword); JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword);
if(ObjectUtil.isNull(template)) return dbInfos;
// 查询当前所连接的数据库的表信息 // 查询当前所连接的数据库的表信息
List<DBInfo> dbInfos = template.query(DBSQL.DBINFO_PG, mapper); dbInfos = template.query(DBSQL.DBINFO_PG, mapper);
List<DBInfo> dbRowNum = template.query(DBSQL.DBROWNUM_PG, mapper); List<DBInfo> dbRowNum = template.query(DBSQL.DBROWNUM_PG, mapper);
Map<String, Integer> rowNum = dbRowNum.stream() Map<String, Integer> rowNum = dbRowNum.stream()
.collect(Collectors.toMap(DBInfo::getTableName, DBInfo::getNumRow)); .collect(Collectors.toMap(DBInfo::getTableName, DBInfo::getNumRow));

View File

@ -80,29 +80,35 @@ public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer
}catch (Exception e){ }catch (Exception e){
log.error("向运管系统查询Hosts信息异常: {}", e.getMessage()); log.error("向运管系统查询Hosts信息异常: {}", e.getMessage());
} }
// 将List<Host>转换为Map<hostId,Host>
Map<String, Host> hostMap = hosts.stream().collect(Collectors.toMap(Host::getHostId, Host -> Host));
// 获取服务器状态信息
Map<Object, Object> statusMap = redisUtil.hmget(RedisConstant.SERVER_STATUS);
for (ServerDto serverDto : serverDtos) { for (ServerDto serverDto : serverDtos) {
int alarms = serverDto.getAlarms(); int alarms = serverDto.getAlarms();
String hostIdS = serverDto.getHostId(); String id = serverDto.getId();
String hostId = serverDto.getHostId();
serverDto.setAlarmRed(alarms > 0); serverDto.setAlarmRed(alarms > 0);
for (Host host : hosts) { // 设置服务器状态信息
String hostId = host.getHostId(); serverDto.setStatus((String) statusMap.getOrDefault(id, ServerStatus.UNKNOWN.getValue()));
if (!StrUtil.equals(hostIdS, hostId)) continue; // 设置服务器的硬件使用情况信息
Host host = hostMap.get(hostId);
Map<String, Item> items = host.getItems(); if (ObjectUtil.isNull(host))
// cpu利用率 continue;
Item cpuItem = items.getOrDefault(MonitorConstant.ITEM_CPUUSED, new Item()); Map<String, Item> items = host.getItems();
String cpuValue = cpuItem.getLastValue(); // cpu利用率
String cpu = StrUtil.isBlank(cpuValue) ? "--" : Item cpuItem = items.getOrDefault(MonitorConstant.ITEM_CPUUSED, new Item());
NumberUtil.formatPercent(Double.parseDouble(cpuValue), 1); String cpuValue = cpuItem.getLastValue();
// 内存使用率 String cpu = StrUtil.isBlank(cpuValue) ? "--" :
Item memoryItem = items.getOrDefault(MonitorConstant.ITEM_MEMORYUSED, new Item()); NumberUtil.formatPercent(Double.parseDouble(cpuValue), 1);
String memoryValue = memoryItem.getLastValue(); // 内存使用率
String memory = StrUtil.isBlank(memoryValue) ? "--" : Item memoryItem = items.getOrDefault(MonitorConstant.ITEM_MEMORYUSED, new Item());
NumUtil.keepStr(memoryValue, 1) + "%"; String memoryValue = memoryItem.getLastValue();
// 磁盘使用率 String memory = StrUtil.isBlank(memoryValue) ? "--" :
serverDto.setOnline(true).setCpuUutilzation(cpu) NumUtil.keepStr(memoryValue, 1) + "%";
.setMemoryUsage(memory).setDiskUsage("--"); // 磁盘使用率
} serverDto.setOnline(true).setCpuUutilzation(cpu)
.setMemoryUsage(memory).setDiskUsage("--");
} }
// 统计Alarm总数 // 统计Alarm总数
// int alarms = noPage.stream().mapToInt(ServerDto::getAlarms).sum(); // int alarms = noPage.stream().mapToInt(ServerDto::getAlarms).sum();
@ -300,16 +306,15 @@ public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer
String key = RedisConstant.SERVER_STATUS; String key = RedisConstant.SERVER_STATUS;
Map<String, Object> values = new HashMap<>(); Map<String, Object> values = new HashMap<>();
try { try {
Servers servers = monitorAlarm.listApp(MonitorConstant.SERVER_APP).getResult(); List<Host> hosts = monitorAlarm.listApp(MonitorConstant.SERVER_APP).getResult().getRecords();
List<Host> hosts = servers.getRecords(); Map<String, Host> hostMap = hosts.stream().collect(Collectors.toMap(Host::getHostId, Host -> Host));
for (SysServer server : sysServers) { for (SysServer server : sysServers) {
String hostId = server.getHostId(); String hostId = server.getHostId();
String serverId = server.getId(); String serverId = server.getId();
Optional<Host> first = hosts.stream().filter(item -> StrUtil.equals(hostId, item.getHostId())).findFirst(); Host host = hostMap.get(hostId);
// 如果当前服务器在监控服务器列表 则获取该服务器的状态并保存 // 获取该服务器的状态并保存
if (first.isPresent()) { if (ObjectUtil.isNotNull(host)) {
String status = first.get().getStatus(); values.put(serverId, host.getStatus());
values.put(serverId, status);
continue; continue;
} }
// 当前服务器不在监控服务器列表 将它的状态设置为未知 // 当前服务器不在监控服务器列表 将它的状态设置为未知

View File

@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.oConvertUtils; import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.DatabaseStatusManager; import org.jeecg.modules.DatabaseStatusManager;
import org.jeecg.modules.EmailStatusManager; import org.jeecg.modules.EmailStatusManager;
import org.jeecg.modules.ServerStatusManager;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -25,6 +26,8 @@ import java.net.UnknownHostException;
@RequiredArgsConstructor @RequiredArgsConstructor
public class JeecgAbnormalAlarmApplication extends SpringBootServletInitializer implements CommandLineRunner { public class JeecgAbnormalAlarmApplication extends SpringBootServletInitializer implements CommandLineRunner {
private final ServerStatusManager serverStatusManager;
private final EmailStatusManager emailStatusManager; private final EmailStatusManager emailStatusManager;
private final DatabaseStatusManager databaseStatusManager; private final DatabaseStatusManager databaseStatusManager;
@ -54,6 +57,8 @@ public class JeecgAbnormalAlarmApplication extends SpringBootServletInitializer
databaseStatusManager.start(); databaseStatusManager.start();
// 启动监测邮箱服务器连接状态的线程 // 启动监测邮箱服务器连接状态的线程
emailStatusManager.start(); emailStatusManager.start();
// 启动监测服务器连接状态的线程
serverStatusManager.start();
} }
} }