最近新增的工作
This commit is contained in:
29
systemmonitor/README.md
Normal file
29
systemmonitor/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# System Monitor 模块说明
|
||||
|
||||
## 当前状态
|
||||
|
||||
`systemmonitor` 当前作为系统监控能力聚合模块使用。
|
||||
|
||||
当前真实保留的子模块有:
|
||||
|
||||
- `disk-monitor`
|
||||
|
||||
## 当前结构
|
||||
|
||||
```text
|
||||
systemmonitor/
|
||||
└── disk-monitor/
|
||||
```
|
||||
|
||||
## disk-monitor 的职责
|
||||
|
||||
`disk-monitor` 预留用于承载磁盘监控相关能力,后续可在该模块内继续补充:
|
||||
|
||||
- 磁盘监控配置管理
|
||||
- 磁盘巡检任务
|
||||
- 磁盘容量计算与阈值判定
|
||||
- 磁盘预警与告警留痕
|
||||
|
||||
## 模块定位
|
||||
|
||||
当前将磁盘监控拆分到 `systemmonitor/disk-monitor`,目的是避免将系统监控扩展逻辑直接混入 `system` 公共基础模块,便于后续继续扩展 CPU、内存或进程级监控能力。
|
||||
11
systemmonitor/disk-monitor/README.md
Normal file
11
systemmonitor/disk-monitor/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# disk-monitor
|
||||
|
||||
`disk-monitor` 模块用于承载磁盘监控相关代码。
|
||||
|
||||
当前这一版只完成模块骨架接入,后续可以在该模块内继续补充:
|
||||
|
||||
- Controller
|
||||
- Service
|
||||
- 定时巡检任务
|
||||
- 磁盘容量采集与阈值判断
|
||||
- 日志留痕与 SQL 脚本
|
||||
37
systemmonitor/disk-monitor/pom.xml
Normal file
37
systemmonitor/disk-monitor/pom.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.njcn.gather</groupId>
|
||||
<artifactId>systemmonitor</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>disk-monitor</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>disk-monitor</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.njcn</groupId>
|
||||
<artifactId>njcn-common</artifactId>
|
||||
<version>0.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.njcn</groupId>
|
||||
<artifactId>mybatis-plus</artifactId>
|
||||
<version>0.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.njcn</groupId>
|
||||
<artifactId>spingboot2.3.12</artifactId>
|
||||
<version>2.3.12</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,250 @@
|
||||
package com.njcn.gather.systemmonitor.disk.component;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.constant.DiskMonitorConstant;
|
||||
import com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorNotifyLogMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.dto.DiskMonitorNotifyHttpItem;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.dto.DiskMonitorNotifyPathItem;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorJob;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorNotifyLog;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorResult;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorTarget;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 磁盘监控通知发送组件。
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DiskMonitorNotificationComponent {
|
||||
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
private static final TypeReference<List<DiskMonitorNotifyPathItem>> PATH_LIST_TYPE = new TypeReference<List<DiskMonitorNotifyPathItem>>() {
|
||||
};
|
||||
private static final TypeReference<List<DiskMonitorNotifyHttpItem>> HTTP_LIST_TYPE = new TypeReference<List<DiskMonitorNotifyHttpItem>>() {
|
||||
};
|
||||
|
||||
private final DiskMonitorNotifyLogMapper notifyLogMapper;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public void sendNotifications(DiskMonitorJob job, DiskMonitorTarget target, DiskMonitorResult result,
|
||||
BigDecimal usedPercent, String currentStatus, String notifyReason,
|
||||
String notifyLevel, LocalDateTime scanTime, String message) {
|
||||
List<DiskMonitorNotifyPathItem> pathItems;
|
||||
List<DiskMonitorNotifyHttpItem> httpItems;
|
||||
try {
|
||||
pathItems = parsePathItems(target.getNotifyPathListJson());
|
||||
httpItems = parseHttpItems(target.getNotifyHttpListJson());
|
||||
} catch (Exception exception) {
|
||||
insertFailedNotifyLog(job, result, target, notifyLevel, "N/A", "通知配置解析失败: " + exception.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
boolean pathConfigured = isEnabled(target.getNotifyPathEnabled()) && pathItems.stream().anyMatch(item -> Boolean.TRUE.equals(item.getEnabled()));
|
||||
boolean httpConfigured = isEnabled(target.getNotifyHttpEnabled()) && httpItems.stream().anyMatch(item -> Boolean.TRUE.equals(item.getEnabled()));
|
||||
if (!pathConfigured && !httpConfigured) {
|
||||
insertFailedNotifyLog(job, result, target, notifyLevel, "N/A", "当前盘符未配置可用通知通道");
|
||||
return;
|
||||
}
|
||||
|
||||
String notifyTitle = buildNotifyTitle(target.getDriveLetter(), notifyLevel, usedPercent);
|
||||
String notifyContent = buildNotifyContent(job, target, usedPercent, currentStatus, notifyLevel, scanTime, message);
|
||||
|
||||
if (pathConfigured) {
|
||||
for (DiskMonitorNotifyPathItem item : pathItems) {
|
||||
if (!Boolean.TRUE.equals(item.getEnabled())) {
|
||||
continue;
|
||||
}
|
||||
sendPathNotification(job, target, result, notifyReason, notifyLevel, notifyTitle, notifyContent, item,
|
||||
usedPercent, currentStatus, scanTime, message);
|
||||
}
|
||||
}
|
||||
if (httpConfigured) {
|
||||
for (DiskMonitorNotifyHttpItem item : httpItems) {
|
||||
if (!Boolean.TRUE.equals(item.getEnabled())) {
|
||||
continue;
|
||||
}
|
||||
sendHttpNotification(job, target, result, notifyReason, notifyLevel, notifyTitle, notifyContent, item,
|
||||
usedPercent, currentStatus, scanTime, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPathNotification(DiskMonitorJob job, DiskMonitorTarget target, DiskMonitorResult result,
|
||||
String notifyReason, String notifyLevel, String notifyTitle, String notifyContent,
|
||||
DiskMonitorNotifyPathItem item, BigDecimal usedPercent, String currentStatus,
|
||||
LocalDateTime scanTime, String message) {
|
||||
DiskMonitorNotifyLog notifyLog = createNotifyLog(job, result, target, notifyLevel, notifyTitle, notifyContent,
|
||||
DiskMonitorConstant.CHANNEL_TYPE_PATH, item.getPath());
|
||||
try {
|
||||
Path directoryPath = Paths.get(item.getPath());
|
||||
Files.createDirectories(directoryPath);
|
||||
String fileName = String.format("disk-monitor-%s-%s-%s.json",
|
||||
job.getJobNo(), target.getDriveLetter().replace(":", ""),
|
||||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
|
||||
Path filePath = directoryPath.resolve(fileName);
|
||||
Map<String, Object> payload = buildNotifyPayload(job, target, usedPercent, currentStatus, notifyReason, notifyLevel, scanTime, message);
|
||||
Files.write(filePath, objectMapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(payload));
|
||||
notifyLog.setSendStatus(DiskMonitorConstant.SEND_STATUS_SUCCESS);
|
||||
notifyLog.setResponseMessage("写入成功:" + filePath.toString());
|
||||
} catch (Exception exception) {
|
||||
log.error("磁盘监控路径通知发送失败,driveLetter={}, path={}", target.getDriveLetter(), item.getPath(), exception);
|
||||
notifyLog.setSendStatus(DiskMonitorConstant.SEND_STATUS_FAILED);
|
||||
notifyLog.setResponseMessage(exception.getMessage());
|
||||
}
|
||||
notifyLogMapper.insert(notifyLog);
|
||||
}
|
||||
|
||||
private void sendHttpNotification(DiskMonitorJob job, DiskMonitorTarget target, DiskMonitorResult result,
|
||||
String notifyReason, String notifyLevel, String notifyTitle, String notifyContent,
|
||||
DiskMonitorNotifyHttpItem item, BigDecimal usedPercent, String currentStatus,
|
||||
LocalDateTime scanTime, String message) {
|
||||
DiskMonitorNotifyLog notifyLog = createNotifyLog(job, result, target, notifyLevel, notifyTitle, notifyContent,
|
||||
DiskMonitorConstant.CHANNEL_TYPE_HTTP, item.getUrl());
|
||||
HttpURLConnection connection = null;
|
||||
try {
|
||||
Map<String, Object> payload = buildNotifyPayload(job, target, usedPercent, currentStatus, notifyReason, notifyLevel, scanTime, message);
|
||||
byte[] body = objectMapper.writeValueAsBytes(payload);
|
||||
URL url = new URL(item.getUrl());
|
||||
connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(StrUtil.blankToDefault(item.getMethod(), DiskMonitorConstant.HTTP_METHOD_POST).trim().toUpperCase(Locale.ROOT));
|
||||
connection.setConnectTimeout(resolveTimeout(item.getTimeoutMs()));
|
||||
connection.setReadTimeout(resolveTimeout(item.getTimeoutMs()));
|
||||
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
|
||||
connection.setDoInput(true);
|
||||
if (!"GET".equalsIgnoreCase(connection.getRequestMethod())) {
|
||||
connection.setDoOutput(true);
|
||||
try (OutputStream outputStream = connection.getOutputStream()) {
|
||||
outputStream.write(body);
|
||||
}
|
||||
}
|
||||
int statusCode = connection.getResponseCode();
|
||||
notifyLog.setSendStatus(statusCode >= 200 && statusCode < 300
|
||||
? DiskMonitorConstant.SEND_STATUS_SUCCESS
|
||||
: DiskMonitorConstant.SEND_STATUS_FAILED);
|
||||
notifyLog.setResponseMessage(statusCode + " " + connection.getResponseMessage());
|
||||
} catch (Exception exception) {
|
||||
log.error("磁盘监控HTTP通知发送失败,driveLetter={}, url={}", target.getDriveLetter(), item.getUrl(), exception);
|
||||
notifyLog.setSendStatus(DiskMonitorConstant.SEND_STATUS_FAILED);
|
||||
notifyLog.setResponseMessage(exception.getMessage());
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
notifyLogMapper.insert(notifyLog);
|
||||
}
|
||||
|
||||
private Map<String, Object> buildNotifyPayload(DiskMonitorJob job, DiskMonitorTarget target, BigDecimal usedPercent,
|
||||
String currentStatus, String notifyReason, String notifyLevel,
|
||||
LocalDateTime scanTime, String message) {
|
||||
Map<String, Object> payload = new LinkedHashMap<>();
|
||||
payload.put("jobNo", job.getJobNo());
|
||||
payload.put("driveLetter", target.getDriveLetter());
|
||||
payload.put("currentStatus", currentStatus);
|
||||
payload.put("notifyReason", notifyReason);
|
||||
payload.put("notifyLevel", notifyLevel);
|
||||
payload.put("usedPercent", usedPercent);
|
||||
payload.put("warningUsagePercent", target.getWarningUsagePercent());
|
||||
payload.put("alarmUsagePercent", target.getAlarmUsagePercent());
|
||||
payload.put("scanTime", formatDateTime(scanTime));
|
||||
payload.put("message", message);
|
||||
return payload;
|
||||
}
|
||||
|
||||
private String buildNotifyTitle(String driveLetter, String notifyLevel, BigDecimal usedPercent) {
|
||||
return String.format("磁盘监控通知[%s] %s 使用率%s%%",
|
||||
notifyLevel, driveLetter, usedPercent == null ? "0.00" : usedPercent.toPlainString());
|
||||
}
|
||||
|
||||
private String buildNotifyContent(DiskMonitorJob job, DiskMonitorTarget target, BigDecimal usedPercent,
|
||||
String currentStatus, String notifyLevel, LocalDateTime scanTime, String message) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("任务编号:").append(job.getJobNo())
|
||||
.append(";盘符:").append(target.getDriveLetter())
|
||||
.append(";当前状态:").append(currentStatus)
|
||||
.append(";通知级别:").append(notifyLevel)
|
||||
.append(";使用率:").append(usedPercent == null ? "0.00" : usedPercent.toPlainString()).append("%")
|
||||
.append(";预警阈值:").append(target.getWarningUsagePercent()).append("%")
|
||||
.append(";告警阈值:").append(target.getAlarmUsagePercent()).append("%")
|
||||
.append(";扫描时间:").append(formatDateTime(scanTime));
|
||||
if (StrUtil.isNotBlank(message)) {
|
||||
builder.append(";说明:").append(message);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private DiskMonitorNotifyLog createNotifyLog(DiskMonitorJob job, DiskMonitorResult result, DiskMonitorTarget target,
|
||||
String notifyLevel, String notifyTitle, String notifyContent,
|
||||
String channelType, String channelTarget) {
|
||||
DiskMonitorNotifyLog notifyLog = new DiskMonitorNotifyLog();
|
||||
notifyLog.setJobId(job.getId());
|
||||
notifyLog.setResultId(result.getId());
|
||||
notifyLog.setTargetId(target.getId());
|
||||
notifyLog.setDriveLetter(target.getDriveLetter());
|
||||
notifyLog.setNotifyLevel(notifyLevel);
|
||||
notifyLog.setChannelType(channelType);
|
||||
notifyLog.setChannelTarget(channelTarget);
|
||||
notifyLog.setNotifyTitle(notifyTitle);
|
||||
notifyLog.setNotifyContent(notifyContent);
|
||||
notifyLog.setSentAt(LocalDateTime.now());
|
||||
return notifyLog;
|
||||
}
|
||||
|
||||
private void insertFailedNotifyLog(DiskMonitorJob job, DiskMonitorResult result, DiskMonitorTarget target,
|
||||
String notifyLevel, String channelTarget, String responseMessage) {
|
||||
DiskMonitorNotifyLog notifyLog = createNotifyLog(job, result, target, notifyLevel,
|
||||
"磁盘监控通知失败", responseMessage, DiskMonitorConstant.CHANNEL_TYPE_HTTP, channelTarget);
|
||||
notifyLog.setSendStatus(DiskMonitorConstant.SEND_STATUS_FAILED);
|
||||
notifyLog.setResponseMessage(responseMessage);
|
||||
notifyLogMapper.insert(notifyLog);
|
||||
}
|
||||
|
||||
private List<DiskMonitorNotifyPathItem> parsePathItems(String json) throws Exception {
|
||||
return readJsonList(json, PATH_LIST_TYPE);
|
||||
}
|
||||
|
||||
private List<DiskMonitorNotifyHttpItem> parseHttpItems(String json) throws Exception {
|
||||
return readJsonList(json, HTTP_LIST_TYPE);
|
||||
}
|
||||
|
||||
private <T> List<T> readJsonList(String json, TypeReference<List<T>> typeReference) throws Exception {
|
||||
if (StrUtil.isBlank(json)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<T> result = objectMapper.readValue(json, typeReference);
|
||||
return result == null ? new ArrayList<>() : result;
|
||||
}
|
||||
|
||||
private boolean isEnabled(Integer value) {
|
||||
return value != null && value == 1;
|
||||
}
|
||||
|
||||
private int resolveTimeout(Integer timeoutMs) {
|
||||
return timeoutMs == null || timeoutMs <= 0 ? DiskMonitorConstant.DEFAULT_HTTP_TIMEOUT_MS : timeoutMs;
|
||||
}
|
||||
|
||||
private String formatDateTime(LocalDateTime dateTime) {
|
||||
return dateTime == null ? null : dateTime.format(DATE_TIME_FORMATTER);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.njcn.gather.systemmonitor.disk.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 磁盘监控模块基础配置入口,后续磁盘监控相关 Bean 统一放在该模块下扩展。
|
||||
*/
|
||||
@Configuration
|
||||
public class DiskMonitorModuleConfig {
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.njcn.gather.systemmonitor.disk.constant;
|
||||
|
||||
/**
|
||||
* 磁盘监控模块常量。
|
||||
*/
|
||||
public interface DiskMonitorConstant {
|
||||
|
||||
String DEFAULT_POLICY_NAME = "默认磁盘监控策略";
|
||||
String DEFAULT_DAILY_RUN_TIME = "08:30:00";
|
||||
String WARNING_NOTIFY_MODE_STATUS_CHANGE = "STATUS_CHANGE";
|
||||
String ALARM_NOTIFY_MODE_EVERY_TIME = "EVERY_TIME";
|
||||
|
||||
String STATUS_UNKNOWN = "UNKNOWN";
|
||||
String STATUS_NORMAL = "NORMAL";
|
||||
String STATUS_WARNING = "WARNING";
|
||||
String STATUS_ALARM = "ALARM";
|
||||
|
||||
String JOB_SOURCE_APP_START = "APP_START";
|
||||
String JOB_SOURCE_DAILY_SCHEDULE = "DAILY_SCHEDULE";
|
||||
String JOB_SOURCE_MANUAL = "MANUAL";
|
||||
|
||||
String JOB_STATUS_RUNNING = "RUNNING";
|
||||
String JOB_STATUS_SUCCESS = "SUCCESS";
|
||||
String JOB_STATUS_PARTIAL_SUCCESS = "PARTIAL_SUCCESS";
|
||||
String JOB_STATUS_FAILED = "FAILED";
|
||||
|
||||
String NOTIFY_REASON_ALARM_EVERY_TIME = "ALARM_EVERY_TIME";
|
||||
String NOTIFY_REASON_STATUS_CHANGED = "STATUS_CHANGED";
|
||||
String NOTIFY_REASON_NO_NOTIFY = "NO_NOTIFY";
|
||||
|
||||
String NOTIFY_LEVEL_WARNING = "WARNING";
|
||||
String NOTIFY_LEVEL_ALARM = "ALARM";
|
||||
String NOTIFY_LEVEL_RECOVER = "RECOVER";
|
||||
|
||||
String CHANNEL_TYPE_PATH = "PATH";
|
||||
String CHANNEL_TYPE_HTTP = "HTTP";
|
||||
|
||||
String SEND_STATUS_SUCCESS = "SUCCESS";
|
||||
String SEND_STATUS_FAILED = "FAILED";
|
||||
|
||||
String HTTP_METHOD_POST = "POST";
|
||||
int DEFAULT_HTTP_TIMEOUT_MS = 5000;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.njcn.gather.systemmonitor.disk.constant;
|
||||
|
||||
/**
|
||||
* 磁盘监控参数校验提示。
|
||||
*/
|
||||
public interface DiskMonitorValidMessage {
|
||||
|
||||
String POLICY_NOT_NULL = "policy不能为空,请检查policy参数";
|
||||
String TARGETS_NOT_NULL = "targets不能为空,请检查targets参数";
|
||||
String DRIVE_LETTER_NOT_BLANK = "盘符不能为空,请检查driveLetter参数";
|
||||
String DAILY_RUN_TIME_NOT_BLANK = "每日统一执行时间不能为空,请检查dailyRunTime参数";
|
||||
String DAILY_RUN_TIME_FORMAT_ERROR = "每日统一执行时间格式错误,请使用HH:mm:ss";
|
||||
String WARNING_USAGE_PERCENT_NOT_NULL = "预警使用率不能为空,请检查warningUsagePercent参数";
|
||||
String ALARM_USAGE_PERCENT_NOT_NULL = "告警使用率不能为空,请检查alarmUsagePercent参数";
|
||||
String USAGE_PERCENT_FORMAT_ERROR = "阈值范围必须在1-100之间,请检查阈值参数";
|
||||
String JOB_SOURCE_NOT_BLANK = "任务来源不能为空,请检查jobSource参数";
|
||||
String JOB_ID_NOT_NULL = "jobId不能为空,请检查jobId参数";
|
||||
String POLICY_NAME_NOT_BLANK = "策略名称不能为空,请检查policyName参数";
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.njcn.gather.systemmonitor.disk.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.constant.OperateType;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.param.DiskMonitorParam;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.vo.DiskMonitorVO;
|
||||
import com.njcn.gather.systemmonitor.disk.service.IDiskMonitorJobService;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 磁盘监控任务接口。
|
||||
*/
|
||||
@Validated
|
||||
@Slf4j
|
||||
@Api(tags = "磁盘监控任务")
|
||||
@RestController
|
||||
@RequestMapping("/disk-monitor")
|
||||
@RequiredArgsConstructor
|
||||
public class DiskMonitorJobController extends BaseController {
|
||||
|
||||
private final IDiskMonitorJobService diskMonitorJobService;
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
||||
@PostMapping("/job/run")
|
||||
@ApiOperation("手动执行磁盘监控")
|
||||
@ApiImplicitParam(name = "param", value = "手动执行参数", required = true)
|
||||
public HttpResult<DiskMonitorVO.JobRunVO> run(@RequestBody @Valid DiskMonitorParam.JobRunParam param) {
|
||||
String methodDescribe = getMethodDescribe("run");
|
||||
LogUtil.njcnDebug(log, "{},执行磁盘监控任务,source={}", methodDescribe, param.getJobSource());
|
||||
return HttpResultUtil.assembleResult(CommonResponseEnum.SUCCESS.getCode(), diskMonitorJobService.runJob(param), "任务已启动");
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@PostMapping("/job/list")
|
||||
@ApiOperation("分页查询磁盘监控任务列表")
|
||||
@ApiImplicitParam(name = "param", value = "任务分页查询参数", required = true)
|
||||
public HttpResult<Page<DiskMonitorVO.JobListVO>> list(@RequestBody @Valid DiskMonitorParam.JobListParam param) {
|
||||
String methodDescribe = getMethodDescribe("list");
|
||||
LogUtil.njcnDebug(log, "{},分页查询磁盘监控任务列表", methodDescribe);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, diskMonitorJobService.listJobs(param), methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@GetMapping("/job/{jobId}/detail")
|
||||
@ApiOperation("查询磁盘监控任务详情")
|
||||
@ApiImplicitParam(name = "jobId", value = "任务ID", required = true)
|
||||
public HttpResult<DiskMonitorVO.JobDetailVO> jobDetail(@PathVariable("jobId") Long jobId) {
|
||||
String methodDescribe = getMethodDescribe("jobDetail");
|
||||
LogUtil.njcnDebug(log, "{},查询磁盘监控任务详情,jobId={}", methodDescribe, jobId);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, diskMonitorJobService.getJobDetail(jobId), methodDescribe);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.njcn.gather.systemmonitor.disk.controller;
|
||||
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.constant.OperateType;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.param.DiskMonitorParam;
|
||||
import com.njcn.gather.systemmonitor.disk.service.IDiskMonitorNotifyService;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 磁盘监控通知接口。
|
||||
*/
|
||||
@Validated
|
||||
@Slf4j
|
||||
@Api(tags = "磁盘监控通知")
|
||||
@RestController
|
||||
@RequestMapping("/disk-monitor")
|
||||
@RequiredArgsConstructor
|
||||
public class DiskMonitorNotifyController extends BaseController {
|
||||
|
||||
private final IDiskMonitorNotifyService diskMonitorNotifyService;
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
||||
@PostMapping("/notify/test")
|
||||
@ApiOperation("测试磁盘监控通知")
|
||||
@ApiImplicitParam(name = "param", value = "通知测试参数", required = true)
|
||||
public HttpResult<Boolean> testNotify(@RequestBody @Valid DiskMonitorParam.NotifyTestParam param) {
|
||||
String methodDescribe = getMethodDescribe("testNotify");
|
||||
LogUtil.njcnDebug(log, "{},测试磁盘监控通知,driveLetter={}", methodDescribe, param.getDriveLetter());
|
||||
boolean result = diskMonitorNotifyService.testNotify(param);
|
||||
return HttpResultUtil.assembleCommonResponseResult(result ? CommonResponseEnum.SUCCESS : CommonResponseEnum.FAIL, result, methodDescribe);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.njcn.gather.systemmonitor.disk.controller;
|
||||
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.constant.OperateType;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.param.DiskMonitorParam;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.vo.DiskMonitorVO;
|
||||
import com.njcn.gather.systemmonitor.disk.service.IDiskMonitorPolicyService;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 磁盘监控配置接口。
|
||||
*/
|
||||
@Validated
|
||||
@Slf4j
|
||||
@Api(tags = "磁盘监控配置")
|
||||
@RestController
|
||||
@RequestMapping("/disk-monitor")
|
||||
@RequiredArgsConstructor
|
||||
public class DiskMonitorPolicyController extends BaseController {
|
||||
|
||||
private final IDiskMonitorPolicyService diskMonitorPolicyService;
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@GetMapping("/policy/detail")
|
||||
@ApiOperation("查询磁盘监控配置详情")
|
||||
public HttpResult<DiskMonitorVO.PolicyDetailVO> detail() {
|
||||
String methodDescribe = getMethodDescribe("detail");
|
||||
LogUtil.njcnDebug(log, "{},查询磁盘监控配置详情", methodDescribe);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, diskMonitorPolicyService.getPolicyDetail(), methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
||||
@PostMapping("/policy/save")
|
||||
@ApiOperation("保存磁盘监控配置")
|
||||
@ApiImplicitParam(name = "param", value = "磁盘监控配置", required = true)
|
||||
public HttpResult<Boolean> save(@RequestBody @Valid DiskMonitorParam.PolicySaveParam param) {
|
||||
String methodDescribe = getMethodDescribe("save");
|
||||
LogUtil.njcnDebug(log, "{},保存磁盘监控配置", methodDescribe);
|
||||
boolean result = diskMonitorPolicyService.savePolicy(param);
|
||||
return HttpResultUtil.assembleCommonResponseResult(result ? CommonResponseEnum.SUCCESS : CommonResponseEnum.FAIL, result, methodDescribe);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.njcn.gather.systemmonitor.disk.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 磁盘监控模块业务响应码。
|
||||
*/
|
||||
@Getter
|
||||
public enum DiskMonitorResponseEnum {
|
||||
|
||||
POLICY_NOT_FOUND("A01060", "磁盘监控策略不存在"),
|
||||
TARGET_NOT_FOUND("A01061", "磁盘监控盘符配置不存在"),
|
||||
DRIVE_LETTER_REPEAT("A01062", "盘符重复,请检查driveLetter参数"),
|
||||
DRIVE_LETTER_FORMAT_ERROR("A01063", "盘符格式错误,请使用类似 C: 的格式"),
|
||||
DAILY_RUN_TIME_FORMAT_ERROR("A01064", "每日统一执行时间格式错误,请使用HH:mm:ss"),
|
||||
USAGE_PERCENT_INVALID("A01065", "告警使用率必须大于等于预警使用率"),
|
||||
NOTIFY_PATH_EMPTY("A01066", "路径通知目标不能为空"),
|
||||
NOTIFY_HTTP_EMPTY("A01067", "HTTP通知目标不能为空"),
|
||||
NOTIFY_PATH_VALUE_EMPTY("A01068", "通知路径不能为空"),
|
||||
NOTIFY_HTTP_URL_INVALID("A01069", "HTTP通知目标格式错误,请检查url参数"),
|
||||
NO_ENABLED_TARGET("A01070", "暂无启用的磁盘监控盘符配置"),
|
||||
JOB_NOT_FOUND("A01071", "监控任务不存在"),
|
||||
POLICY_SAVE_FAILED("A01072", "磁盘监控配置保存失败"),
|
||||
DRIVE_SCAN_FAILED("A01073", "磁盘扫描失败"),
|
||||
NOTIFY_TARGET_NOT_FOUND("A01074", "通知测试盘符不存在"),
|
||||
NOTIFY_CHANNEL_MISSING("A01075", "当前盘符未配置可用通知通道"),
|
||||
POLICY_MODE_INVALID("A01076", "通知模式配置非法"),
|
||||
JOB_SOURCE_INVALID("A01077", "任务来源非法");
|
||||
|
||||
private final String code;
|
||||
private final String message;
|
||||
|
||||
DiskMonitorResponseEnum(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.njcn.gather.systemmonitor.disk.event;
|
||||
|
||||
/**
|
||||
* 磁盘监控策略变更事件。
|
||||
*/
|
||||
public class DiskMonitorPolicyChangedEvent {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.njcn.gather.systemmonitor.disk.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorJob;
|
||||
|
||||
/**
|
||||
* 磁盘监控任务 Mapper。
|
||||
*/
|
||||
public interface DiskMonitorJobMapper extends MPJBaseMapper<DiskMonitorJob> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.njcn.gather.systemmonitor.disk.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorNotifyLog;
|
||||
|
||||
/**
|
||||
* 磁盘监控通知日志 Mapper。
|
||||
*/
|
||||
public interface DiskMonitorNotifyLogMapper extends MPJBaseMapper<DiskMonitorNotifyLog> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.njcn.gather.systemmonitor.disk.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorPolicy;
|
||||
|
||||
/**
|
||||
* 磁盘监控策略 Mapper。
|
||||
*/
|
||||
public interface DiskMonitorPolicyMapper extends MPJBaseMapper<DiskMonitorPolicy> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.njcn.gather.systemmonitor.disk.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorResult;
|
||||
|
||||
/**
|
||||
* 磁盘监控结果 Mapper。
|
||||
*/
|
||||
public interface DiskMonitorResultMapper extends MPJBaseMapper<DiskMonitorResult> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.njcn.gather.systemmonitor.disk.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorTarget;
|
||||
|
||||
/**
|
||||
* 磁盘监控盘符配置 Mapper。
|
||||
*/
|
||||
public interface DiskMonitorTargetMapper extends MPJBaseMapper<DiskMonitorTarget> {
|
||||
}
|
||||
@@ -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="com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorJobMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -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="com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorNotifyLogMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -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="com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorPolicyMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -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="com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorResultMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -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="com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorTargetMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.njcn.gather.systemmonitor.disk.pojo.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* HTTP 通知项。
|
||||
*/
|
||||
@Data
|
||||
public class DiskMonitorNotifyHttpItem {
|
||||
|
||||
@ApiModelProperty("回调地址")
|
||||
@NotBlank(message = "HTTP通知目标不能为空,请检查url参数")
|
||||
private String url;
|
||||
|
||||
@ApiModelProperty("名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("请求方法")
|
||||
private String method;
|
||||
|
||||
@ApiModelProperty("超时时间")
|
||||
@Min(value = 1, message = "timeoutMs必须大于0")
|
||||
private Integer timeoutMs;
|
||||
|
||||
@ApiModelProperty("是否启用")
|
||||
private Boolean enabled;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.njcn.gather.systemmonitor.disk.pojo.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 路径通知项。
|
||||
*/
|
||||
@Data
|
||||
public class DiskMonitorNotifyPathItem {
|
||||
|
||||
@ApiModelProperty("路径")
|
||||
@NotBlank(message = "通知路径不能为空,请检查path参数")
|
||||
private String path;
|
||||
|
||||
@ApiModelProperty("名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("是否启用")
|
||||
private Boolean enabled;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.njcn.gather.systemmonitor.disk.pojo.param;
|
||||
|
||||
import com.njcn.gather.systemmonitor.disk.constant.DiskMonitorValidMessage;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.dto.DiskMonitorNotifyHttpItem;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.dto.DiskMonitorNotifyPathItem;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 磁盘监控接口参数。
|
||||
*/
|
||||
public class DiskMonitorParam {
|
||||
|
||||
@Data
|
||||
public static class PolicySaveParam {
|
||||
|
||||
@ApiModelProperty("全局策略")
|
||||
@NotNull(message = DiskMonitorValidMessage.POLICY_NOT_NULL)
|
||||
@Valid
|
||||
private PolicyParam policy;
|
||||
|
||||
@ApiModelProperty("盘符配置")
|
||||
@NotNull(message = DiskMonitorValidMessage.TARGETS_NOT_NULL)
|
||||
@Valid
|
||||
private List<TargetParam> targets = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class PolicyParam {
|
||||
|
||||
@ApiModelProperty("策略ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("策略名称")
|
||||
@NotBlank(message = DiskMonitorValidMessage.POLICY_NAME_NOT_BLANK)
|
||||
private String policyName;
|
||||
|
||||
@ApiModelProperty("是否启用监控")
|
||||
private Boolean monitorEnabled;
|
||||
|
||||
@ApiModelProperty("应用启动后立即执行一次")
|
||||
private Boolean runOnAppStart;
|
||||
|
||||
@ApiModelProperty("每日统一执行时间")
|
||||
@NotBlank(message = DiskMonitorValidMessage.DAILY_RUN_TIME_NOT_BLANK)
|
||||
private String dailyRunTime;
|
||||
|
||||
@ApiModelProperty("预警通知模式")
|
||||
private String warningNotifyMode;
|
||||
|
||||
@ApiModelProperty("告警通知模式")
|
||||
private String alarmNotifyMode;
|
||||
|
||||
@ApiModelProperty("备注")
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class TargetParam {
|
||||
|
||||
@ApiModelProperty("盘符配置ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("盘符")
|
||||
@NotBlank(message = DiskMonitorValidMessage.DRIVE_LETTER_NOT_BLANK)
|
||||
private String driveLetter;
|
||||
|
||||
@ApiModelProperty("是否监控")
|
||||
private Boolean monitorEnabled;
|
||||
|
||||
@ApiModelProperty("预警使用率")
|
||||
@NotNull(message = DiskMonitorValidMessage.WARNING_USAGE_PERCENT_NOT_NULL)
|
||||
@Min(value = 1, message = DiskMonitorValidMessage.USAGE_PERCENT_FORMAT_ERROR)
|
||||
@Max(value = 100, message = DiskMonitorValidMessage.USAGE_PERCENT_FORMAT_ERROR)
|
||||
private Integer warningUsagePercent;
|
||||
|
||||
@ApiModelProperty("告警使用率")
|
||||
@NotNull(message = DiskMonitorValidMessage.ALARM_USAGE_PERCENT_NOT_NULL)
|
||||
@Min(value = 1, message = DiskMonitorValidMessage.USAGE_PERCENT_FORMAT_ERROR)
|
||||
@Max(value = 100, message = DiskMonitorValidMessage.USAGE_PERCENT_FORMAT_ERROR)
|
||||
private Integer alarmUsagePercent;
|
||||
|
||||
@ApiModelProperty("是否启用路径通知")
|
||||
private Boolean notifyPathEnabled;
|
||||
|
||||
@ApiModelProperty("路径通知列表")
|
||||
@Valid
|
||||
private List<DiskMonitorNotifyPathItem> notifyPathList = new ArrayList<>();
|
||||
|
||||
@ApiModelProperty("是否启用HTTP通知")
|
||||
private Boolean notifyHttpEnabled;
|
||||
|
||||
@ApiModelProperty("HTTP通知列表")
|
||||
@Valid
|
||||
private List<DiskMonitorNotifyHttpItem> notifyHttpList = new ArrayList<>();
|
||||
|
||||
@ApiModelProperty("备注")
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class JobRunParam {
|
||||
|
||||
@ApiModelProperty("任务来源")
|
||||
@NotBlank(message = DiskMonitorValidMessage.JOB_SOURCE_NOT_BLANK)
|
||||
private String jobSource;
|
||||
}
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class JobListParam extends BaseParam {
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class NotifyTestParam {
|
||||
|
||||
@ApiModelProperty("盘符")
|
||||
@NotBlank(message = DiskMonitorValidMessage.DRIVE_LETTER_NOT_BLANK)
|
||||
private String driveLetter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.njcn.gather.systemmonitor.disk.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 磁盘监控任务批次表。
|
||||
*/
|
||||
@Data
|
||||
@TableName("disk_monitor_job")
|
||||
public class DiskMonitorJob implements Serializable {
|
||||
private static final long serialVersionUID = 2956749403195165256L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@TableField("job_no")
|
||||
private String jobNo;
|
||||
|
||||
@TableField("job_source")
|
||||
private String jobSource;
|
||||
|
||||
@TableField("planned_time")
|
||||
private LocalDateTime plannedTime;
|
||||
|
||||
@TableField("started_at")
|
||||
private LocalDateTime startedAt;
|
||||
|
||||
@TableField("finished_at")
|
||||
private LocalDateTime finishedAt;
|
||||
|
||||
@TableField("job_status")
|
||||
private String jobStatus;
|
||||
|
||||
@TableField("target_count")
|
||||
private Integer targetCount;
|
||||
|
||||
@TableField("success_count")
|
||||
private Integer successCount;
|
||||
|
||||
@TableField("warning_count")
|
||||
private Integer warningCount;
|
||||
|
||||
@TableField("alarm_count")
|
||||
private Integer alarmCount;
|
||||
|
||||
@TableField("message")
|
||||
private String message;
|
||||
|
||||
@TableField("created_at")
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.njcn.gather.systemmonitor.disk.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 磁盘监控通知日志表。
|
||||
*/
|
||||
@Data
|
||||
@TableName("disk_monitor_notify_log")
|
||||
public class DiskMonitorNotifyLog implements Serializable {
|
||||
private static final long serialVersionUID = -8873612319853902451L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@TableField("job_id")
|
||||
private Long jobId;
|
||||
|
||||
@TableField("result_id")
|
||||
private Long resultId;
|
||||
|
||||
@TableField("target_id")
|
||||
private Long targetId;
|
||||
|
||||
@TableField("drive_letter")
|
||||
private String driveLetter;
|
||||
|
||||
@TableField("notify_level")
|
||||
private String notifyLevel;
|
||||
|
||||
@TableField("channel_type")
|
||||
private String channelType;
|
||||
|
||||
@TableField("channel_target")
|
||||
private String channelTarget;
|
||||
|
||||
@TableField("notify_title")
|
||||
private String notifyTitle;
|
||||
|
||||
@TableField("notify_content")
|
||||
private String notifyContent;
|
||||
|
||||
@TableField("send_status")
|
||||
private String sendStatus;
|
||||
|
||||
@TableField("response_message")
|
||||
private String responseMessage;
|
||||
|
||||
@TableField("sent_at")
|
||||
private LocalDateTime sentAt;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.njcn.gather.systemmonitor.disk.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
* 磁盘监控全局策略表。
|
||||
*/
|
||||
@Data
|
||||
@TableName("disk_monitor_policy")
|
||||
public class DiskMonitorPolicy implements Serializable {
|
||||
private static final long serialVersionUID = -2789228200584651740L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@TableField("policy_name")
|
||||
private String policyName;
|
||||
|
||||
@TableField("monitor_enabled")
|
||||
private Integer monitorEnabled;
|
||||
|
||||
@TableField("run_on_app_start")
|
||||
private Integer runOnAppStart;
|
||||
|
||||
@TableField("daily_run_time")
|
||||
private LocalTime dailyRunTime;
|
||||
|
||||
@TableField("warning_notify_mode")
|
||||
private String warningNotifyMode;
|
||||
|
||||
@TableField("alarm_notify_mode")
|
||||
private String alarmNotifyMode;
|
||||
|
||||
@TableField("last_job_id")
|
||||
private Long lastJobId;
|
||||
|
||||
@TableField("remark")
|
||||
private String remark;
|
||||
|
||||
@TableField("created_by")
|
||||
private String createdBy;
|
||||
|
||||
@TableField("created_at")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@TableField("updated_by")
|
||||
private String updatedBy;
|
||||
|
||||
@TableField("updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.njcn.gather.systemmonitor.disk.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 磁盘监控结果表。
|
||||
*/
|
||||
@Data
|
||||
@TableName("disk_monitor_result")
|
||||
public class DiskMonitorResult implements Serializable {
|
||||
private static final long serialVersionUID = 5557836396879348480L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@TableField("job_id")
|
||||
private Long jobId;
|
||||
|
||||
@TableField("target_id")
|
||||
private Long targetId;
|
||||
|
||||
@TableField("drive_letter")
|
||||
private String driveLetter;
|
||||
|
||||
@TableField("total_bytes")
|
||||
private Long totalBytes;
|
||||
|
||||
@TableField("used_bytes")
|
||||
private Long usedBytes;
|
||||
|
||||
@TableField("free_bytes")
|
||||
private Long freeBytes;
|
||||
|
||||
@TableField("used_percent")
|
||||
private BigDecimal usedPercent;
|
||||
|
||||
@TableField("current_status")
|
||||
private String currentStatus;
|
||||
|
||||
@TableField("previous_status")
|
||||
private String previousStatus;
|
||||
|
||||
@TableField("status_changed")
|
||||
private Integer statusChanged;
|
||||
|
||||
@TableField("should_notify")
|
||||
private Integer shouldNotify;
|
||||
|
||||
@TableField("notify_reason")
|
||||
private String notifyReason;
|
||||
|
||||
@TableField("scan_time")
|
||||
private LocalDateTime scanTime;
|
||||
|
||||
@TableField("message")
|
||||
private String message;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.njcn.gather.systemmonitor.disk.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 磁盘监控盘符配置表。
|
||||
*/
|
||||
@Data
|
||||
@TableName("disk_monitor_target")
|
||||
public class DiskMonitorTarget implements Serializable {
|
||||
private static final long serialVersionUID = -3567440027709476481L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@TableField("policy_id")
|
||||
private Long policyId;
|
||||
|
||||
@TableField("drive_letter")
|
||||
private String driveLetter;
|
||||
|
||||
@TableField("monitor_enabled")
|
||||
private Integer monitorEnabled;
|
||||
|
||||
@TableField("warning_usage_percent")
|
||||
private Integer warningUsagePercent;
|
||||
|
||||
@TableField("alarm_usage_percent")
|
||||
private Integer alarmUsagePercent;
|
||||
|
||||
@TableField("notify_path_enabled")
|
||||
private Integer notifyPathEnabled;
|
||||
|
||||
@TableField("notify_path_list_json")
|
||||
private String notifyPathListJson;
|
||||
|
||||
@TableField("notify_http_enabled")
|
||||
private Integer notifyHttpEnabled;
|
||||
|
||||
@TableField("notify_http_list_json")
|
||||
private String notifyHttpListJson;
|
||||
|
||||
@TableField("last_status")
|
||||
private String lastStatus;
|
||||
|
||||
@TableField("last_scan_time")
|
||||
private LocalDateTime lastScanTime;
|
||||
|
||||
@TableField("last_used_percent")
|
||||
private BigDecimal lastUsedPercent;
|
||||
|
||||
@TableField("remark")
|
||||
private String remark;
|
||||
|
||||
@TableField("created_by")
|
||||
private String createdBy;
|
||||
|
||||
@TableField("created_at")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@TableField("updated_by")
|
||||
private String updatedBy;
|
||||
|
||||
@TableField("updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package com.njcn.gather.systemmonitor.disk.pojo.vo;
|
||||
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.dto.DiskMonitorNotifyHttpItem;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.dto.DiskMonitorNotifyPathItem;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 磁盘监控接口返回对象。
|
||||
*/
|
||||
public class DiskMonitorVO {
|
||||
|
||||
@Data
|
||||
public static class PolicyDetailVO {
|
||||
private PolicyVO policy;
|
||||
private List<TargetVO> targets = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class PolicyVO {
|
||||
private Long id;
|
||||
private String policyName;
|
||||
private Boolean monitorEnabled;
|
||||
private Boolean runOnAppStart;
|
||||
private String dailyRunTime;
|
||||
private String warningNotifyMode;
|
||||
private String alarmNotifyMode;
|
||||
private Long lastJobId;
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class TargetVO {
|
||||
private Long id;
|
||||
private String driveLetter;
|
||||
private Boolean monitorEnabled;
|
||||
private Integer warningUsagePercent;
|
||||
private Integer alarmUsagePercent;
|
||||
private Boolean notifyPathEnabled;
|
||||
private List<DiskMonitorNotifyPathItem> notifyPathList = new ArrayList<>();
|
||||
private Boolean notifyHttpEnabled;
|
||||
private List<DiskMonitorNotifyHttpItem> notifyHttpList = new ArrayList<>();
|
||||
private String lastStatus;
|
||||
private String lastScanTime;
|
||||
private BigDecimal lastUsedPercent;
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class JobRunVO {
|
||||
private Long jobId;
|
||||
private String jobNo;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class JobListVO {
|
||||
private Long jobId;
|
||||
private String jobNo;
|
||||
private String jobSource;
|
||||
private String startedAt;
|
||||
private String finishedAt;
|
||||
private String jobStatus;
|
||||
private Integer targetCount;
|
||||
private Integer warningCount;
|
||||
private Integer alarmCount;
|
||||
private String message;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class JobDetailVO {
|
||||
private JobInfoVO job;
|
||||
private List<ResultVO> results = new ArrayList<>();
|
||||
private List<NotifyLogVO> notifyLogs = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class JobInfoVO {
|
||||
private Long id;
|
||||
private String jobNo;
|
||||
private String jobSource;
|
||||
private String startedAt;
|
||||
private String finishedAt;
|
||||
private String jobStatus;
|
||||
private Integer targetCount;
|
||||
private Integer successCount;
|
||||
private Integer warningCount;
|
||||
private Integer alarmCount;
|
||||
private String message;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ResultVO {
|
||||
private Long resultId;
|
||||
private Long targetId;
|
||||
private String driveLetter;
|
||||
private Long totalBytes;
|
||||
private Long usedBytes;
|
||||
private Long freeBytes;
|
||||
private BigDecimal usedPercent;
|
||||
private String currentStatus;
|
||||
private String previousStatus;
|
||||
private Boolean statusChanged;
|
||||
private Boolean shouldNotify;
|
||||
private String notifyReason;
|
||||
private String scanTime;
|
||||
private String message;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class NotifyLogVO {
|
||||
private Long id;
|
||||
private Long resultId;
|
||||
private String driveLetter;
|
||||
private String notifyLevel;
|
||||
private String channelType;
|
||||
private String channelTarget;
|
||||
private String sendStatus;
|
||||
private String responseMessage;
|
||||
private String sentAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.njcn.gather.systemmonitor.disk.schedule;
|
||||
|
||||
import com.njcn.gather.systemmonitor.disk.event.DiskMonitorPolicyChangedEvent;
|
||||
import com.njcn.gather.systemmonitor.disk.service.IDiskMonitorJobService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 磁盘监控启动与定时调度管理。
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DiskMonitorScheduleManager implements ApplicationRunner {
|
||||
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private final IDiskMonitorJobService diskMonitorJobService;
|
||||
private final AtomicInteger threadIndex = new AtomicInteger(1);
|
||||
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(createThreadFactory());
|
||||
private ScheduledFuture<?> scheduledFuture;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
try {
|
||||
diskMonitorJobService.executeAppStartMonitor();
|
||||
} catch (Exception exception) {
|
||||
log.error("应用启动后执行磁盘监控失败", exception);
|
||||
}
|
||||
refreshSchedule();
|
||||
}
|
||||
|
||||
@EventListener(DiskMonitorPolicyChangedEvent.class)
|
||||
public void onPolicyChanged() {
|
||||
refreshSchedule();
|
||||
}
|
||||
|
||||
public synchronized void refreshSchedule() {
|
||||
if (scheduledFuture != null) {
|
||||
scheduledFuture.cancel(false);
|
||||
scheduledFuture = null;
|
||||
}
|
||||
LocalDateTime nextRunTime = diskMonitorJobService.getNextDailyRunTime();
|
||||
if (nextRunTime == null) {
|
||||
log.info("磁盘监控每日调度未启用或未配置执行时间,跳过注册");
|
||||
return;
|
||||
}
|
||||
long delayMs = Math.max(Duration.between(LocalDateTime.now(), nextRunTime).toMillis(), 0L);
|
||||
scheduledFuture = scheduler.schedule(this::executeDailyTask, delayMs, TimeUnit.MILLISECONDS);
|
||||
log.info("磁盘监控每日调度已注册,下次执行时间:{}", nextRunTime.format(DATE_TIME_FORMATTER));
|
||||
}
|
||||
|
||||
private void executeDailyTask() {
|
||||
try {
|
||||
diskMonitorJobService.executeDailyScheduleMonitor();
|
||||
} catch (Exception exception) {
|
||||
log.error("每日磁盘监控执行失败", exception);
|
||||
} finally {
|
||||
refreshSchedule();
|
||||
}
|
||||
}
|
||||
|
||||
private ThreadFactory createThreadFactory() {
|
||||
return runnable -> {
|
||||
Thread thread = new Thread(runnable);
|
||||
thread.setName("disk-monitor-schedule-" + threadIndex.getAndIncrement());
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
};
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public synchronized void destroy() {
|
||||
if (scheduledFuture != null) {
|
||||
scheduledFuture.cancel(false);
|
||||
}
|
||||
scheduler.shutdown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.njcn.gather.systemmonitor.disk.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.param.DiskMonitorParam;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.vo.DiskMonitorVO;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 磁盘监控任务服务。
|
||||
*/
|
||||
public interface IDiskMonitorJobService {
|
||||
|
||||
DiskMonitorVO.JobRunVO runJob(DiskMonitorParam.JobRunParam param);
|
||||
|
||||
Page<DiskMonitorVO.JobListVO> listJobs(DiskMonitorParam.JobListParam param);
|
||||
|
||||
DiskMonitorVO.JobDetailVO getJobDetail(Long jobId);
|
||||
|
||||
void executeAppStartMonitor();
|
||||
|
||||
void executeDailyScheduleMonitor();
|
||||
|
||||
LocalDateTime getNextDailyRunTime();
|
||||
|
||||
void executeNotifyTest(String driveLetter);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.njcn.gather.systemmonitor.disk.service;
|
||||
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.param.DiskMonitorParam;
|
||||
|
||||
/**
|
||||
* 磁盘监控通知服务。
|
||||
*/
|
||||
public interface IDiskMonitorNotifyService {
|
||||
|
||||
boolean testNotify(DiskMonitorParam.NotifyTestParam param);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.njcn.gather.systemmonitor.disk.service;
|
||||
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.param.DiskMonitorParam;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorPolicy;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorTarget;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.vo.DiskMonitorVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 磁盘监控配置服务。
|
||||
*/
|
||||
public interface IDiskMonitorPolicyService {
|
||||
|
||||
DiskMonitorVO.PolicyDetailVO getPolicyDetail();
|
||||
|
||||
boolean savePolicy(DiskMonitorParam.PolicySaveParam param);
|
||||
|
||||
DiskMonitorPolicy getCurrentPolicy();
|
||||
|
||||
DiskMonitorPolicy getOrCreatePolicy();
|
||||
|
||||
List<DiskMonitorTarget> listEnabledTargets();
|
||||
|
||||
DiskMonitorTarget getTargetByDriveLetter(String driveLetter);
|
||||
}
|
||||
@@ -0,0 +1,517 @@
|
||||
package com.njcn.gather.systemmonitor.disk.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.gather.systemmonitor.disk.component.DiskMonitorNotificationComponent;
|
||||
import com.njcn.gather.systemmonitor.disk.constant.DiskMonitorConstant;
|
||||
import com.njcn.gather.systemmonitor.disk.enums.DiskMonitorResponseEnum;
|
||||
import com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorJobMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorNotifyLogMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorPolicyMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorResultMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorTargetMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.param.DiskMonitorParam;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorJob;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorNotifyLog;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorPolicy;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorResult;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorTarget;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.vo.DiskMonitorVO;
|
||||
import com.njcn.gather.systemmonitor.disk.service.IDiskMonitorJobService;
|
||||
import com.njcn.gather.systemmonitor.disk.service.IDiskMonitorPolicyService;
|
||||
import com.njcn.web.factory.PageFactory;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 磁盘监控任务服务实现。
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DiskMonitorJobServiceImpl implements IDiskMonitorJobService {
|
||||
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private final IDiskMonitorPolicyService diskMonitorPolicyService;
|
||||
private final DiskMonitorNotificationComponent diskMonitorNotificationComponent;
|
||||
private final DiskMonitorJobMapper jobMapper;
|
||||
private final DiskMonitorResultMapper resultMapper;
|
||||
private final DiskMonitorNotifyLogMapper notifyLogMapper;
|
||||
private final DiskMonitorTargetMapper targetMapper;
|
||||
private final DiskMonitorPolicyMapper policyMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public DiskMonitorVO.JobRunVO runJob(DiskMonitorParam.JobRunParam param) {
|
||||
String jobSource = StrUtil.blankToDefault(param.getJobSource(), DiskMonitorConstant.JOB_SOURCE_MANUAL).trim().toUpperCase();
|
||||
if (!DiskMonitorConstant.JOB_SOURCE_MANUAL.equals(jobSource)) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.JOB_SOURCE_INVALID);
|
||||
}
|
||||
return executeMonitorJob(jobSource, null, false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<DiskMonitorVO.JobListVO> listJobs(DiskMonitorParam.JobListParam param) {
|
||||
Page<DiskMonitorJob> page = jobMapper.selectPage(
|
||||
new Page<>(PageFactory.getPageNum(param), PageFactory.getPageSize(param)),
|
||||
new QueryWrapper<DiskMonitorJob>().orderByDesc("started_at", "id")
|
||||
);
|
||||
Page<DiskMonitorVO.JobListVO> resultPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
|
||||
resultPage.setRecords(page.getRecords().stream().map(this::toJobListVO).collect(Collectors.toList()));
|
||||
return resultPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiskMonitorVO.JobDetailVO getJobDetail(Long jobId) {
|
||||
DiskMonitorJob job = jobMapper.selectById(jobId);
|
||||
if (job == null) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.JOB_NOT_FOUND);
|
||||
}
|
||||
DiskMonitorVO.JobDetailVO detailVO = new DiskMonitorVO.JobDetailVO();
|
||||
detailVO.setJob(toJobInfoVO(job));
|
||||
List<DiskMonitorResult> results = resultMapper.selectList(new QueryWrapper<DiskMonitorResult>()
|
||||
.eq("job_id", jobId)
|
||||
.orderByAsc("scan_time", "id"));
|
||||
detailVO.setResults(results.stream().map(this::toResultVO).collect(Collectors.toList()));
|
||||
List<DiskMonitorNotifyLog> notifyLogs = notifyLogMapper.selectList(new QueryWrapper<DiskMonitorNotifyLog>()
|
||||
.eq("job_id", jobId)
|
||||
.orderByAsc("sent_at", "id"));
|
||||
detailVO.setNotifyLogs(notifyLogs.stream().map(this::toNotifyLogVO).collect(Collectors.toList()));
|
||||
return detailVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void executeAppStartMonitor() {
|
||||
DiskMonitorPolicy policy = diskMonitorPolicyService.getOrCreatePolicy();
|
||||
if (!isEnabled(policy.getMonitorEnabled()) || !isEnabled(policy.getRunOnAppStart())) {
|
||||
return;
|
||||
}
|
||||
executeMonitorJob(DiskMonitorConstant.JOB_SOURCE_APP_START, null, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void executeDailyScheduleMonitor() {
|
||||
DiskMonitorPolicy policy = diskMonitorPolicyService.getOrCreatePolicy();
|
||||
if (!isEnabled(policy.getMonitorEnabled()) || policy.getDailyRunTime() == null) {
|
||||
return;
|
||||
}
|
||||
executeMonitorJob(DiskMonitorConstant.JOB_SOURCE_DAILY_SCHEDULE, null, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime getNextDailyRunTime() {
|
||||
DiskMonitorPolicy policy = diskMonitorPolicyService.getOrCreatePolicy();
|
||||
if (!isEnabled(policy.getMonitorEnabled()) || policy.getDailyRunTime() == null) {
|
||||
return null;
|
||||
}
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime candidate = LocalDate.now().atTime(policy.getDailyRunTime());
|
||||
if (!candidate.isAfter(now)) {
|
||||
candidate = candidate.plusDays(1);
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void executeNotifyTest(String driveLetter) {
|
||||
executeMonitorJob(DiskMonitorConstant.JOB_SOURCE_MANUAL, driveLetter, true, true);
|
||||
}
|
||||
|
||||
private DiskMonitorVO.JobRunVO executeMonitorJob(String jobSource, String driveLetter, boolean forceNotify, boolean failWhenNoTarget) {
|
||||
validateJobSource(jobSource);
|
||||
List<DiskMonitorTarget> targets = resolveExecutionTargets(driveLetter);
|
||||
if (targets.isEmpty()) {
|
||||
logNoExecutionTargets(jobSource, driveLetter);
|
||||
if (failWhenNoTarget) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.NO_ENABLED_TARGET);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
DiskMonitorJob job = new DiskMonitorJob();
|
||||
job.setJobNo(generateJobNo());
|
||||
job.setJobSource(jobSource);
|
||||
job.setPlannedTime(now);
|
||||
job.setStartedAt(now);
|
||||
job.setJobStatus(DiskMonitorConstant.JOB_STATUS_RUNNING);
|
||||
job.setTargetCount(targets.size());
|
||||
job.setSuccessCount(0);
|
||||
job.setWarningCount(0);
|
||||
job.setAlarmCount(0);
|
||||
job.setMessage(forceNotify ? "通知测试任务" : null);
|
||||
jobMapper.insert(job);
|
||||
|
||||
int successCount = 0;
|
||||
int warningCount = 0;
|
||||
int alarmCount = 0;
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
DiskMonitorPolicy policy = diskMonitorPolicyService.getOrCreatePolicy();
|
||||
|
||||
for (DiskMonitorTarget target : targets) {
|
||||
try {
|
||||
ScanSnapshot snapshot = resolveSnapshotStatus(target, scanDrive(target.getDriveLetter()));
|
||||
if (snapshot.isSuccess()) {
|
||||
successCount++;
|
||||
}
|
||||
if (DiskMonitorConstant.STATUS_WARNING.equals(snapshot.getCurrentStatus())) {
|
||||
warningCount++;
|
||||
}
|
||||
if (DiskMonitorConstant.STATUS_ALARM.equals(snapshot.getCurrentStatus())) {
|
||||
alarmCount++;
|
||||
}
|
||||
|
||||
NotifyDecision notifyDecision = resolveNotifyDecision(target, snapshot.getCurrentStatus(), forceNotify);
|
||||
DiskMonitorResult result = buildResult(job, target, snapshot, notifyDecision);
|
||||
resultMapper.insert(result);
|
||||
|
||||
if (notifyDecision.isShouldNotify()) {
|
||||
diskMonitorNotificationComponent.sendNotifications(job, target, result,
|
||||
snapshot.getUsedPercent(), snapshot.getCurrentStatus(),
|
||||
notifyDecision.getNotifyReason(), notifyDecision.getNotifyLevel(),
|
||||
snapshot.getScanTime(), snapshot.getMessage());
|
||||
}
|
||||
|
||||
updateTargetLastState(target, snapshot);
|
||||
} catch (Exception exception) {
|
||||
log.error("磁盘监控执行异常,driveLetter={}", target.getDriveLetter(), exception);
|
||||
errorMessages.add(target.getDriveLetter() + ":" + exception.getMessage());
|
||||
ScanSnapshot failedSnapshot = ScanSnapshot.failed(exception.getMessage());
|
||||
DiskMonitorResult result = buildResult(job, target, failedSnapshot,
|
||||
new NotifyDecision(false, DiskMonitorConstant.NOTIFY_REASON_NO_NOTIFY, resolveNotifyLevel(failedSnapshot.getCurrentStatus())));
|
||||
resultMapper.insert(result);
|
||||
updateTargetLastState(target, failedSnapshot);
|
||||
}
|
||||
}
|
||||
|
||||
finishJob(job, policy, successCount, warningCount, alarmCount, errorMessages);
|
||||
DiskMonitorVO.JobRunVO runVO = new DiskMonitorVO.JobRunVO();
|
||||
runVO.setJobId(job.getId());
|
||||
runVO.setJobNo(job.getJobNo());
|
||||
return runVO;
|
||||
}
|
||||
|
||||
private void finishJob(DiskMonitorJob job, DiskMonitorPolicy policy, int successCount, int warningCount,
|
||||
int alarmCount, List<String> errorMessages) {
|
||||
job.setSuccessCount(successCount);
|
||||
job.setWarningCount(warningCount);
|
||||
job.setAlarmCount(alarmCount);
|
||||
job.setFinishedAt(LocalDateTime.now());
|
||||
if (successCount == job.getTargetCount()) {
|
||||
job.setJobStatus(DiskMonitorConstant.JOB_STATUS_SUCCESS);
|
||||
} else if (successCount == 0) {
|
||||
job.setJobStatus(DiskMonitorConstant.JOB_STATUS_FAILED);
|
||||
} else {
|
||||
job.setJobStatus(DiskMonitorConstant.JOB_STATUS_PARTIAL_SUCCESS);
|
||||
}
|
||||
if (!errorMessages.isEmpty()) {
|
||||
job.setMessage(String.join(";", errorMessages));
|
||||
}
|
||||
jobMapper.updateById(job);
|
||||
|
||||
policy.setLastJobId(job.getId());
|
||||
policyMapper.updateById(policy);
|
||||
}
|
||||
|
||||
private DiskMonitorResult buildResult(DiskMonitorJob job, DiskMonitorTarget target, ScanSnapshot snapshot, NotifyDecision notifyDecision) {
|
||||
DiskMonitorResult result = new DiskMonitorResult();
|
||||
result.setJobId(job.getId());
|
||||
result.setTargetId(target.getId());
|
||||
result.setDriveLetter(target.getDriveLetter());
|
||||
result.setTotalBytes(snapshot.getTotalBytes());
|
||||
result.setUsedBytes(snapshot.getUsedBytes());
|
||||
result.setFreeBytes(snapshot.getFreeBytes());
|
||||
result.setUsedPercent(snapshot.getUsedPercent());
|
||||
result.setCurrentStatus(snapshot.getCurrentStatus());
|
||||
result.setPreviousStatus(resolvePreviousStatus(target.getLastStatus()));
|
||||
result.setStatusChanged(snapshot.getCurrentStatus().equals(resolvePreviousStatus(target.getLastStatus())) ? 0 : 1);
|
||||
result.setShouldNotify(notifyDecision.isShouldNotify() ? 1 : 0);
|
||||
result.setNotifyReason(notifyDecision.getNotifyReason());
|
||||
result.setScanTime(snapshot.getScanTime());
|
||||
result.setMessage(snapshot.getMessage());
|
||||
return result;
|
||||
}
|
||||
|
||||
private void updateTargetLastState(DiskMonitorTarget target, ScanSnapshot snapshot) {
|
||||
target.setLastStatus(snapshot.getCurrentStatus());
|
||||
target.setLastScanTime(snapshot.getScanTime());
|
||||
target.setLastUsedPercent(snapshot.getUsedPercent());
|
||||
targetMapper.updateById(target);
|
||||
}
|
||||
|
||||
private NotifyDecision resolveNotifyDecision(DiskMonitorTarget target, String currentStatus, boolean forceNotify) {
|
||||
String previousStatus = resolvePreviousStatus(target.getLastStatus());
|
||||
if (forceNotify) {
|
||||
return new NotifyDecision(true, DiskMonitorConstant.NOTIFY_REASON_STATUS_CHANGED, resolveNotifyLevel(currentStatus));
|
||||
}
|
||||
if (DiskMonitorConstant.STATUS_ALARM.equals(currentStatus)) {
|
||||
return new NotifyDecision(true, DiskMonitorConstant.NOTIFY_REASON_ALARM_EVERY_TIME, DiskMonitorConstant.NOTIFY_LEVEL_ALARM);
|
||||
}
|
||||
if (DiskMonitorConstant.STATUS_WARNING.equals(currentStatus) && !DiskMonitorConstant.STATUS_WARNING.equals(previousStatus)) {
|
||||
return new NotifyDecision(true, DiskMonitorConstant.NOTIFY_REASON_STATUS_CHANGED, DiskMonitorConstant.NOTIFY_LEVEL_WARNING);
|
||||
}
|
||||
if (DiskMonitorConstant.STATUS_NORMAL.equals(currentStatus)
|
||||
&& (DiskMonitorConstant.STATUS_WARNING.equals(previousStatus) || DiskMonitorConstant.STATUS_ALARM.equals(previousStatus))) {
|
||||
return new NotifyDecision(true, DiskMonitorConstant.NOTIFY_REASON_STATUS_CHANGED, DiskMonitorConstant.NOTIFY_LEVEL_RECOVER);
|
||||
}
|
||||
return new NotifyDecision(false, DiskMonitorConstant.NOTIFY_REASON_NO_NOTIFY, resolveNotifyLevel(currentStatus));
|
||||
}
|
||||
|
||||
private String resolveNotifyLevel(String currentStatus) {
|
||||
if (DiskMonitorConstant.STATUS_ALARM.equals(currentStatus)) {
|
||||
return DiskMonitorConstant.NOTIFY_LEVEL_ALARM;
|
||||
}
|
||||
if (DiskMonitorConstant.STATUS_WARNING.equals(currentStatus)) {
|
||||
return DiskMonitorConstant.NOTIFY_LEVEL_WARNING;
|
||||
}
|
||||
return DiskMonitorConstant.NOTIFY_LEVEL_RECOVER;
|
||||
}
|
||||
|
||||
private ScanSnapshot scanDrive(String driveLetter) {
|
||||
File driveRoot = new File(driveLetter + File.separator);
|
||||
if (!driveRoot.exists()) {
|
||||
log.warn("磁盘监控扫描跳过,监控盘符不存在或当前运行账号无访问权限,driveLetter={}", driveLetter);
|
||||
return ScanSnapshot.failed("盘符不存在或当前运行账户无访问权限");
|
||||
}
|
||||
long totalBytes = driveRoot.getTotalSpace();
|
||||
if (totalBytes <= 0) {
|
||||
log.warn("磁盘监控扫描失败,未读取到有效磁盘容量,driveLetter={}", driveLetter);
|
||||
return ScanSnapshot.failed("未读取到有效磁盘容量");
|
||||
}
|
||||
long freeBytes = driveRoot.getUsableSpace();
|
||||
long usedBytes = totalBytes - freeBytes;
|
||||
BigDecimal usedPercent = BigDecimal.valueOf(usedBytes)
|
||||
.multiply(BigDecimal.valueOf(100))
|
||||
.divide(BigDecimal.valueOf(totalBytes), 2, RoundingMode.HALF_UP);
|
||||
return new ScanSnapshot(true, totalBytes, usedBytes, freeBytes, usedPercent, LocalDateTime.now(),
|
||||
DiskMonitorConstant.STATUS_UNKNOWN, null);
|
||||
}
|
||||
|
||||
private ScanSnapshot resolveSnapshotStatus(DiskMonitorTarget target, ScanSnapshot snapshot) {
|
||||
if (!snapshot.isSuccess()) {
|
||||
return snapshot;
|
||||
}
|
||||
String currentStatus;
|
||||
if (snapshot.getUsedPercent().compareTo(BigDecimal.valueOf(target.getAlarmUsagePercent())) >= 0) {
|
||||
currentStatus = DiskMonitorConstant.STATUS_ALARM;
|
||||
} else if (snapshot.getUsedPercent().compareTo(BigDecimal.valueOf(target.getWarningUsagePercent())) >= 0) {
|
||||
currentStatus = DiskMonitorConstant.STATUS_WARNING;
|
||||
} else {
|
||||
currentStatus = DiskMonitorConstant.STATUS_NORMAL;
|
||||
}
|
||||
return new ScanSnapshot(true, snapshot.getTotalBytes(), snapshot.getUsedBytes(), snapshot.getFreeBytes(),
|
||||
snapshot.getUsedPercent(), snapshot.getScanTime(), currentStatus, snapshot.getMessage());
|
||||
}
|
||||
|
||||
private List<DiskMonitorTarget> resolveExecutionTargets(String driveLetter) {
|
||||
if (StrUtil.isNotBlank(driveLetter)) {
|
||||
DiskMonitorTarget target = diskMonitorPolicyService.getTargetByDriveLetter(driveLetter);
|
||||
return target == null ? Collections.emptyList() : Collections.singletonList(target);
|
||||
}
|
||||
return diskMonitorPolicyService.listEnabledTargets();
|
||||
}
|
||||
|
||||
private void logNoExecutionTargets(String jobSource, String driveLetter) {
|
||||
if (StrUtil.isNotBlank(driveLetter)) {
|
||||
log.warn("磁盘监控执行跳过,未找到可执行的盘符配置,jobSource={}, driveLetter={}", jobSource, driveLetter);
|
||||
return;
|
||||
}
|
||||
log.warn("磁盘监控执行跳过,暂无启用的磁盘监控盘符配置,jobSource={}", jobSource);
|
||||
}
|
||||
|
||||
private void validateJobSource(String jobSource) {
|
||||
if (!DiskMonitorConstant.JOB_SOURCE_APP_START.equals(jobSource)
|
||||
&& !DiskMonitorConstant.JOB_SOURCE_DAILY_SCHEDULE.equals(jobSource)
|
||||
&& !DiskMonitorConstant.JOB_SOURCE_MANUAL.equals(jobSource)) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.JOB_SOURCE_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEnabled(Integer value) {
|
||||
return value != null && value == 1;
|
||||
}
|
||||
|
||||
private String resolvePreviousStatus(String previousStatus) {
|
||||
return StrUtil.isBlank(previousStatus) ? DiskMonitorConstant.STATUS_UNKNOWN : previousStatus;
|
||||
}
|
||||
|
||||
private String formatDateTime(LocalDateTime dateTime) {
|
||||
return dateTime == null ? null : dateTime.format(DATE_TIME_FORMATTER);
|
||||
}
|
||||
|
||||
private String generateJobNo() {
|
||||
return "DM" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
|
||||
}
|
||||
|
||||
private DiskMonitorVO.JobListVO toJobListVO(DiskMonitorJob job) {
|
||||
DiskMonitorVO.JobListVO jobListVO = new DiskMonitorVO.JobListVO();
|
||||
jobListVO.setJobId(job.getId());
|
||||
jobListVO.setJobNo(job.getJobNo());
|
||||
jobListVO.setJobSource(job.getJobSource());
|
||||
jobListVO.setStartedAt(formatDateTime(job.getStartedAt()));
|
||||
jobListVO.setFinishedAt(formatDateTime(job.getFinishedAt()));
|
||||
jobListVO.setJobStatus(job.getJobStatus());
|
||||
jobListVO.setTargetCount(job.getTargetCount());
|
||||
jobListVO.setWarningCount(job.getWarningCount());
|
||||
jobListVO.setAlarmCount(job.getAlarmCount());
|
||||
jobListVO.setMessage(job.getMessage());
|
||||
return jobListVO;
|
||||
}
|
||||
|
||||
private DiskMonitorVO.JobInfoVO toJobInfoVO(DiskMonitorJob job) {
|
||||
DiskMonitorVO.JobInfoVO jobInfoVO = new DiskMonitorVO.JobInfoVO();
|
||||
jobInfoVO.setId(job.getId());
|
||||
jobInfoVO.setJobNo(job.getJobNo());
|
||||
jobInfoVO.setJobSource(job.getJobSource());
|
||||
jobInfoVO.setStartedAt(formatDateTime(job.getStartedAt()));
|
||||
jobInfoVO.setFinishedAt(formatDateTime(job.getFinishedAt()));
|
||||
jobInfoVO.setJobStatus(job.getJobStatus());
|
||||
jobInfoVO.setTargetCount(job.getTargetCount());
|
||||
jobInfoVO.setSuccessCount(job.getSuccessCount());
|
||||
jobInfoVO.setWarningCount(job.getWarningCount());
|
||||
jobInfoVO.setAlarmCount(job.getAlarmCount());
|
||||
jobInfoVO.setMessage(job.getMessage());
|
||||
return jobInfoVO;
|
||||
}
|
||||
|
||||
private DiskMonitorVO.ResultVO toResultVO(DiskMonitorResult result) {
|
||||
DiskMonitorVO.ResultVO resultVO = new DiskMonitorVO.ResultVO();
|
||||
resultVO.setResultId(result.getId());
|
||||
resultVO.setTargetId(result.getTargetId());
|
||||
resultVO.setDriveLetter(result.getDriveLetter());
|
||||
resultVO.setTotalBytes(result.getTotalBytes());
|
||||
resultVO.setUsedBytes(result.getUsedBytes());
|
||||
resultVO.setFreeBytes(result.getFreeBytes());
|
||||
resultVO.setUsedPercent(result.getUsedPercent());
|
||||
resultVO.setCurrentStatus(result.getCurrentStatus());
|
||||
resultVO.setPreviousStatus(result.getPreviousStatus());
|
||||
resultVO.setStatusChanged(Objects.equals(result.getStatusChanged(), 1));
|
||||
resultVO.setShouldNotify(Objects.equals(result.getShouldNotify(), 1));
|
||||
resultVO.setNotifyReason(result.getNotifyReason());
|
||||
resultVO.setScanTime(formatDateTime(result.getScanTime()));
|
||||
resultVO.setMessage(result.getMessage());
|
||||
return resultVO;
|
||||
}
|
||||
|
||||
private DiskMonitorVO.NotifyLogVO toNotifyLogVO(DiskMonitorNotifyLog notifyLog) {
|
||||
DiskMonitorVO.NotifyLogVO notifyLogVO = new DiskMonitorVO.NotifyLogVO();
|
||||
notifyLogVO.setId(notifyLog.getId());
|
||||
notifyLogVO.setResultId(notifyLog.getResultId());
|
||||
notifyLogVO.setDriveLetter(notifyLog.getDriveLetter());
|
||||
notifyLogVO.setNotifyLevel(notifyLog.getNotifyLevel());
|
||||
notifyLogVO.setChannelType(notifyLog.getChannelType());
|
||||
notifyLogVO.setChannelTarget(notifyLog.getChannelTarget());
|
||||
notifyLogVO.setSendStatus(notifyLog.getSendStatus());
|
||||
notifyLogVO.setResponseMessage(notifyLog.getResponseMessage());
|
||||
notifyLogVO.setSentAt(formatDateTime(notifyLog.getSentAt()));
|
||||
return notifyLogVO;
|
||||
}
|
||||
|
||||
private static class NotifyDecision {
|
||||
private final boolean shouldNotify;
|
||||
private final String notifyReason;
|
||||
private final String notifyLevel;
|
||||
|
||||
private NotifyDecision(boolean shouldNotify, String notifyReason, String notifyLevel) {
|
||||
this.shouldNotify = shouldNotify;
|
||||
this.notifyReason = notifyReason;
|
||||
this.notifyLevel = notifyLevel;
|
||||
}
|
||||
|
||||
public boolean isShouldNotify() {
|
||||
return shouldNotify;
|
||||
}
|
||||
|
||||
public String getNotifyReason() {
|
||||
return notifyReason;
|
||||
}
|
||||
|
||||
public String getNotifyLevel() {
|
||||
return notifyLevel;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ScanSnapshot {
|
||||
private final boolean success;
|
||||
private final Long totalBytes;
|
||||
private final Long usedBytes;
|
||||
private final Long freeBytes;
|
||||
private final BigDecimal usedPercent;
|
||||
private final LocalDateTime scanTime;
|
||||
private final String currentStatus;
|
||||
private final String message;
|
||||
|
||||
private ScanSnapshot(boolean success, Long totalBytes, Long usedBytes, Long freeBytes,
|
||||
BigDecimal usedPercent, LocalDateTime scanTime, String currentStatus, String message) {
|
||||
this.success = success;
|
||||
this.totalBytes = totalBytes;
|
||||
this.usedBytes = usedBytes;
|
||||
this.freeBytes = freeBytes;
|
||||
this.usedPercent = usedPercent == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) : usedPercent;
|
||||
this.scanTime = scanTime == null ? LocalDateTime.now() : scanTime;
|
||||
this.currentStatus = StrUtil.blankToDefault(currentStatus, DiskMonitorConstant.STATUS_UNKNOWN);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public static ScanSnapshot failed(String message) {
|
||||
return new ScanSnapshot(false, 0L, 0L, 0L, BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP),
|
||||
LocalDateTime.now(), DiskMonitorConstant.STATUS_UNKNOWN, message);
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public Long getTotalBytes() {
|
||||
return totalBytes;
|
||||
}
|
||||
|
||||
public Long getUsedBytes() {
|
||||
return usedBytes;
|
||||
}
|
||||
|
||||
public Long getFreeBytes() {
|
||||
return freeBytes;
|
||||
}
|
||||
|
||||
public BigDecimal getUsedPercent() {
|
||||
return usedPercent;
|
||||
}
|
||||
|
||||
public LocalDateTime getScanTime() {
|
||||
return scanTime;
|
||||
}
|
||||
|
||||
public String getCurrentStatus() {
|
||||
if (!success || totalBytes == null || totalBytes <= 0) {
|
||||
return DiskMonitorConstant.STATUS_UNKNOWN;
|
||||
}
|
||||
return currentStatus == null ? DiskMonitorConstant.STATUS_NORMAL : currentStatus;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.njcn.gather.systemmonitor.disk.service.impl;
|
||||
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.gather.systemmonitor.disk.enums.DiskMonitorResponseEnum;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.param.DiskMonitorParam;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorTarget;
|
||||
import com.njcn.gather.systemmonitor.disk.service.IDiskMonitorJobService;
|
||||
import com.njcn.gather.systemmonitor.disk.service.IDiskMonitorNotifyService;
|
||||
import com.njcn.gather.systemmonitor.disk.service.IDiskMonitorPolicyService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 磁盘监控通知服务实现。
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DiskMonitorNotifyServiceImpl implements IDiskMonitorNotifyService {
|
||||
|
||||
private final IDiskMonitorPolicyService diskMonitorPolicyService;
|
||||
private final IDiskMonitorJobService diskMonitorJobService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean testNotify(DiskMonitorParam.NotifyTestParam param) {
|
||||
DiskMonitorTarget target = diskMonitorPolicyService.getTargetByDriveLetter(param.getDriveLetter());
|
||||
if (target == null) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.NOTIFY_TARGET_NOT_FOUND);
|
||||
}
|
||||
diskMonitorJobService.executeNotifyTest(target.getDriveLetter());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
package com.njcn.gather.systemmonitor.disk.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.gather.systemmonitor.disk.constant.DiskMonitorConstant;
|
||||
import com.njcn.gather.systemmonitor.disk.enums.DiskMonitorResponseEnum;
|
||||
import com.njcn.gather.systemmonitor.disk.event.DiskMonitorPolicyChangedEvent;
|
||||
import com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorPolicyMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.mapper.DiskMonitorTargetMapper;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.dto.DiskMonitorNotifyHttpItem;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.dto.DiskMonitorNotifyPathItem;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.param.DiskMonitorParam;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorPolicy;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.po.DiskMonitorTarget;
|
||||
import com.njcn.gather.systemmonitor.disk.pojo.vo.DiskMonitorVO;
|
||||
import com.njcn.gather.systemmonitor.disk.service.IDiskMonitorPolicyService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.net.URL;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 磁盘监控配置服务实现。
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DiskMonitorPolicyServiceImpl implements IDiskMonitorPolicyService {
|
||||
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
|
||||
private static final TypeReference<List<DiskMonitorNotifyPathItem>> PATH_LIST_TYPE = new TypeReference<List<DiskMonitorNotifyPathItem>>() {
|
||||
};
|
||||
private static final TypeReference<List<DiskMonitorNotifyHttpItem>> HTTP_LIST_TYPE = new TypeReference<List<DiskMonitorNotifyHttpItem>>() {
|
||||
};
|
||||
|
||||
private final DiskMonitorPolicyMapper policyMapper;
|
||||
private final DiskMonitorTargetMapper targetMapper;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public DiskMonitorVO.PolicyDetailVO getPolicyDetail() {
|
||||
DiskMonitorPolicy policy = getOrCreatePolicy();
|
||||
DiskMonitorVO.PolicyDetailVO detailVO = new DiskMonitorVO.PolicyDetailVO();
|
||||
detailVO.setPolicy(toPolicyVO(policy));
|
||||
detailVO.setTargets(listTargetsByPolicyId(policy.getId()).stream().map(this::toTargetVO).collect(Collectors.toList()));
|
||||
return detailVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean savePolicy(DiskMonitorParam.PolicySaveParam param) {
|
||||
validateSaveParam(param);
|
||||
DiskMonitorPolicy currentPolicy = getOrCreatePolicy();
|
||||
DiskMonitorParam.PolicyParam policyParam = param.getPolicy();
|
||||
|
||||
currentPolicy.setPolicyName(policyParam.getPolicyName().trim());
|
||||
currentPolicy.setMonitorEnabled(boolToInt(policyParam.getMonitorEnabled(), true));
|
||||
currentPolicy.setRunOnAppStart(boolToInt(policyParam.getRunOnAppStart(), true));
|
||||
currentPolicy.setDailyRunTime(parseTime(policyParam.getDailyRunTime()));
|
||||
currentPolicy.setWarningNotifyMode(resolveWarningNotifyMode(policyParam.getWarningNotifyMode()));
|
||||
currentPolicy.setAlarmNotifyMode(resolveAlarmNotifyMode(policyParam.getAlarmNotifyMode()));
|
||||
currentPolicy.setRemark(policyParam.getRemark());
|
||||
if (policyMapper.updateById(currentPolicy) <= 0) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.POLICY_SAVE_FAILED);
|
||||
}
|
||||
|
||||
List<DiskMonitorTarget> existingTargets = listTargetsByPolicyId(currentPolicy.getId());
|
||||
Map<Long, DiskMonitorTarget> existingById = existingTargets.stream()
|
||||
.collect(Collectors.toMap(DiskMonitorTarget::getId, item -> item, (left, right) -> left, LinkedHashMap::new));
|
||||
Map<String, DiskMonitorTarget> existingByDrive = existingTargets.stream()
|
||||
.collect(Collectors.toMap(item -> normalizeDriveLetter(item.getDriveLetter()), item -> item, (left, right) -> left, LinkedHashMap::new));
|
||||
|
||||
List<Long> keepIds = new ArrayList<>();
|
||||
for (DiskMonitorParam.TargetParam targetParam : param.getTargets()) {
|
||||
String driveLetter = normalizeDriveLetter(targetParam.getDriveLetter());
|
||||
DiskMonitorTarget target = targetParam.getId() == null ? null : existingById.get(targetParam.getId());
|
||||
if (target == null) {
|
||||
target = existingByDrive.get(driveLetter);
|
||||
}
|
||||
if (target == null) {
|
||||
target = new DiskMonitorTarget();
|
||||
target.setPolicyId(currentPolicy.getId());
|
||||
target.setDriveLetter(driveLetter);
|
||||
target.setLastStatus(DiskMonitorConstant.STATUS_UNKNOWN);
|
||||
}
|
||||
fillTarget(target, targetParam, driveLetter);
|
||||
if (target.getId() == null) {
|
||||
targetMapper.insert(target);
|
||||
} else {
|
||||
targetMapper.updateById(target);
|
||||
}
|
||||
keepIds.add(target.getId());
|
||||
}
|
||||
|
||||
List<Long> deleteIds = existingTargets.stream()
|
||||
.map(DiskMonitorTarget::getId)
|
||||
.filter(id -> !keepIds.contains(id))
|
||||
.collect(Collectors.toList());
|
||||
if (!deleteIds.isEmpty()) {
|
||||
targetMapper.deleteBatchIds(deleteIds);
|
||||
}
|
||||
|
||||
applicationEventPublisher.publishEvent(new DiskMonitorPolicyChangedEvent());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiskMonitorPolicy getCurrentPolicy() {
|
||||
return policyMapper.selectOne(new QueryWrapper<DiskMonitorPolicy>().orderByAsc("id").last("LIMIT 1"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public DiskMonitorPolicy getOrCreatePolicy() {
|
||||
DiskMonitorPolicy policy = getCurrentPolicy();
|
||||
if (policy != null) {
|
||||
return policy;
|
||||
}
|
||||
policy = new DiskMonitorPolicy();
|
||||
policy.setPolicyName(DiskMonitorConstant.DEFAULT_POLICY_NAME);
|
||||
policy.setMonitorEnabled(1);
|
||||
policy.setRunOnAppStart(1);
|
||||
policy.setDailyRunTime(parseTime(DiskMonitorConstant.DEFAULT_DAILY_RUN_TIME));
|
||||
policy.setWarningNotifyMode(DiskMonitorConstant.WARNING_NOTIFY_MODE_STATUS_CHANGE);
|
||||
policy.setAlarmNotifyMode(DiskMonitorConstant.ALARM_NOTIFY_MODE_EVERY_TIME);
|
||||
policyMapper.insert(policy);
|
||||
return policy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DiskMonitorTarget> listEnabledTargets() {
|
||||
return targetMapper.selectList(new QueryWrapper<DiskMonitorTarget>()
|
||||
.eq("monitor_enabled", 1)
|
||||
.orderByAsc("drive_letter", "id"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiskMonitorTarget getTargetByDriveLetter(String driveLetter) {
|
||||
return targetMapper.selectOne(new QueryWrapper<DiskMonitorTarget>()
|
||||
.eq("drive_letter", normalizeDriveLetter(driveLetter))
|
||||
.last("LIMIT 1"));
|
||||
}
|
||||
|
||||
private List<DiskMonitorTarget> listTargetsByPolicyId(Long policyId) {
|
||||
return targetMapper.selectList(new QueryWrapper<DiskMonitorTarget>()
|
||||
.eq("policy_id", policyId)
|
||||
.orderByAsc("drive_letter", "id"));
|
||||
}
|
||||
|
||||
private void fillTarget(DiskMonitorTarget target, DiskMonitorParam.TargetParam targetParam, String driveLetter) {
|
||||
target.setDriveLetter(driveLetter);
|
||||
target.setMonitorEnabled(boolToInt(targetParam.getMonitorEnabled(), true));
|
||||
target.setWarningUsagePercent(targetParam.getWarningUsagePercent());
|
||||
target.setAlarmUsagePercent(targetParam.getAlarmUsagePercent());
|
||||
target.setNotifyPathEnabled(boolToInt(targetParam.getNotifyPathEnabled(), false));
|
||||
target.setNotifyPathListJson(writeValueAsJson(targetParam.getNotifyPathList()));
|
||||
target.setNotifyHttpEnabled(boolToInt(targetParam.getNotifyHttpEnabled(), false));
|
||||
target.setNotifyHttpListJson(writeValueAsJson(targetParam.getNotifyHttpList()));
|
||||
target.setRemark(targetParam.getRemark());
|
||||
}
|
||||
|
||||
private void validateSaveParam(DiskMonitorParam.PolicySaveParam param) {
|
||||
DiskMonitorParam.PolicyParam policyParam = param.getPolicy();
|
||||
parseTime(policyParam.getDailyRunTime());
|
||||
resolveWarningNotifyMode(policyParam.getWarningNotifyMode());
|
||||
resolveAlarmNotifyMode(policyParam.getAlarmNotifyMode());
|
||||
|
||||
Map<String, Boolean> driveMap = new LinkedHashMap<>();
|
||||
for (DiskMonitorParam.TargetParam targetParam : param.getTargets()) {
|
||||
String driveLetter = normalizeDriveLetter(targetParam.getDriveLetter());
|
||||
if (driveMap.put(driveLetter, Boolean.TRUE) != null) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.DRIVE_LETTER_REPEAT);
|
||||
}
|
||||
if (targetParam.getAlarmUsagePercent() < targetParam.getWarningUsagePercent()) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.USAGE_PERCENT_INVALID);
|
||||
}
|
||||
if (Boolean.TRUE.equals(targetParam.getNotifyPathEnabled())
|
||||
&& (targetParam.getNotifyPathList() == null || targetParam.getNotifyPathList().isEmpty())) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.NOTIFY_PATH_EMPTY);
|
||||
}
|
||||
if (Boolean.TRUE.equals(targetParam.getNotifyHttpEnabled())
|
||||
&& (targetParam.getNotifyHttpList() == null || targetParam.getNotifyHttpList().isEmpty())) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.NOTIFY_HTTP_EMPTY);
|
||||
}
|
||||
if (targetParam.getNotifyPathList() != null) {
|
||||
for (DiskMonitorNotifyPathItem item : targetParam.getNotifyPathList()) {
|
||||
if (StrUtil.isBlank(item.getPath())) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.NOTIFY_PATH_VALUE_EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (targetParam.getNotifyHttpList() != null) {
|
||||
for (DiskMonitorNotifyHttpItem item : targetParam.getNotifyHttpList()) {
|
||||
validateHttpUrl(item.getUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveWarningNotifyMode(String mode) {
|
||||
String value = StrUtil.blankToDefault(mode, DiskMonitorConstant.WARNING_NOTIFY_MODE_STATUS_CHANGE).trim().toUpperCase(Locale.ROOT);
|
||||
if (!DiskMonitorConstant.WARNING_NOTIFY_MODE_STATUS_CHANGE.equals(value)) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.POLICY_MODE_INVALID);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private String resolveAlarmNotifyMode(String mode) {
|
||||
String value = StrUtil.blankToDefault(mode, DiskMonitorConstant.ALARM_NOTIFY_MODE_EVERY_TIME).trim().toUpperCase(Locale.ROOT);
|
||||
if (!DiskMonitorConstant.ALARM_NOTIFY_MODE_EVERY_TIME.equals(value)) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.POLICY_MODE_INVALID);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private void validateHttpUrl(String url) {
|
||||
try {
|
||||
URL httpUrl = new URL(url);
|
||||
httpUrl.toURI();
|
||||
String protocol = httpUrl.getProtocol();
|
||||
if (!"http".equalsIgnoreCase(protocol) && !"https".equalsIgnoreCase(protocol)) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.NOTIFY_HTTP_URL_INVALID);
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.NOTIFY_HTTP_URL_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
private String normalizeDriveLetter(String driveLetter) {
|
||||
if (StrUtil.isBlank(driveLetter)) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.DRIVE_LETTER_FORMAT_ERROR);
|
||||
}
|
||||
String normalized = driveLetter.trim().toUpperCase(Locale.ROOT);
|
||||
if (!normalized.matches("^[A-Z]:$")) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.DRIVE_LETTER_FORMAT_ERROR);
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
private LocalTime parseTime(String time) {
|
||||
try {
|
||||
return LocalTime.parse(time, TIME_FORMATTER);
|
||||
} catch (DateTimeParseException exception) {
|
||||
throw new BusinessException(DiskMonitorResponseEnum.DAILY_RUN_TIME_FORMAT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
private int boolToInt(Boolean value, boolean defaultValue) {
|
||||
return Boolean.TRUE.equals(value == null ? defaultValue : value) ? 1 : 0;
|
||||
}
|
||||
|
||||
private boolean isEnabled(Integer value) {
|
||||
return value != null && value == 1;
|
||||
}
|
||||
|
||||
private String writeValueAsJson(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return objectMapper.writeValueAsString(value);
|
||||
} catch (JsonProcessingException exception) {
|
||||
throw new BusinessException(CommonResponseEnum.JSON_CONVERT_EXCEPTION, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private List<DiskMonitorNotifyPathItem> parsePathItems(String json) {
|
||||
return readJsonList(json, PATH_LIST_TYPE);
|
||||
}
|
||||
|
||||
private List<DiskMonitorNotifyHttpItem> parseHttpItems(String json) {
|
||||
return readJsonList(json, HTTP_LIST_TYPE);
|
||||
}
|
||||
|
||||
private <T> List<T> readJsonList(String json, TypeReference<List<T>> typeReference) {
|
||||
if (StrUtil.isBlank(json)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
try {
|
||||
List<T> result = objectMapper.readValue(json, typeReference);
|
||||
return result == null ? new ArrayList<>() : result;
|
||||
} catch (Exception exception) {
|
||||
throw new BusinessException(CommonResponseEnum.JSON_CONVERT_EXCEPTION, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private DiskMonitorVO.PolicyVO toPolicyVO(DiskMonitorPolicy policy) {
|
||||
DiskMonitorVO.PolicyVO policyVO = new DiskMonitorVO.PolicyVO();
|
||||
policyVO.setId(policy.getId());
|
||||
policyVO.setPolicyName(policy.getPolicyName());
|
||||
policyVO.setMonitorEnabled(isEnabled(policy.getMonitorEnabled()));
|
||||
policyVO.setRunOnAppStart(isEnabled(policy.getRunOnAppStart()));
|
||||
policyVO.setDailyRunTime(policy.getDailyRunTime() == null ? null : policy.getDailyRunTime().format(TIME_FORMATTER));
|
||||
policyVO.setWarningNotifyMode(policy.getWarningNotifyMode());
|
||||
policyVO.setAlarmNotifyMode(policy.getAlarmNotifyMode());
|
||||
policyVO.setLastJobId(policy.getLastJobId());
|
||||
policyVO.setRemark(policy.getRemark());
|
||||
return policyVO;
|
||||
}
|
||||
|
||||
private DiskMonitorVO.TargetVO toTargetVO(DiskMonitorTarget target) {
|
||||
DiskMonitorVO.TargetVO targetVO = new DiskMonitorVO.TargetVO();
|
||||
targetVO.setId(target.getId());
|
||||
targetVO.setDriveLetter(target.getDriveLetter());
|
||||
targetVO.setMonitorEnabled(isEnabled(target.getMonitorEnabled()));
|
||||
targetVO.setWarningUsagePercent(target.getWarningUsagePercent());
|
||||
targetVO.setAlarmUsagePercent(target.getAlarmUsagePercent());
|
||||
targetVO.setNotifyPathEnabled(isEnabled(target.getNotifyPathEnabled()));
|
||||
targetVO.setNotifyPathList(parsePathItems(target.getNotifyPathListJson()));
|
||||
targetVO.setNotifyHttpEnabled(isEnabled(target.getNotifyHttpEnabled()));
|
||||
targetVO.setNotifyHttpList(parseHttpItems(target.getNotifyHttpListJson()));
|
||||
targetVO.setLastStatus(target.getLastStatus());
|
||||
targetVO.setLastScanTime(formatDateTime(target.getLastScanTime()));
|
||||
targetVO.setLastUsedPercent(target.getLastUsedPercent());
|
||||
targetVO.setRemark(target.getRemark());
|
||||
return targetVO;
|
||||
}
|
||||
|
||||
private String formatDateTime(LocalDateTime dateTime) {
|
||||
return dateTime == null ? null : dateTime.format(DATE_TIME_FORMATTER);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
CREATE TABLE IF NOT EXISTS `disk_monitor_policy` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`policy_name` VARCHAR(100) NOT NULL DEFAULT '默认磁盘监控策略' COMMENT '策略名称',
|
||||
`monitor_enabled` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否启用监控:0否 1是',
|
||||
`run_on_app_start` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '应用启动后是否执行一次:0否 1是',
|
||||
`daily_run_time` TIME NOT NULL COMMENT '每日统一执行时间',
|
||||
`warning_notify_mode` VARCHAR(32) NOT NULL DEFAULT 'STATUS_CHANGE' COMMENT '预警通知模式',
|
||||
`alarm_notify_mode` VARCHAR(32) NOT NULL DEFAULT 'EVERY_TIME' COMMENT '告警通知模式',
|
||||
`last_job_id` BIGINT NULL COMMENT '最近一次任务ID',
|
||||
`remark` VARCHAR(500) NULL COMMENT '备注',
|
||||
`created_by` VARCHAR(64) NULL COMMENT '创建人',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_by` VARCHAR(64) NULL COMMENT '更新人',
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='磁盘监控全局策略表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `disk_monitor_target` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`policy_id` BIGINT NOT NULL COMMENT '策略ID',
|
||||
`drive_letter` VARCHAR(10) NOT NULL COMMENT '盘符,例如 C:',
|
||||
`monitor_enabled` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否启用监控:0否 1是',
|
||||
`warning_usage_percent` TINYINT UNSIGNED NOT NULL COMMENT '预警使用率阈值',
|
||||
`alarm_usage_percent` TINYINT UNSIGNED NOT NULL COMMENT '告警使用率阈值',
|
||||
`notify_path_enabled` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否启用路径通知:0否 1是',
|
||||
`notify_path_list_json` JSON NULL COMMENT '路径通知目标列表JSON',
|
||||
`notify_http_enabled` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否启用HTTP通知:0否 1是',
|
||||
`notify_http_list_json` JSON NULL COMMENT 'HTTP通知目标列表JSON',
|
||||
`last_status` VARCHAR(32) NOT NULL DEFAULT 'UNKNOWN' COMMENT '最近一次状态',
|
||||
`last_scan_time` DATETIME NULL COMMENT '最近扫描时间',
|
||||
`last_used_percent` DECIMAL(5,2) NULL COMMENT '最近一次使用率',
|
||||
`remark` VARCHAR(500) NULL COMMENT '备注',
|
||||
`created_by` VARCHAR(64) NULL COMMENT '创建人',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_by` VARCHAR(64) NULL COMMENT '更新人',
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_drive_letter` (`drive_letter`),
|
||||
KEY `idx_policy_id` (`policy_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='磁盘监控盘符配置表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `disk_monitor_job` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`job_no` VARCHAR(64) NOT NULL COMMENT '任务编号',
|
||||
`job_source` VARCHAR(32) NOT NULL COMMENT '任务来源',
|
||||
`planned_time` DATETIME NULL COMMENT '计划执行时间',
|
||||
`started_at` DATETIME NOT NULL COMMENT '开始时间',
|
||||
`finished_at` DATETIME NULL COMMENT '结束时间',
|
||||
`job_status` VARCHAR(32) NOT NULL COMMENT '任务状态',
|
||||
`target_count` INT NOT NULL DEFAULT 0 COMMENT '计划扫描盘符数量',
|
||||
`success_count` INT NOT NULL DEFAULT 0 COMMENT '成功扫描数量',
|
||||
`warning_count` INT NOT NULL DEFAULT 0 COMMENT '预警数量',
|
||||
`alarm_count` INT NOT NULL DEFAULT 0 COMMENT '告警数量',
|
||||
`message` VARCHAR(1000) NULL COMMENT '结果说明',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_job_no` (`job_no`),
|
||||
KEY `idx_job_source` (`job_source`),
|
||||
KEY `idx_started_at` (`started_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='磁盘监控任务批次表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `disk_monitor_result` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`job_id` BIGINT NOT NULL COMMENT '任务ID',
|
||||
`target_id` BIGINT NOT NULL COMMENT '盘符配置ID',
|
||||
`drive_letter` VARCHAR(10) NOT NULL COMMENT '盘符',
|
||||
`total_bytes` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '总容量字节数',
|
||||
`used_bytes` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已使用字节数',
|
||||
`free_bytes` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '剩余字节数',
|
||||
`used_percent` DECIMAL(5,2) NOT NULL DEFAULT 0.00 COMMENT '使用率',
|
||||
`current_status` VARCHAR(32) NOT NULL COMMENT '当前状态',
|
||||
`previous_status` VARCHAR(32) NOT NULL DEFAULT 'UNKNOWN' COMMENT '上一次状态',
|
||||
`status_changed` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '状态是否变化:0否 1是',
|
||||
`should_notify` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '本次是否通知:0否 1是',
|
||||
`notify_reason` VARCHAR(32) NOT NULL DEFAULT 'NO_NOTIFY' COMMENT '通知原因',
|
||||
`scan_time` DATETIME NOT NULL COMMENT '扫描时间',
|
||||
`message` VARCHAR(1000) NULL COMMENT '扫描说明',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_job_id` (`job_id`),
|
||||
KEY `idx_target_id` (`target_id`),
|
||||
KEY `idx_drive_letter` (`drive_letter`),
|
||||
KEY `idx_scan_time` (`scan_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='磁盘监控结果表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `disk_monitor_notify_log` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`job_id` BIGINT NOT NULL COMMENT '任务ID',
|
||||
`result_id` BIGINT NOT NULL COMMENT '结果ID',
|
||||
`target_id` BIGINT NOT NULL COMMENT '盘符配置ID',
|
||||
`drive_letter` VARCHAR(10) NOT NULL COMMENT '盘符',
|
||||
`notify_level` VARCHAR(32) NOT NULL COMMENT '通知级别',
|
||||
`channel_type` VARCHAR(32) NOT NULL COMMENT '通知通道类型',
|
||||
`channel_target` VARCHAR(1000) NOT NULL COMMENT '通知目标',
|
||||
`notify_title` VARCHAR(255) NOT NULL COMMENT '通知标题',
|
||||
`notify_content` TEXT NOT NULL COMMENT '通知内容',
|
||||
`send_status` VARCHAR(32) NOT NULL COMMENT '发送状态',
|
||||
`response_message` VARCHAR(2000) NULL COMMENT '响应结果或异常信息',
|
||||
`sent_at` DATETIME NOT NULL COMMENT '发送时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_job_id` (`job_id`),
|
||||
KEY `idx_result_id` (`result_id`),
|
||||
KEY `idx_target_id` (`target_id`),
|
||||
KEY `idx_sent_at` (`sent_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='磁盘监控通知日志表';
|
||||
22
systemmonitor/pom.xml
Normal file
22
systemmonitor/pom.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.njcn.gather</groupId>
|
||||
<artifactId>CN_Tool</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>systemmonitor</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>systemmonitor</name>
|
||||
<description>System monitor capability aggregator.</description>
|
||||
|
||||
<modules>
|
||||
<module>disk-monitor</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
Reference in New Issue
Block a user