feat:Database 各项统计信息采集
This commit is contained in:
parent
312aebbc99
commit
723c5a1706
|
@ -12,6 +12,13 @@ public interface DBSQL {
|
||||||
"0.0 AS used, 0.0 AS dataSize, 0.0 AS indexSize " +
|
"0.0 AS used, 0.0 AS dataSize, 0.0 AS indexSize " +
|
||||||
"FROM pg_class WHERE relkind = 'r' AND relname NOT LIKE 'pg_%' AND relname NOT LIKE 'sql_%'";
|
"FROM pg_class WHERE relkind = 'r' AND relname NOT LIKE 'pg_%' AND relname NOT LIKE 'sql_%'";
|
||||||
|
|
||||||
|
String DBSTATUS_PG = "SELECT *, 0 AS logResidue FROM " +
|
||||||
|
"(SELECT COUNT(*) AS loginNum FROM pg_stat_activity WHERE query_start >= now() - interval '1 minute') AS loginNum," +
|
||||||
|
"(SELECT COUNT(*) AS connNum FROM pg_stat_activity WHERE query_start >= now() - interval '1 minute') AS connNum," +
|
||||||
|
"(SELECT ROUND(SUM(pg_database_size(datname)) / 1024 / 1024, 0) AS dataSize FROM pg_database) AS dataSize";
|
||||||
|
|
||||||
|
String DBSTATUS_CONN_PG = "SELECT COUNT(*) FROM pg_stat_activity WHERE query_start >= now() - interval '1 minute'";
|
||||||
|
|
||||||
/* Oracle */
|
/* Oracle */
|
||||||
String DBNAMES_OR = "SELECT username FROM all_users";
|
String DBNAMES_OR = "SELECT username FROM all_users";
|
||||||
String DBINFO_OR = "SELECT a.table_name AS tableName, a.num_rows AS numRow," +
|
String DBINFO_OR = "SELECT a.table_name AS tableName, a.num_rows AS numRow," +
|
||||||
|
@ -39,6 +46,14 @@ public interface DBSQL {
|
||||||
"AND d.segment_type = 'INDEX' WHERE a.owner = '%s' " +
|
"AND d.segment_type = 'INDEX' WHERE a.owner = '%s' " +
|
||||||
"ORDER BY a.table_name";
|
"ORDER BY a.table_name";
|
||||||
|
|
||||||
|
String DBSTATUS_OR = "SELECT * FROM " +
|
||||||
|
"(SELECT COUNT(*) AS loginNum FROM V$SESSION WHERE LOGON_TIME >= SYSDATE - 1 / 24 / 60 AND TYPE = 'USER')," +
|
||||||
|
"(SELECT COUNT(*) AS connNum FROM V$SESSION WHERE LOGON_TIME >= SYSDATE - 1 / 24 / 60)," +
|
||||||
|
"(SELECT SUM(BYTES) / 1024 / 1024 AS logResidue FROM V$log WHERE ARCHIVED = 'NO')," +
|
||||||
|
"(SELECT SUM(BYTES) / 1024 / 1024 AS dataSize FROM dba_data_files)";
|
||||||
|
|
||||||
|
String DBSTATUS_CONN_OR = "SELECT COUNT(*) FROM V$SESSION WHERE LOGON_TIME >= SYSDATE - 1 / 24 / 60";
|
||||||
|
|
||||||
/* MySQL */
|
/* MySQL */
|
||||||
String DBNAMES_MY = "SHOW DATABASES";
|
String DBNAMES_MY = "SHOW DATABASES";
|
||||||
String DBINFO_MY = "SELECT TABLE_NAME AS tableName, TABLE_ROWS AS numRow," +
|
String DBINFO_MY = "SELECT TABLE_NAME AS tableName, TABLE_ROWS AS numRow," +
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package org.jeecg.modules.base.dto;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.jeecg.common.system.base.entity.JeecgEntity;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("database_status_conn")
|
||||||
|
public class DatabaseStatusConn extends JeecgEntity {
|
||||||
|
|
||||||
|
// private Double memory;
|
||||||
|
//
|
||||||
|
// private Integer loginNum;
|
||||||
|
|
||||||
|
private Integer connNum;
|
||||||
|
|
||||||
|
// private Double respTime; // 单位: 秒(S)
|
||||||
|
//
|
||||||
|
// private Double logResidue; // 单位 MB
|
||||||
|
//
|
||||||
|
// private Double dataSize; // 单位 MB
|
||||||
|
|
||||||
|
private String databaseId;
|
||||||
|
|
||||||
|
private LocalDateTime collectTime;
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.jeecg.modules;
|
||||||
|
|
||||||
|
import org.jeecg.common.constant.DBSQL;
|
||||||
|
import org.jeecg.common.util.JDBCUtil;
|
||||||
|
import org.jeecg.modules.base.entity.postgre.SysDatabase;
|
||||||
|
import org.jeecg.modules.databaseStatus.ConnFetcher;
|
||||||
|
import org.jeecg.modules.service.ISysDatabaseService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DatabaseStatusFetcher {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysDatabaseService databaseService;
|
||||||
|
|
||||||
|
public void start(){
|
||||||
|
List<SysDatabase> databases = databaseService.list();
|
||||||
|
// 采集数据库连接数
|
||||||
|
Thread connFetcher = new Thread(new ConnFetcher(databases));
|
||||||
|
connFetcher.setName("Thread-connFetcher");
|
||||||
|
connFetcher.start();
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String url = "jdbc:oracle:thin:@82.157.234.81:1521:XE";
|
||||||
|
String driver = "oracle.jdbc.OracleDriver";
|
||||||
|
String user = "configuration";
|
||||||
|
String pass = "123456";
|
||||||
|
|
||||||
|
JdbcTemplate template = JDBCUtil.template(url, driver, user, pass);
|
||||||
|
System.out.println(template.queryForObject(DBSQL.DBSTATUS_CONN_OR, Integer.class));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.jeecg.modules.controller;
|
||||||
|
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import org.jeecg.modules.service.IDatabaseStatusConnService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sysDatabaseStatus")
|
||||||
|
@Api(value = "数据库状态信息管理", tags = "数据库状态信息管理")
|
||||||
|
public class SysDatabaseStatusController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDatabaseStatusConnService databaseStatusService;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package org.jeecg.modules.databaseStatus;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.constant.DBSQL;
|
||||||
|
import org.jeecg.common.constant.enums.DbType;
|
||||||
|
import org.jeecg.common.util.JDBCUtil;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import org.jeecg.modules.base.dto.DatabaseStatusConn;
|
||||||
|
import org.jeecg.modules.base.entity.postgre.SysDatabase;
|
||||||
|
import org.jeecg.modules.service.IDatabaseStatusConnService;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jeecg.common.constant.enums.DbType.typeOf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 收集数据源的连接数信息 入库
|
||||||
|
* */
|
||||||
|
@Slf4j
|
||||||
|
public class ConnFetcher implements Runnable{
|
||||||
|
|
||||||
|
private List<SysDatabase> databases;
|
||||||
|
|
||||||
|
private IDatabaseStatusConnService connService;
|
||||||
|
|
||||||
|
public ConnFetcher(List<SysDatabase> databases) {
|
||||||
|
this.databases = databases;
|
||||||
|
connService = SpringContextUtils.getBean(IDatabaseStatusConnService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (CollUtil.isEmpty(databases)) return;
|
||||||
|
List<DatabaseStatusConn> statusList = new ArrayList<>();
|
||||||
|
Iterator<SysDatabase> iterator = databases.iterator();
|
||||||
|
while (true){
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
try {
|
||||||
|
SysDatabase database= iterator.next();
|
||||||
|
String databaseId = database.getId();
|
||||||
|
String dbType = database.getDbType();
|
||||||
|
String dbUrl = database.getDbUrl();
|
||||||
|
String dbDriver = database.getDbDriver();
|
||||||
|
String dbUsername = database.getDbUsername();
|
||||||
|
String dbPassword = database.getDbPassword();
|
||||||
|
JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword);
|
||||||
|
if (ObjectUtil.isNull(template)) {
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Integer conn = null;
|
||||||
|
// 根据数据库类型选择执行哪种数据库的状态查询SQL
|
||||||
|
DbType dbTypeE = typeOf(dbType);
|
||||||
|
if (ObjectUtil.isNotNull(dbTypeE)){
|
||||||
|
switch (dbTypeE){
|
||||||
|
case POSTGRESQL:
|
||||||
|
conn = template.queryForObject(DBSQL.DBSTATUS_CONN_PG, Integer.class);
|
||||||
|
break;
|
||||||
|
case ORACLE:
|
||||||
|
conn = template.queryForObject(DBSQL.DBSTATUS_CONN_OR, Integer.class);
|
||||||
|
break;
|
||||||
|
case MYSQL55:
|
||||||
|
// ...
|
||||||
|
break;
|
||||||
|
case MYSQL57:
|
||||||
|
// ...
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果conn == null 说明数据源类型不确定
|
||||||
|
if (ObjectUtil.isNull(conn)) {
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DatabaseStatusConn databaseStatus = new DatabaseStatusConn();
|
||||||
|
databaseStatus.setConnNum(conn);
|
||||||
|
databaseStatus.setDatabaseId(databaseId);
|
||||||
|
databaseStatus.setCollectTime(now);
|
||||||
|
// 数据达到一定数量,进行批量保存
|
||||||
|
statusList.add(databaseStatus);
|
||||||
|
if (statusList.size() == 5){
|
||||||
|
connService.saveBatch(statusList);
|
||||||
|
statusList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("ConnFetcher采集数据库连接数异常: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package org.jeecg.modules.databaseStatus;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.constant.DBSQL;
|
||||||
|
import org.jeecg.common.constant.enums.DbType;
|
||||||
|
import org.jeecg.common.util.JDBCUtil;
|
||||||
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
|
import org.jeecg.modules.base.dto.DatabaseStatusConn;
|
||||||
|
import org.jeecg.modules.base.entity.postgre.SysDatabase;
|
||||||
|
import org.jeecg.modules.service.IDatabaseStatusConnService;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static org.jeecg.common.constant.enums.DbType.typeOf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 收集数据源的状态信息 入库
|
||||||
|
* */
|
||||||
|
@Slf4j
|
||||||
|
public class StatusFetcher implements Runnable{
|
||||||
|
|
||||||
|
private final long sleepTime = 30 * 60 * 1000;
|
||||||
|
|
||||||
|
private final SysDatabase database;
|
||||||
|
|
||||||
|
private IDatabaseStatusConnService statusService;
|
||||||
|
|
||||||
|
public StatusFetcher(SysDatabase database) {
|
||||||
|
this.database = database;
|
||||||
|
statusService = SpringContextUtils.getBean(IDatabaseStatusConnService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (ObjectUtil.isNull(database)) return;
|
||||||
|
String databaseId = database.getId();
|
||||||
|
String dbType = database.getDbType();
|
||||||
|
String dbUrl = database.getDbUrl();
|
||||||
|
String dbDriver = database.getDbDriver();
|
||||||
|
String dbUsername = database.getDbUsername();
|
||||||
|
String dbPassword = database.getDbPassword();
|
||||||
|
List<DatabaseStatusConn> statusList = new ArrayList<>();
|
||||||
|
while (true){
|
||||||
|
try {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
|
||||||
|
/*
|
||||||
|
如果template == null 表示数据源连接失败,睡眠30min后重试
|
||||||
|
如果template != null 则表示连接成功,同时记录数据源连接响应时间
|
||||||
|
*/
|
||||||
|
if (ObjectUtil.isNull(template)){
|
||||||
|
TimeUnit.MILLISECONDS.sleep(sleepTime);
|
||||||
|
log.warn("数据源");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
log.info("11111111111111111111111111111111111111111111111");
|
||||||
|
DatabaseStatusConn databaseStatus = null;
|
||||||
|
// 根据数据库类型选择执行哪种数据库的状态查询SQL
|
||||||
|
DbType dbTypeE = typeOf(dbType);
|
||||||
|
if (ObjectUtil.isNotNull(dbTypeE)){
|
||||||
|
switch (dbTypeE){
|
||||||
|
case POSTGRESQL:
|
||||||
|
// databaseStatus = template.queryForObject(DBSQL.DBSTATUS_PG, mapper);
|
||||||
|
break;
|
||||||
|
case ORACLE:
|
||||||
|
// databaseStatus = template.queryForObject(DBSQL.DBSTATUS_OR, mapper);
|
||||||
|
break;
|
||||||
|
case MYSQL55:
|
||||||
|
// ...
|
||||||
|
break;
|
||||||
|
case MYSQL57:
|
||||||
|
// ...
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果databaseStatus == null 说明数据源类型不确定
|
||||||
|
if (ObjectUtil.isNull(databaseStatus)) return;
|
||||||
|
databaseStatus.setDatabaseId(databaseId);
|
||||||
|
// 设置数据的响应时间
|
||||||
|
BigDecimal decimal = new BigDecimal((end - start));
|
||||||
|
double respTime = decimal.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP).doubleValue();
|
||||||
|
//databaseStatus.setRespTime(respTime);
|
||||||
|
// 数据达到一定数量,进行批量保存
|
||||||
|
statusList.add(databaseStatus);
|
||||||
|
if (statusList.size() == 300){
|
||||||
|
statusService.saveBatch(statusList);
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package org.jeecg.modules.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.jeecg.modules.base.dto.DatabaseStatusConn;
|
||||||
|
|
||||||
|
public interface DatabaseStatusConnMapper extends BaseMapper<DatabaseStatusConn> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.jeecg.modules.mapper.DatabaseStatusConnMapper">
|
||||||
|
|
||||||
|
</mapper>
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.jeecg.modules.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.jeecg.modules.base.dto.DatabaseStatusConn;
|
||||||
|
|
||||||
|
public interface IDatabaseStatusConnService extends IService<DatabaseStatusConn> {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package org.jeecg.modules.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.jeecg.modules.base.dto.*;
|
||||||
|
import org.jeecg.modules.mapper.DatabaseStatusConnMapper;
|
||||||
|
import org.jeecg.modules.service.IDatabaseStatusConnService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service("databaseStatusConnService")
|
||||||
|
public class DatabaseStatusConnServiceImpl extends ServiceImpl<DatabaseStatusConnMapper, DatabaseStatusConn> implements IDatabaseStatusConnService {
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package org.jeecg;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.DatabaseStatusFetcher;
|
||||||
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.jeecg.modules.ServerStatusManager;
|
||||||
|
@ -32,6 +33,8 @@ public class JeecgAbnormalAlarmApplication extends SpringBootServletInitializer
|
||||||
|
|
||||||
private final DatabaseStatusManager databaseStatusManager;
|
private final DatabaseStatusManager databaseStatusManager;
|
||||||
|
|
||||||
|
private final DatabaseStatusFetcher databaseStatusFetcher;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||||
return application.sources(JeecgAbnormalAlarmApplication.class);
|
return application.sources(JeecgAbnormalAlarmApplication.class);
|
||||||
|
@ -59,6 +62,8 @@ public class JeecgAbnormalAlarmApplication extends SpringBootServletInitializer
|
||||||
emailStatusManager.start();
|
emailStatusManager.start();
|
||||||
// 启动监测服务器连接状态的线程
|
// 启动监测服务器连接状态的线程
|
||||||
serverStatusManager.start();
|
serverStatusManager.start();
|
||||||
|
// 启动采集数据库状态信息线程组
|
||||||
|
databaseStatusFetcher.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -15,5 +15,5 @@ spring:
|
||||||
config:
|
config:
|
||||||
import:
|
import:
|
||||||
- optional:nacos:armd.yaml
|
- optional:nacos:armd.yaml
|
||||||
- optional:nacos:armd-@profile.name@.yaml
|
- optional:nacos:armd-@profile.name@1.yaml
|
||||||
- optional:nacos:armd-analysis-@profile.name@.yaml
|
- optional:nacos:armd-analysis-@profile.name@.yaml
|
||||||
|
|
Loading…
Reference in New Issue
Block a user