fix:优化状态监控,新增服务器状态监控

This commit is contained in:
nieziyan 2023-11-29 19:10:10 +08:00
parent ba40f06460
commit 5f4d2f1d41
19 changed files with 240 additions and 71 deletions

View File

@ -2,11 +2,6 @@ package org.jeecg.common.constant;
public interface MonitorConstant {
//设备状态 1 正常 2 离线 3 告警
String STATUS_ON = "1";
String STATUS_OFF = "2";
String STATUS_WARN = "3";
// 监控项名称
String ITEM_CPUUSED = "cpuUtilization";
String ITEM_SWAPUSED = "swapUtilization";

View File

@ -27,11 +27,11 @@ public interface RedisConstant {
String NUCLIDE_LINES_LIB = "Nuclide_Lines_Lib:";
String PREFIX_STATUS = "Status:";
String DATABASE_STATUS = "Status:Database_Status";
String DATABASE_STATUS = "Database_Status";
String EMAIL_STATUS = "Status:Email_Status";
String EMAIL_STATUS = "Email_Status";
String SERVER_STATUS = "Status:Server_Status";
String EMAIL_SENDER = "Email_Sender";
}

View File

@ -18,6 +18,6 @@ public class AlarmItem extends JeecgEntity {
@TableField("description")
private String description;
@TableField("source_id")
private String sourceId;
@TableField("host_id")
private String hostId;
}

View File

@ -22,7 +22,7 @@ public class SysServer extends JeecgEntity implements Serializable {
private String name;
/**
* 状态0-停机1-正常2-故障
* 状态(-1未知 1正常 2离线 3告警)
*/
@TableField(value = "status")
private Integer status;

View File

@ -0,0 +1,23 @@
package org.jeecg.modules.base.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ServerStatus {
UNKNOWN("-1", "未知"),ON("1","在线"),OFF("2","离线"),WARN("3","告警");
private String value;
private String desc;
public static ServerStatus statusOf(String value){
for (ServerStatus status : ServerStatus.values()) {
if (status.getValue().equals(value))
return status;
}
return null;
}
}

View File

@ -35,12 +35,17 @@ public class DatabaseStatusManager {
@Override
public void run() {
while (true){
while (true) {
try {
databaseService.status2Redis();
TimeUnit.MILLISECONDS.sleep(sleepTime);
} catch (Exception e) {
log.error("DatabaseStatusManager.run()异常: {}", e.getMessage());
}finally {
try {
TimeUnit.MILLISECONDS.sleep(sleepTime);
} catch (InterruptedException e) {
log.error("DatabaseStatusManager.sleep()异常: {}", e.getMessage());
}
}
}
}

View File

@ -44,6 +44,12 @@ public class EmailStatusManager {
TimeUnit.MILLISECONDS.sleep(sleepTime);
} catch (Exception e) {
log.error("EmailStatusManager.run()异常: {}", e.getMessage());
}finally {
try {
TimeUnit.MILLISECONDS.sleep(sleepTime);
} catch (InterruptedException e) {
log.error("EmailStatusManager.sleep()异常: {}", e.getMessage());
}
}
}
}

View File

@ -0,0 +1,48 @@
package org.jeecg.modules;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.modules.service.ISysDatabaseService;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
public class ServerStatusManager {
public void start() {
ServerStatusThread serverStatusThread = new ServerStatusThread();
serverStatusThread.start();
}
private static class ServerStatusThread extends Thread{
private long sleepTime;
private ServerStatusThread(){
init();
}
@Override
public void run() {
while (true) {
try {
} catch (Exception e) {
log.error("ServerStatusManager.run()异常: {}", e.getMessage());
}finally {
try {
TimeUnit.MILLISECONDS.sleep(sleepTime);
} catch (InterruptedException e) {
log.error("ServerStatusManager.sleep()异常: {}", e.getMessage());
}
}
}
}
private void init(){
sleepTime = 30 * 60 * 1000; // 睡眠时间30min
}
}
}

View File

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

View File

@ -7,7 +7,6 @@ import org.jeecg.modules.base.dto.ItemDto;
import org.jeecg.modules.base.entity.postgre.AlarmItem;
import org.jeecg.modules.base.entity.postgre.AlarmRule;
import org.jeecg.modules.base.bizVo.AlarmRuleVo;
import org.jeecg.modules.feignclient.MonitorAlarm;
import org.jeecg.modules.service.IAlarmItemService;
import org.jeecg.modules.service.IAlarmRuleService;
import org.springframework.beans.factory.annotation.Autowired;
@ -21,9 +20,6 @@ import java.util.stream.Collectors;
@Api(value = "报警规则管理", tags = "报警规则管理")
public class AlarmRuleController {
@Autowired
private MonitorAlarm monitorAlarm;
@Autowired
private IAlarmRuleService alarmRuleService;

View File

@ -30,9 +30,7 @@ public class SysEmailLogController {
@GetMapping("status")
@ApiOperation("邮箱服务器状态")
public Result<?> status(@RequestParam("emailId") String emailId){
String prefixStatus = RedisConstant.PREFIX_STATUS;
String emailStatus = RedisConstant.EMAIL_STATUS;
String statusKey = prefixStatus + emailStatus;
String statusKey = RedisConstant.EMAIL_STATUS;
Boolean emailSatus = (Boolean) redisUtil.hget(statusKey, emailId);
return Result.OK(ObjectUtil.isNotNull(emailSatus) && emailSatus);
}

View File

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

View File

@ -33,4 +33,6 @@ public interface ISysServerService extends IService<SysServer> {
Result<?> details_BasicInfo(String hostId);
Result<?> details_AlarmInfo(String sourceId, Integer pageNo, Integer pageSize);
void status2Redis();
}

View File

@ -7,6 +7,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.MonitorConstant;
import org.jeecg.common.constant.Prompt;
@ -40,6 +41,7 @@ import static org.jeecg.modules.base.enums.SourceType.SERVER;
@Service
@Slf4j
public class AlarmItemServiceImpl extends ServiceImpl<AlarmItemMapper, AlarmItem> implements IAlarmItemService {
@Autowired
@ -54,7 +56,7 @@ public class AlarmItemServiceImpl extends ServiceImpl<AlarmItemMapper, AlarmItem
/**
* 同步所有服务器监控项信息
*/
@Transactional
/*@Transactional
public boolean syncServerItem() {
try {
// 获取所有服务器信息(不包括数据库服务)
@ -62,12 +64,12 @@ public class AlarmItemServiceImpl extends ServiceImpl<AlarmItemMapper, AlarmItem
// 获取所有服务器信息
List<SysServer> servers = serverService.list();
for (SysServer server : servers) {
String name = server.getName();
String ipAddress = server.getIpAddress();
String serverId = server.getId();
// 批量保存服务器对应的监控项信息
for (Host host : hosts) {
String code = host.getCode();
if (!StrUtil.equals(name, code))
if (!StrUtil.equals(ipAddress, code))
continue;
server.setHostId(host.getHostId());
List<Item> items = ListUtil.toList(host.getItems().values());
@ -84,22 +86,50 @@ public class AlarmItemServiceImpl extends ServiceImpl<AlarmItemMapper, AlarmItem
// 添加或更新SysServer的HostId
return serverService.updateBatchById(servers);
}catch (Exception e){
e.printStackTrace();
log.error("向运管系统同步Server监控项信息异常: {}", e.getMessage());
return false;
}
}*/
@Transactional
public boolean syncServerItem() {
try {
// 获取所有服务器信息
List<SysServer> servers = serverService.list();
List<String> hostIds = servers.stream().map(SysServer::getHostId).filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
// 获取所有监控服务器信息(不包括数据库服务)
List<Host> hosts = monitorAlarm.listApp(MonitorConstant.SERVER_APP).getResult().getRecords();
// 收集监控服务器列表中当前系统录入的服务器
hosts = hosts.stream().filter(host -> CollUtil.contains(hostIds, host.getHostId()))
.collect(Collectors.toList());
List<AlarmItem> alarmItems = new ArrayList<>();
for (Host host : hosts) {
List<Item> items = ListUtil.toList(host.getItems().values());
for (Item item : items) {
AlarmItem alarmItem = BeanUtil.copyProperties(item, AlarmItem.class);
alarmItem.setId(item.getItemId());
alarmItems.add(alarmItem);
}
}
return saveOrUpdateBatch(alarmItems);
}catch (Exception e){
log.error("向运管系统同步Server监控项信息异常: {}", e.getMessage());
return false;
}
}
/**
* @param sourceId
* @param hostId
*
* 返回指定服务器的所有监控项
*/
@Override
public List<AlarmItem> alarmItems(String sourceId) {
if (StrUtil.isBlank(sourceId))
public List<AlarmItem> alarmItems(String hostId) {
if (StrUtil.isBlank(hostId))
return new ArrayList<>();
LambdaQueryWrapper<AlarmItem> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(AlarmItem::getSourceId,sourceId);
wrapper.eq(AlarmItem::getHostId, hostId);
return list(wrapper);
}

View File

@ -69,9 +69,7 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
Map<String, String> dataSourceMap = items.stream().collect(Collectors
.toMap(DictModel::getValue, DictModel::getText, (oldValue, newValue) -> newValue));
// 数据库连接状态Map key:id value:状态值(true|false)
String prefixStatus = RedisConstant.PREFIX_STATUS;
String databaseStatus = RedisConstant.DATABASE_STATUS;
String statusKey = prefixStatus + databaseStatus;
String statusKey = RedisConstant.DATABASE_STATUS;
Map<Object, Object> statusMap = redisUtil.hmget(statusKey);
for (DatabaseDto databaseDto : databaseDtos) {
String id = databaseDto.getId();
@ -321,9 +319,7 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
statusMap.put(id, isConn);
}
// 将数据源连接状态更新到reids
String prefixStatus = RedisConstant.PREFIX_STATUS;
String databaseStatus = RedisConstant.DATABASE_STATUS;
String statusKey = prefixStatus + databaseStatus;
String statusKey = RedisConstant.DATABASE_STATUS;
redisUtil.hmset(statusKey, statusMap);
}
@ -394,9 +390,7 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
String dbUsername = database.getDbUsername();
String dbPassword = database.getDbPassword();
boolean isConn = JDBCUtil.isConnection(dbUrl, dbDriver, dbUsername, dbPassword);
String prefixStatus = RedisConstant.PREFIX_STATUS;
String databaseStatus = RedisConstant.DATABASE_STATUS;
String statusKey = prefixStatus + databaseStatus;
String statusKey = RedisConstant.DATABASE_STATUS;
redisUtil.hset(statusKey, id, isConn);
}
@ -404,9 +398,7 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
* 删除指定id的数据源的状态值
* */
private void delStatus(String databaseId){
String prefixStatus = RedisConstant.PREFIX_STATUS;
String databaseStatus = RedisConstant.DATABASE_STATUS;
String statusKey = prefixStatus + databaseStatus;
String statusKey = RedisConstant.DATABASE_STATUS;
if(redisUtil.hHasKey(statusKey, databaseId))
redisUtil.hdel(statusKey, databaseId);
}

View File

@ -84,9 +84,7 @@ public class SysEmailServiceImpl extends ServiceImpl<SysEmailMapper, SysEmail> i
Map<String, Integer> weekMap = baseMapper.counts(emailIds, weekStart, todayEnd)
.stream().collect(Collectors.toMap(IdCount::getId, IdCount::getCount));
// 邮箱状态Map key:id value:状态(true|false)
String prefixStatus = RedisConstant.PREFIX_STATUS;
String emailStatus = RedisConstant.EMAIL_STATUS;
String statusKey = prefixStatus + emailStatus;
String statusKey = RedisConstant.EMAIL_STATUS;
Map<Object, Object> statusMap = redisUtil.hmget(statusKey);
// 查询是否有企业邮箱
List<Integer> hasQieye = emailDtos.stream().map(EmailDto::getIsQiye)
@ -248,9 +246,7 @@ public class SysEmailServiceImpl extends ServiceImpl<SysEmailMapper, SysEmail> i
statusMap.put(id, isConn);
}
// 将邮箱服务器连接状态更新到reids
String prefixStatus = RedisConstant.PREFIX_STATUS;
String emailStatus = RedisConstant.EMAIL_STATUS;
String statusKey = prefixStatus + emailStatus;
String statusKey = RedisConstant.EMAIL_STATUS;
redisUtil.hmset(statusKey, statusMap);
}
@ -260,9 +256,7 @@ public class SysEmailServiceImpl extends ServiceImpl<SysEmailMapper, SysEmail> i
private void saveOrUpdateStatus(SysEmail email){
String id = email.getId();
boolean isConn = EmailUtil.isConnection(email);
String prefixStatus = RedisConstant.PREFIX_STATUS;
String emailStatus = RedisConstant.EMAIL_STATUS;
String statusKey = prefixStatus + emailStatus;
String statusKey = RedisConstant.EMAIL_STATUS;
redisUtil.hset(statusKey, id, isConn);
}
@ -270,9 +264,7 @@ public class SysEmailServiceImpl extends ServiceImpl<SysEmailMapper, SysEmail> i
* 删除指定id的邮箱服务器的状态值
* */
private void delStatus(String emailId){
String prefixStatus = RedisConstant.PREFIX_STATUS;
String emailStatus = RedisConstant.EMAIL_STATUS;
String statusKey = prefixStatus + emailStatus;
String statusKey = RedisConstant.EMAIL_STATUS;
if(redisUtil.hHasKey(statusKey, emailId))
redisUtil.hdel(statusKey, emailId);
}

View File

@ -17,16 +17,21 @@ import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.DateConstant;
import org.jeecg.common.constant.MonitorConstant;
import org.jeecg.common.constant.Prompt;
import org.jeecg.common.constant.RedisConstant;
import org.jeecg.common.util.NumUtil;
import org.jeecg.common.util.PageUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.ServerStatusManager;
import org.jeecg.modules.base.dto.AlarmInfo;
import org.jeecg.modules.base.dto.BasicInfo;
import org.jeecg.modules.base.dto.ServerDto;
import org.jeecg.modules.base.dto.SourceDto;
import org.jeecg.modules.base.entity.monitor.Host;
import org.jeecg.modules.base.entity.monitor.Item;
import org.jeecg.modules.base.entity.monitor.Servers;
import org.jeecg.modules.base.entity.postgre.SysServer;
import org.jeecg.modules.base.bizVo.SourceVo;
import org.jeecg.modules.base.enums.ServerStatus;
import org.jeecg.modules.entity.AlarmHistory;
import org.jeecg.modules.feignclient.MonitorAlarm;
import org.jeecg.modules.mapper.SysServerMapper;
@ -39,12 +44,16 @@ import javax.naming.directory.ModificationItem;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Service("sysServerService")
@Slf4j
public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer> implements ISysServerService {
@Autowired
private RedisUtil redisUtil;
@Autowired
private MonitorAlarm monitorAlarm;
@ -66,10 +75,10 @@ public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer
// 获取所有在线服务器信息
List<Host> hosts = new ArrayList<>();
try {
hosts = monitorAlarm.listOnApp(MonitorConstant.STATUS_ON,
hosts = monitorAlarm.listOnApp(ServerStatus.ON.getValue(),
MonitorConstant.SERVER_APP).getResult().getRecords();
}catch (Exception e){
log.error("向运管系统查询Server监控项信息异常: {}", e.getMessage());
log.error("向运管系统查询Hosts信息异常: {}", e.getMessage());
}
for (ServerDto serverDto : serverDtos) {
int alarms = serverDto.getAlarms();
@ -123,8 +132,8 @@ public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer
if (CollUtil.isNotEmpty(list(wrapper)))
return Result.error("IP Address" + Prompt.NOT_REPEAT);
int count = baseMapper.insert(sysServer);
if (count == 1)
boolean success = saveOrUpatedStatus(sysServer);
if (success)
return Result.OK(Prompt.ADD_SUCC);
return Result.error(Prompt.ADD_ERR);
}
@ -149,8 +158,8 @@ public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer
if (CollUtil.isNotEmpty(list(wrapper)))
return Result.error("IP Address" + Prompt.NOT_REPEAT);
}
int count = baseMapper.updateById(sysServer);
if (count == 1)
boolean success = saveOrUpatedStatus(sysServer);
if (success)
return Result.OK(Prompt.UPDATE_SUCC);
return Result.error(Prompt.UPDATE_ERR);
}
@ -159,8 +168,10 @@ public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer
@Transactional
public Result<?> deleteById(String id) {
boolean success = removeById(id);
if(success)
if(success) {
delStatus(id);
return Result.OK(Prompt.DELETE_SUCC);
}
return Result.error(Prompt.DELETE_ERR);
}
@ -183,7 +194,6 @@ public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer
@Override
public List<SourceDto> listAll() {
LambdaQueryWrapper<SysServer> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByDesc(SysServer::getStatus);
wrapper.orderByAsc(SysServer::getName);
List<SourceDto> sourceDtos = new ArrayList<>();
for (SysServer sysServer : list(wrapper)) {
@ -217,13 +227,18 @@ public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer
public Result<?> details_BasicInfo(String hostId) {
if (StrUtil.isBlank(hostId))
return Result.error("HostId" + Prompt.PARAM_REQUIRED);
Host host = monitorAlarm.summary(hostId, MonitorConstant.PAGE_SUMMARY).getResult();
Host host = null;
try {
host = monitorAlarm.summary(hostId, MonitorConstant.PAGE_SUMMARY).getResult();
}catch (Exception e){
log.error("向运管系统查询Host信息异常: {}", e.getMessage());
}
/* BasicInfo */
if (ObjectUtil.isNull(host))
return Result.error("The Host To Be Queried Does Not Exist!");
// 服务器是否在线
String status = host.getStatus();
boolean online = StrUtil.equals(status, MonitorConstant.STATUS_ON);
boolean online = StrUtil.equals(status, ServerStatus.ON.getValue());
Map<String, Item> items = host.getItems();
String runTime = items.get(MonitorConstant.ITEM_RUNTIME).getLastValue();
runTime = StrUtil.isBlank(runTime) ? "--" :
@ -278,4 +293,75 @@ public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer
page = baseMapper.alarmInfo(page, sourceId);
return Result.OK(page);
}
@Override
public void status2Redis() {
List<SysServer> sysServers = this.list();
String key = RedisConstant.SERVER_STATUS;
Map<String, Object> values = new HashMap<>();
try {
Servers servers = monitorAlarm.listApp(MonitorConstant.SERVER_APP).getResult();
List<Host> hosts = servers.getRecords();
for (SysServer server : sysServers) {
String hostId = server.getHostId();
String serverId = server.getId();
Optional<Host> first = hosts.stream().filter(item -> StrUtil.equals(hostId, item.getHostId())).findFirst();
// 如果当前服务器在监控服务器列表 则获取该服务器的状态并保存
if (first.isPresent()) {
String status = first.get().getStatus();
values.put(serverId, status);
continue;
}
// 当前服务器不在监控服务器列表 将它的状态设置为未知
values.put(serverId, ServerStatus.UNKNOWN.getValue());
}
redisUtil.hmset(key, values);
}catch (Exception e){
defaultStatus(sysServers);
log.error("向运管系统查询Hosts信息异常: {}", e.getMessage());
}
}
private void defaultStatus(List<SysServer> sysServers){
String key = RedisConstant.SERVER_STATUS;
Map<String, Object> values = new HashMap<>();
for (SysServer sysServer : sysServers) {
String id = sysServer.getId();
values.put(id, ServerStatus.UNKNOWN.getValue());
}
redisUtil.hmset(key, values);
}
/*
* 更新服务器的状态(-1未知 1正常 2离线 3告警)和它对应的系统监控的HostId
* */
private boolean saveOrUpatedStatus(SysServer server){
String key = RedisConstant.SERVER_STATUS;
String status = ServerStatus.UNKNOWN.getValue(); // 初始值为-1
try {
String ipAddress = server.getIpAddress();
Servers servers = monitorAlarm.listApp(MonitorConstant.SERVER_APP).getResult();
// 获取所有监控主机信息
List<Host> hosts = servers.getRecords();
for (Host host : hosts) {
String code = host.getCode();
if (!StrUtil.equals(ipAddress, code))
continue;
server.setHostId(host.getHostId());
status = host.getStatus();
}
}catch (Exception e){
log.error("向运管系统查询Hosts信息异常: {}", e.getMessage());
}
boolean success = this.saveOrUpdate(server);
String id = server.getId();
redisUtil.hset(key, id, status);
return success;
}
private void delStatus(String id){
String key = RedisConstant.SERVER_STATUS;
if (redisUtil.hHasKey(key, id))
redisUtil.hdel(key, id);
}
}

View File

@ -129,9 +129,7 @@ public class DatabaseJob extends Monitor implements Job{
* */
private Integer isConnection(String databaseId){
int res = 1;
String prefixStatus = RedisConstant.PREFIX_STATUS;
String databaseStatus = RedisConstant.DATABASE_STATUS;
String statusKey = prefixStatus + databaseStatus;
String statusKey = RedisConstant.DATABASE_STATUS;
Boolean status = (Boolean)getRedisUtil().hget(statusKey, databaseId);
if (ObjectUtil.isNull(status) || !status) res = 0;
return res;

View File

@ -111,9 +111,7 @@ public class EmailJob extends Monitor implements Job{
* */
private Integer isConnection(String emailId){
int res = 1;
String prefixStatus = RedisConstant.PREFIX_STATUS;
String emailStatus = RedisConstant.EMAIL_STATUS;
String statusKey = prefixStatus + emailStatus;
String statusKey = RedisConstant.EMAIL_STATUS;
Boolean status = (Boolean)getRedisUtil().hget(statusKey, emailId);
if (ObjectUtil.isNull(status) || !status) res = 0;
return res;