diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/notice/fs/FsNotice.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/notice/fs/FsNotice.java index 2d5ca1461..bb2a58a43 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/notice/fs/FsNotice.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/notice/fs/FsNotice.java @@ -1,10 +1,13 @@ package com.ruoyi.framework.notice.fs; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSON; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.framework.notice.AbstractNotice; import com.ruoyi.framework.notice.fs.entity.*; import lombok.extern.slf4j.Slf4j; @@ -32,6 +35,10 @@ public class FsNotice extends AbstractNotice { private String defaultAppSecret; @Value("${fs.robot.defaultChatId:oc_4f66ce3cf471f50aac6c3fdae7f0aad9}") private String defaultChatId; + @Value("${fs.robot.monitorSwitch:true}") + private Boolean monitorSwitch; + @Value("${fs.robot.monitorChartId:oc_34e207df88addd15d83ec274fda95ef6}") + private String monitorChartId; /** * 发送消息给默认会话 @@ -43,6 +50,41 @@ public class FsNotice extends AbstractNotice { ThreadUtil.execAsync(() -> sendMsg(title, content, new String[]{defaultChatId})); } + /** + * 发送异常信息给监控群 + * + * @param e + */ + public void sendException2MonitorChat(T e) { + if (Boolean.TRUE.equals(monitorSwitch)) { + ThreadUtil.execAsync(() -> { + try { + //内容 + FeiShuMsg.ZhCn zhCn = new FeiShuMsg.ZhCn(); + List> contentFields = new ArrayList<>(); + contentFields.add(Collections.singletonList(FeiShuTextField + .createText(CharSequenceUtil.format("主机:{}", IpUtils.getHostIp())))); + contentFields.add(Collections.singletonList(FeiShuTextField + .createText(CharSequenceUtil.format("时间:{}", DateUtil.now())))); + contentFields.add(Collections.singletonList(FeiShuTextField + .createText(CharSequenceUtil.format("异常:{}", e.getClass().getName())))); + contentFields.add(Collections.singletonList(FeiShuTextField + .createText(CharSequenceUtil.format("错误信息:{}", StrUtil.truncateUtf8(e.getMessage(),512))))); + zhCn.setContent(contentFields); + //消息体 + FeiShuMsg feiShuMsg = new FeiShuMsg(); + feiShuMsg.setChatId(monitorChartId); + feiShuMsg.setMsgType("post"); + feiShuMsg.setContent(FeiShuMsg.Content.builder().post(FeiShuMsg.Post.builder().zhCn(zhCn).build()).build()); + //发送 + httpPost(FEI_SHU_ROBOT_SEND_MSG_URL, createDefaultHeader(), JSON.toJSONString(feiShuMsg)); + } catch (Exception ex) { + log.error("[FS]发送消息异常", ex); + } + }); + } + } + /** * 发送消息 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java index 465e23d98..4e75f03c1 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java @@ -7,6 +7,8 @@ import com.ruoyi.common.exception.DemoModeException; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.html.EscapeUtil; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.framework.notice.fs.FsNotice; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.AccessDeniedException; @@ -38,6 +40,7 @@ public class GlobalExceptionHandler { String requestURI = request.getRequestURI(); log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage()); + sendExceptionMsg(e); return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权"); } @@ -50,6 +53,7 @@ public class GlobalExceptionHandler { String requestURI = request.getRequestURI(); log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + sendExceptionMsg(e); return AjaxResult.error(e.getMessage()); } @@ -60,6 +64,7 @@ public class GlobalExceptionHandler public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) { log.error("请求地址'{}',发生业务异常'{}'", request.getRequestURI(), e.getMessage()); + sendExceptionMsg(e); Integer code = e.getCode(); return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); } @@ -71,6 +76,7 @@ public class GlobalExceptionHandler @ExceptionHandler(IllegalArgumentException.class) public AjaxResult illegalArgumentException(IllegalArgumentException e, HttpServletRequest request) { log.error("请求地址'{}',发生校验异常'{}'", request.getRequestURI(), e.getMessage()); + sendExceptionMsg(e); return AjaxResult.error(e.getMessage()); } @@ -82,6 +88,7 @@ public class GlobalExceptionHandler { String requestURI = request.getRequestURI(); log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e); + sendExceptionMsg(e); return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName())); } @@ -98,6 +105,7 @@ public class GlobalExceptionHandler value = EscapeUtil.clean(value); } log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e); + sendExceptionMsg(e); return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value)); } @@ -109,6 +117,7 @@ public class GlobalExceptionHandler { String requestURI = request.getRequestURI(); log.error("请求地址'{}',发生未知异常.", requestURI, e); + sendExceptionMsg(e); return AjaxResult.error(e.getMessage()); } @@ -120,6 +129,7 @@ public class GlobalExceptionHandler { String requestURI = request.getRequestURI(); log.error("请求地址'{}',发生系统异常.", requestURI, e); + sendExceptionMsg(e); return AjaxResult.error(e.getMessage()); } @@ -131,6 +141,7 @@ public class GlobalExceptionHandler { log.error(e.getMessage(), e); String message = e.getAllErrors().get(0).getDefaultMessage(); + sendExceptionMsg(e); return AjaxResult.error(message); } @@ -142,7 +153,8 @@ public class GlobalExceptionHandler { String requestURI = request.getRequestURI(); String message = e.getBindingResult().getFieldError().getDefaultMessage(); - log.error("请求地址'{}',发生校验异常", requestURI, message); + log.error("请求地址'{}',发生校验异常: {}", requestURI, message); + sendExceptionMsg(e); return AjaxResult.error(message); } @@ -154,4 +166,14 @@ public class GlobalExceptionHandler { return AjaxResult.error("演示模式,不允许操作"); } + + /** + * 发送异常消息 + * + * @param e + * @param + */ + private void sendExceptionMsg(T e) { + SpringUtils.getBean(FsNotice.class).sendException2MonitorChat(e); + } }