feat:1.表空间使用率2.Database|Email Monitor

This commit is contained in:
nieziyan 2023-11-20 19:12:32 +08:00
parent 171657a6a2
commit 3b3b61eca5
16 changed files with 204 additions and 16 deletions

View File

@ -22,6 +22,14 @@ public interface DBSQL {
"ON a.owner = d.owner AND a.table_name = d.segment_name " + "ON a.owner = d.owner AND a.table_name = d.segment_name " +
"AND d.segment_type = 'TABLE' WHERE a.owner = '%s' " + "AND d.segment_type = 'TABLE' WHERE a.owner = '%s' " +
"ORDER BY a.table_name"; "ORDER BY a.table_name";
String SPACE_OR = "SELECT a.tablespace_name AS spaceName, total / 1024 / 1024 AS total," +
"Round( free / 1024 / 1024, 2 ) AS free," +
"Round( ( total - free ) / 1024 / 1024, 2 ) AS usage," +
"Round( ( total - free ) / total, 4 ) * 100 AS used " +
"FROM " +
"( SELECT tablespace_name, Sum( bytes ) free FROM DBA_FREE_SPACE GROUP BY tablespace_name ) a," +
"( SELECT tablespace_name, Sum( bytes ) total FROM DBA_DATA_FILES GROUP BY tablespace_name ) b " +
"WHERE a.tablespace_name = b.tablespace_name";
String DBINDEX_OR = "SELECT a.table_name AS tableName, a.num_rows AS numRow," + String DBINDEX_OR = "SELECT a.table_name AS tableName, a.num_rows AS numRow," +
"COALESCE(ROUND((d.bytes / (1024 * 1024)), 2), 0) AS dataSize, " + "COALESCE(ROUND((d.bytes / (1024 * 1024)), 2), 0) AS dataSize, " +
"COALESCE(ROUND((d.bytes / (1024 * 1024)), 2), 0) AS indexSize, " + "COALESCE(ROUND((d.bytes / (1024 * 1024)), 2), 0) AS indexSize, " +

View File

@ -3,6 +3,7 @@ package org.jeecg.modules.base.dto;
import lombok.Data; import lombok.Data;
import org.jeecg.modules.base.entity.monitor.Item; import org.jeecg.modules.base.entity.monitor.Item;
import org.jeecg.modules.base.entity.postgre.AlarmItem; import org.jeecg.modules.base.entity.postgre.AlarmItem;
import org.jeecg.modules.base.entity.postgre.AlarmItemDe;
import java.io.Serializable; import java.io.Serializable;
@ -20,4 +21,10 @@ public class ItemDto implements Serializable{
this.name = alarmItem.getName(); this.name = alarmItem.getName();
this.units = alarmItem.getUnits(); this.units = alarmItem.getUnits();
} }
public ItemDto(AlarmItemDe alarmItemDe) {
this.itemId = alarmItemDe.getId();
this.name = alarmItemDe.getName();
this.units = alarmItemDe.getUnits();
}
} }

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.base.dto;
import lombok.Data;
@Data
public class SpaceInfo {
private String spaceName;
private Integer total;
private Double free;
private Double usage;
private Double used;
}

View File

@ -0,0 +1,23 @@
package org.jeecg.modules.base.entity.postgre;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.jeecg.common.system.base.entity.JeecgEntity;
@Data
@TableName("alarm_item_de")
public class AlarmItemDe extends JeecgEntity {
@TableField("name")
private String name;
@TableField("units")
private String units;
@TableField("description")
private String description;
@TableField("source_type")
private String sourceType;
}

View File

@ -12,7 +12,7 @@ import cn.hutool.core.util.StrUtil;
public enum SourceType { public enum SourceType {
EMAIL("Email"), EMAIL("Email"),
DATABASE("DataBase"), DATABASE("Database"),
SERVER("Server"); SERVER("Server");
private String type; private String type;

View File

@ -67,11 +67,9 @@ public class AlarmRuleController {
} }
@GetMapping("getItems") @GetMapping("getItems")
@ApiOperation(value = "根据资源名称获取监控项",notes = "根据资源名称获取监控项") @ApiOperation(value = "获取监控项",notes = "获取监控项")
public Result getItems(@RequestParam String sourceId){ public Result<?> getItems(@RequestParam String sourceType, String sourceId){
List<AlarmItem> alarmItems = alarmItemService.alarmItems(sourceId); return Result.OK(alarmItemService.allItems(sourceType, sourceId));
List<ItemDto> itemDtos = alarmItems.stream().map(ItemDto::new).collect(Collectors.toList());
return Result.OK(itemDtos);
} }
@PutMapping("updateStatus") @PutMapping("updateStatus")

View File

@ -76,4 +76,10 @@ public class SysDatabaseController {
@RequestParam String dbName) { @RequestParam String dbName) {
return Result.OK(sysDatabaseService.dbInfo(sourceId, dbName)); return Result.OK(sysDatabaseService.dbInfo(sourceId, dbName));
} }
@GetMapping("spaceInfo")
@ApiOperation(value = "数据库表空间使用情况",notes = "数据库表空间使用情况")
public Result<?> spaceInfo(@RequestParam String sourceId) {
return Result.OK(sysDatabaseService.spaceInfo(sourceId));
}
} }

View File

@ -0,0 +1,9 @@
package org.jeecg.modules.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.base.entity.postgre.AlarmItem;
import org.jeecg.modules.base.entity.postgre.AlarmItemDe;
public interface AlarmItemDeMapper extends BaseMapper<AlarmItemDe> {
}

View File

@ -0,0 +1,22 @@
package org.jeecg.modules.mapper;
import org.jeecg.modules.base.dto.DBInfo;
import org.jeecg.modules.base.dto.SpaceInfo;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SpaceRowMapper implements RowMapper<SpaceInfo> {
@Override
public SpaceInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
SpaceInfo spaceInfo = new SpaceInfo();
spaceInfo.setSpaceName(rs.getString("spaceName"));
spaceInfo.setTotal(rs.getInt("total"));
spaceInfo.setFree(rs.getDouble("free"));
spaceInfo.setUsage(rs.getDouble("usage"));
spaceInfo.setUsed(rs.getDouble("used"));
return spaceInfo;
}
}

View File

@ -0,0 +1,11 @@
package org.jeecg.modules.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.base.entity.postgre.AlarmItemDe;
import java.util.List;
public interface IAlarmItemDeService extends IService<AlarmItemDe> {
List<AlarmItemDe> alarmItemDes(String sourceType);
}

View File

@ -2,6 +2,7 @@ package org.jeecg.modules.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.base.dto.ItemDto;
import org.jeecg.modules.base.entity.postgre.AlarmItem; import org.jeecg.modules.base.entity.postgre.AlarmItem;
import java.util.List; import java.util.List;
@ -10,4 +11,6 @@ public interface IAlarmItemService extends IService<AlarmItem> {
boolean syncServerItem(); boolean syncServerItem();
List<AlarmItem> alarmItems(String sourceId); List<AlarmItem> alarmItems(String sourceId);
List<ItemDto> allItems(String sourceType, String sourceId);
} }

View File

@ -5,6 +5,7 @@ import org.jeecg.common.api.QueryRequest;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.base.dto.DBInfo; import org.jeecg.modules.base.dto.DBInfo;
import org.jeecg.modules.base.dto.SourceDto; import org.jeecg.modules.base.dto.SourceDto;
import org.jeecg.modules.base.dto.SpaceInfo;
import org.jeecg.modules.base.entity.postgre.SysDatabase; import org.jeecg.modules.base.entity.postgre.SysDatabase;
import org.jeecg.modules.base.bizVo.SourceVo; import org.jeecg.modules.base.bizVo.SourceVo;
@ -29,4 +30,6 @@ public interface ISysDatabaseService extends IService<SysDatabase> {
List<String> dbNames(String id); List<String> dbNames(String id);
List<DBInfo> dbInfo(String id, String dbName); List<DBInfo> dbInfo(String id, String dbName);
List<SpaceInfo> spaceInfo(String id);
} }

View File

@ -0,0 +1,21 @@
package org.jeecg.modules.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.base.entity.postgre.AlarmItemDe;
import org.jeecg.modules.mapper.AlarmItemDeMapper;
import org.jeecg.modules.service.IAlarmItemDeService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class AlarmItemDeServiceImpl extends ServiceImpl<AlarmItemDeMapper, AlarmItemDe> implements IAlarmItemDeService {
public List<AlarmItemDe> alarmItemDes(String sourceType) {
LambdaQueryWrapper<AlarmItemDe> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(AlarmItemDe::getSourceType,sourceType);
return list(wrapper);
}
}

View File

@ -3,19 +3,27 @@ package org.jeecg.modules.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.MonitorConstant; import org.jeecg.common.constant.MonitorConstant;
import org.jeecg.common.constant.Prompt; import org.jeecg.common.constant.Prompt;
import org.jeecg.common.util.RedisStreamUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.modules.base.dto.ItemDto;
import org.jeecg.modules.base.entity.monitor.Host; import org.jeecg.modules.base.entity.monitor.Host;
import org.jeecg.modules.base.entity.monitor.Item; import org.jeecg.modules.base.entity.monitor.Item;
import org.jeecg.modules.base.entity.monitor.Servers; import org.jeecg.modules.base.entity.monitor.Servers;
import org.jeecg.modules.base.entity.postgre.AlarmItem; import org.jeecg.modules.base.entity.postgre.AlarmItem;
import org.jeecg.modules.base.entity.postgre.AlarmItemDe;
import org.jeecg.modules.base.entity.postgre.SysServer; import org.jeecg.modules.base.entity.postgre.SysServer;
import org.jeecg.modules.base.enums.SourceType;
import org.jeecg.modules.feignclient.MonitorAlarm; import org.jeecg.modules.feignclient.MonitorAlarm;
import org.jeecg.modules.mapper.AlarmItemMapper; import org.jeecg.modules.mapper.AlarmItemMapper;
import org.jeecg.modules.service.IAlarmItemDeService;
import org.jeecg.modules.service.IAlarmItemService; import org.jeecg.modules.service.IAlarmItemService;
import org.jeecg.modules.service.ISysDatabaseService; import org.jeecg.modules.service.ISysDatabaseService;
import org.jeecg.modules.service.ISysServerService; import org.jeecg.modules.service.ISysServerService;
@ -25,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import static org.jeecg.modules.base.enums.SourceType.DATABASE; import static org.jeecg.modules.base.enums.SourceType.DATABASE;
import static org.jeecg.modules.base.enums.SourceType.SERVER; import static org.jeecg.modules.base.enums.SourceType.SERVER;
@ -40,7 +49,7 @@ public class AlarmItemServiceImpl extends ServiceImpl<AlarmItemMapper, AlarmItem
private ISysServerService serverService; private ISysServerService serverService;
@Autowired @Autowired
private ISysDatabaseService databaseService; private IAlarmItemDeService alarmItemDeService;
/** /**
* 同步所有服务器监控项信息 * 同步所有服务器监控项信息
@ -80,6 +89,11 @@ public class AlarmItemServiceImpl extends ServiceImpl<AlarmItemMapper, AlarmItem
} }
} }
/**
* @param sourceId
*
* 返回指定服务器的所有监控项
*/
@Override @Override
public List<AlarmItem> alarmItems(String sourceId) { public List<AlarmItem> alarmItems(String sourceId) {
if (StrUtil.isBlank(sourceId)) if (StrUtil.isBlank(sourceId))
@ -88,4 +102,29 @@ public class AlarmItemServiceImpl extends ServiceImpl<AlarmItemMapper, AlarmItem
wrapper.eq(AlarmItem::getSourceId,sourceId); wrapper.eq(AlarmItem::getSourceId,sourceId);
return list(wrapper); return list(wrapper);
} }
/*
* 返回指定服务器|数据库|邮箱的所有监控项
* */
@Override
public List<ItemDto> allItems(String sourceType, String sourceId) {
List<ItemDto> itemDtos = new ArrayList<>();
SourceType type = SourceType.typeOf(sourceType);
if (ObjectUtil.isNull(type))
return itemDtos;
switch (type){
case SERVER:
itemDtos = alarmItems(sourceId).stream()
.map(ItemDto::new).collect(Collectors.toList());
break;
case DATABASE:
case EMAIL:
itemDtos = alarmItemDeService.alarmItemDes(sourceType).stream()
.map(ItemDto::new).collect(Collectors.toList());
break;
default:
break;
}
return itemDtos;
}
} }

View File

@ -19,11 +19,13 @@ import org.jeecg.config.mybatis.DSSwitcher;
import org.jeecg.modules.base.dto.DBInfo; import org.jeecg.modules.base.dto.DBInfo;
import org.jeecg.modules.base.dto.DatabaseDto; import org.jeecg.modules.base.dto.DatabaseDto;
import org.jeecg.modules.base.dto.SourceDto; import org.jeecg.modules.base.dto.SourceDto;
import org.jeecg.modules.base.dto.SpaceInfo;
import org.jeecg.modules.base.entity.postgre.SysDatabase; import org.jeecg.modules.base.entity.postgre.SysDatabase;
import org.jeecg.modules.base.bizVo.SourceVo; import org.jeecg.modules.base.bizVo.SourceVo;
import org.jeecg.modules.entity.AlarmHistory; import org.jeecg.modules.entity.AlarmHistory;
import org.jeecg.modules.feignclient.SystemClient; import org.jeecg.modules.feignclient.SystemClient;
import org.jeecg.modules.mapper.DBRowMapper; import org.jeecg.modules.mapper.DBRowMapper;
import org.jeecg.modules.mapper.SpaceRowMapper;
import org.jeecg.modules.mapper.SysDatabaseMapper; import org.jeecg.modules.mapper.SysDatabaseMapper;
import org.jeecg.modules.service.ISysDatabaseService; import org.jeecg.modules.service.ISysDatabaseService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -242,6 +244,8 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
String dbType = sysDatabase.getDbType(); String dbType = sysDatabase.getDbType();
JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword); JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword);
DbType dbTypeE = DbType.typeOf(dbType); DbType dbTypeE = DbType.typeOf(dbType);
if (ObjectUtil.isNull(dbTypeE))
return dbNames;
switch (dbTypeE){ switch (dbTypeE){
case POSTGRESQL: case POSTGRESQL:
dbNames = template.queryForList(DBSQL.DBNAMES_PG, String.class); dbNames = template.queryForList(DBSQL.DBNAMES_PG, String.class);
@ -275,6 +279,8 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
DBRowMapper dbRowMapper = new DBRowMapper(); DBRowMapper dbRowMapper = new DBRowMapper();
JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword); JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword);
DbType dbTypeE = DbType.typeOf(dbType); DbType dbTypeE = DbType.typeOf(dbType);
if (ObjectUtil.isNull(dbTypeE))
return dbInfos;
switch (dbTypeE){ switch (dbTypeE){
case POSTGRESQL: case POSTGRESQL:
dbInfos = dbInfoPG(sysDatabase, dbName, dbRowMapper); dbInfos = dbInfoPG(sysDatabase, dbName, dbRowMapper);
@ -294,6 +300,25 @@ public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDa
return dbInfos; return dbInfos;
} }
@Override
public List<SpaceInfo> spaceInfo(String id) {
List<SpaceInfo> spaceInfos = new ArrayList<>();
SysDatabase sysDatabase = getById(id);
if (ObjectUtil.isNull(sysDatabase))
return spaceInfos;
String dbType = sysDatabase.getDbType();
if (StrUtil.equals(dbType, ORACLE.getType())){
String dbUrl = sysDatabase.getDbUrl();
String dbDriver = sysDatabase.getDbDriver();
String dbUsername = sysDatabase.getDbUsername();
String dbPassword = sysDatabase.getDbPassword();
RowMapper<SpaceInfo> mapper = new SpaceRowMapper();
JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword);
spaceInfos = template.query(DBSQL.SPACE_OR, mapper);
}
return spaceInfos;
}
private List<DBInfo> dbInfoPG(SysDatabase sysDatabase, String dbName, RowMapper<DBInfo> mapper){ private List<DBInfo> dbInfoPG(SysDatabase sysDatabase, String dbName, RowMapper<DBInfo> mapper){
String dbUrl = sysDatabase.getDbUrl(); String dbUrl = sysDatabase.getDbUrl();
String dbDriver = sysDatabase.getDbDriver(); String dbDriver = sysDatabase.getDbDriver();

View File

@ -9,7 +9,6 @@ import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.config.mqtoken.UserTokenContext; import org.jeecg.common.config.mqtoken.UserTokenContext;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.DateConstant; import org.jeecg.common.constant.DateConstant;
import org.jeecg.common.constant.RedisConstant; import org.jeecg.common.constant.RedisConstant;
import org.jeecg.common.util.RedisStreamUtil; import org.jeecg.common.util.RedisStreamUtil;
@ -28,12 +27,13 @@ import java.time.format.DateTimeFormatter;
import java.util.Set; import java.util.Set;
import static org.jeecg.modules.base.enums.Op.*; import static org.jeecg.modules.base.enums.Op.*;
import static org.jeecg.modules.base.enums.SourceType.SERVER;
@Data @Data
@Slf4j @Slf4j
@PersistJobDataAfterExecution @PersistJobDataAfterExecution
@DisallowConcurrentExecution @DisallowConcurrentExecution
public class SysInfoJob implements Job { public class ServerJob implements Job {
private String parameter; private String parameter;
@ -52,12 +52,10 @@ public class SysInfoJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException { public void execute(JobExecutionContext context) throws JobExecutionException {
init(); init();
// 查询所有报警规则,根据报警规则查询监控项数据 // 查询所有Server的报警规则,根据报警规则查询监控项数据
String pattern = RedisConstant.PREFIX_RULE; String pattern = RedisConstant.PREFIX_RULE + SERVER.getType();
Set<String> keys = redisStreamUtil.keys(pattern); Set<String> keys = redisStreamUtil.keys(pattern);
if (CollUtil.isEmpty(keys)) { if (CollUtil.isEmpty(keys)) return;
return;
}
// 时间间隔为每分钟 // 时间间隔为每分钟
LocalDateTime now = LocalDateTime.now() LocalDateTime now = LocalDateTime.now()
@ -73,8 +71,6 @@ public class SysInfoJob implements Job {
String operator = null; String operator = null;
for (String ruleKey : keys) { for (String ruleKey : keys) {
try { try {
if (StrUtil.equals(RedisConstant.ANALYSIS_RULE, ruleKey))
continue;
AlarmRule alarmRule = (AlarmRule) redisStreamUtil.get(ruleKey); AlarmRule alarmRule = (AlarmRule) redisStreamUtil.get(ruleKey);
// 如果报警规则为空,或者在沉默周期内,跳过当前规则 // 如果报警规则为空,或者在沉默周期内,跳过当前规则
operator = alarmRule.getOperator(); operator = alarmRule.getOperator();