diff --git a/CHANGELOG.md b/CHANGELOG.md index 206be2379..8f44a9fc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ 3. 【server】新增系统配置-配置菜单是否显示,用于非超级管理员页面菜单控制 4. 【server】新增节点统计功能,快速了解当前所有节点状态 5. 【server】新增节点心跳检测配置`system.nodeHeartSecond` +6. 新增缓存管理查看定时任务执行统计 ### 解决BUG、优化功能 diff --git a/modules/common/src/main/java/io/jpom/cron/CronUtils.java b/modules/common/src/main/java/io/jpom/cron/CronUtils.java index 4bcf59718..6f7666f59 100644 --- a/modules/common/src/main/java/io/jpom/cron/CronUtils.java +++ b/modules/common/src/main/java/io/jpom/cron/CronUtils.java @@ -22,14 +22,20 @@ */ package io.jpom.cron; +import cn.hutool.core.date.SystemClock; import cn.hutool.cron.CronUtil; import cn.hutool.cron.Scheduler; +import cn.hutool.cron.TaskExecutor; import cn.hutool.cron.TaskTable; +import cn.hutool.cron.listener.TaskListener; import cn.hutool.cron.task.Task; +import cn.jiangzeyin.common.DefaultSystemLog; import com.alibaba.fastjson.JSONObject; import io.jpom.system.ExtConfigBean; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -39,6 +45,30 @@ import java.util.stream.Collectors; **/ public class CronUtils { + private static final Map TASK_STAT = new ConcurrentHashMap<>(50); + + /** + * 任务统计 + */ + private static class TaskStat { + /** + * 执行次数 + */ + private int executeCount; + /** + * 失败次数 + */ + private int failedCount; + /** + * 成功次数 + */ + private int succeedCount; + /** + * 最后执行时间 + */ + private Long lastExecuteTime; + } + /** * 开始 */ @@ -50,6 +80,27 @@ public class CronUtils { Scheduler scheduler = CronUtil.getScheduler(); if (!scheduler.isStarted()) { CronUtil.start(); + scheduler.addListener(new TaskListener() { + @Override + public void onStart(TaskExecutor executor) { + TaskStat taskStat = TASK_STAT.computeIfAbsent(executor.getCronTask().getId(), s -> new TaskStat()); + taskStat.lastExecuteTime = SystemClock.now(); + taskStat.executeCount++; + } + + @Override + public void onSucceeded(TaskExecutor executor) { + TaskStat taskStat = TASK_STAT.computeIfAbsent(executor.getCronTask().getId(), s -> new TaskStat()); + taskStat.succeedCount++; + } + + @Override + public void onFailed(TaskExecutor executor, Throwable exception) { + TaskStat taskStat = TASK_STAT.computeIfAbsent(executor.getCronTask().getId(), s -> new TaskStat()); + taskStat.failedCount++; + DefaultSystemLog.getLog().error("定时任务异常", exception); + } + }); } } @@ -63,9 +114,16 @@ public class CronUtils { TaskTable taskTable = scheduler.getTaskTable(); List ids = taskTable.getIds(); return ids.stream().map(s -> { + TaskStat taskStat = TASK_STAT.get(s); JSONObject jsonObject = new JSONObject(); jsonObject.put("taskId", s); jsonObject.put("cron", scheduler.getPattern(s).toString()); + if (taskStat != null) { + jsonObject.put("executeCount", taskStat.executeCount); + jsonObject.put("failedCount", taskStat.failedCount); + jsonObject.put("succeedCount", taskStat.succeedCount); + jsonObject.put("lastExecuteTime", taskStat.lastExecuteTime); + } return jsonObject; }).collect(Collectors.toList()); } diff --git a/modules/server/src/main/java/io/jpom/controller/monitor/MonitorListController.java b/modules/server/src/main/java/io/jpom/controller/monitor/MonitorListController.java index f81e694ab..8cf388a3b 100644 --- a/modules/server/src/main/java/io/jpom/controller/monitor/MonitorListController.java +++ b/modules/server/src/main/java/io/jpom/controller/monitor/MonitorListController.java @@ -22,7 +22,6 @@ */ package io.jpom.controller.monitor; -import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import cn.jiangzeyin.common.JsonMessage; import cn.jiangzeyin.common.validator.ValidatorConfig; @@ -45,7 +44,6 @@ import org.springframework.http.MediaType; import org.springframework.util.Assert; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @@ -84,7 +82,6 @@ public class MonitorListController extends BaseServerController { * @return json */ @RequestMapping(value = "getMonitorList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody @Feature(method = MethodFeature.LIST) public String getMonitorList() { PageResultDto pageResultDto = monitorService.listPage(getRequest()); @@ -98,7 +95,6 @@ public class MonitorListController extends BaseServerController { * @return json */ @RequestMapping(value = "deleteMonitor", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody @Feature(method = MethodFeature.DEL) public String deleteMonitor(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "删除失败") String id) throws SQLException { // @@ -121,7 +117,6 @@ public class MonitorListController extends BaseServerController { * @return json */ @RequestMapping(value = "updateMonitor", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody @Feature(method = MethodFeature.EDIT) public String updateMonitor(String id, @ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "监控名称不能为空")) String name, @@ -170,33 +165,32 @@ public class MonitorListController extends BaseServerController { return JsonMessage.getString(200, "修改成功"); } - /** - * 开启或关闭监控 - * - * @param id id - * @param status 状态 - * @param type 类型 - * @return json - */ - @RequestMapping(value = "changeStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody - @Feature(method = MethodFeature.EDIT) - public String changeStatus(@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "id不能为空")) String id, - String status, String type) { - MonitorModel monitorModel = monitorService.getByKey(id); - Assert.notNull(monitorModel, "不存在监控项啦"); - - boolean bStatus = Convert.toBool(status, false); - if ("status".equalsIgnoreCase(type)) { - monitorModel.setStatus(bStatus); - } else if ("restart".equalsIgnoreCase(type)) { - monitorModel.setAutoRestart(bStatus); - } else { - return JsonMessage.getString(405, "type不正确"); - } - monitorService.updateById(monitorModel); - return JsonMessage.getString(200, "修改成功"); - } +// /** +// * 开启或关闭监控 +// * +// * @param id id +// * @param status 状态 +// * @param type 类型 +// * @return json +// */ +// @RequestMapping(value = "changeStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) +// @Feature(method = MethodFeature.EDIT) +// public String changeStatus(@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "id不能为空")) String id, +// String status, String type) { +// MonitorModel monitorModel = monitorService.getByKey(id); +// Assert.notNull(monitorModel, "不存在监控项啦"); +// +// boolean bStatus = Convert.toBool(status, false); +// if ("status".equalsIgnoreCase(type)) { +// monitorModel.setStatus(bStatus); +// } else if ("restart".equalsIgnoreCase(type)) { +// monitorModel.setAutoRestart(bStatus); +// } else { +// return JsonMessage.getString(405, "type不正确"); +// } +// monitorService.updateById(monitorModel); +// return JsonMessage.getString(200, "修改成功"); +// } } diff --git a/modules/server/src/main/java/io/jpom/model/data/MonitorModel.java b/modules/server/src/main/java/io/jpom/model/data/MonitorModel.java index 4497971a9..b57465275 100644 --- a/modules/server/src/main/java/io/jpom/model/data/MonitorModel.java +++ b/modules/server/src/main/java/io/jpom/model/data/MonitorModel.java @@ -38,6 +38,7 @@ import java.util.List; */ @TableName(value = "MONITOR_INFO", name = "监控信息") public class MonitorModel extends BaseWorkspaceModel { + private String name; /** * 监控的项目 @@ -54,6 +55,7 @@ public class MonitorModel extends BaseWorkspaceModel { /** * 监控周期 */ + @Deprecated private Integer cycle; /** @@ -73,11 +75,12 @@ public class MonitorModel extends BaseWorkspaceModel { this.name = name; } - + @Deprecated public Integer getCycle() { return cycle; } + @Deprecated public void setCycle(Integer cycle) { this.cycle = cycle; } diff --git a/web-vue/src/pages/monitor/list.vue b/web-vue/src/pages/monitor/list.vue index e4705b940..bc1b0f649 100644 --- a/web-vue/src/pages/monitor/list.vue +++ b/web-vue/src/pages/monitor/list.vue @@ -14,8 +14,8 @@ {{ text }} - - + + {{ text }} @@ -33,12 +33,21 @@ + - - - - + + +
+ 自动重启: + +
+
+ + + 1 分钟 @@ -54,7 +63,7 @@