httpServletRequest.getParameterMap()为空_凡凡轶崔的博客-CSDN博客

群机器人配置说明 - 接口文档 - 企业微信开发者中心 (qq.com)

由于项目中暂时没有接入日志系统,导致平时查看异常信息非常的不方便。而且每次都需要产品,测试发现了才知道出错了,这影响不太好。

于是结合 切面 + 全局异常拦截 等技术实现结合企微的实时告警。

我是利用企微中提供的群机器人发布异常信息,新建一个机器人会提供一个Webhook地址

开发者可以按提供的Webhook发起HTTP POST 请求,即可实现给该群组发送消息。具体可以参考文章:群机器人配置说明 - 接口文档 - 企业微信开发者中心 (qq.com)

使用的消息内容类型:markdown类型

{"msgtype": "markdown","markdown": {"content": "实时新增用户反馈<font color=\"warning\">132例</font>,请相关同事注意。\n>类型:<font color=\"comment\">用户反馈</font>>普通用户反馈:<font color=\"comment\">117例</font>>VIP用户反馈:<font color=\"comment\">15例</font>"}
}
参数 是否必填 说明
msgtype 消息类型,此时固定为markdown
content markdown内容,最长不超过4096个字节,必须是utf8编码

使用原因:参数较少并且内容长度支持较长。

异常告警机器人代码:

@Component
@Slf4j
public class ExceptionMsgBot {private static final String METHOD_GET = "GET";private static final String METHOD_POST = "POST";/*** 企微机器人webhook地址*/@Value("${ExceptionMsgBot.url}")private String url;/*** 是否启用*/@Value("${ExceptionMsgBot.isEnable:true}")private Boolean isEnable;/*** 最大长度*/@Value("${ExceptionMsgBot.maxSize:2500}")private int maxSize;public void send(Exception e, HttpServletRequest request) {if (!isEnable) {return;}String title = "标题";//时间String now = DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMAT);//请求urlString api = request.getRequestURL().toString();//请求参数String params = JSONUtil.toJsonStr(request.getAttribute("params"));if (!StringUtils.isEmpty(params)) {//将json转成普通stringparams = params.replace("\"","\\\"");}//服务器IPString serverIP = NetUtil.getLocalhostStr();//客户端IPString clientIP = request.getRemoteAddr();String textMsg = "{\n" +"    \"msgtype\": \"markdown\",\n" +"    \"markdown\": {\n" +"        \"content\": \"" + title + "\\n\n" +"         【url】: " + api + " \n" +"         【参数】: " + params + " \n" +"         【时间】: " + now + " \n" +"         【serverIp】: " + serverIP + " \n" +"         【clientIp】: " + clientIP + " \n" +"         【message】: " + e.getMessage() + " \n" +"         【cause】: " + e.getCause() + " \n" +"         【StackTrace】: " + e + "  \"\n" +"    }\n" +"}\n";//发送消息HttpResponse response = HttpRequest.post(url).header(Header.CONTENT_TYPE, "application/json; charset=UTF-8").body(textMsg).execute();log.info("【异常消息发送结果】 {}", response.body());}
}

这次设计的异常信息主要展示8点

  • 请求接口路径
  • 请求参数
  • 当前时间
  • 服务器ip
  • 客户端ip
  • e.message
  • e.cause
  • e.stack

除了请求参数需要特殊处理,其他参数都可以方便获取。

因为每次请求接口,项目中会有个全局日志切面类打印输出每次请求的信息。

这个全局日志切面类会在进入controller之前进行拦截,从而可以获取到每次请求的参数。然后将参数封装到request,传递给内部web容器使用,也就是本文章的异常告警机器人使用。

@Aspect
@Configuration
@Slf4j
public class GlobalControllerLogAspect {@Pointcut("execution (* com.*..controller..*.*(..))")public void controllers() {}@Around("controllers()")public Object aroundProcess(ProceedingJoinPoint joinPoint) throws Throwable {Object[] args = joinPoint.getArgs();long startTime = System.currentTimeMillis();Object proceed = null;try {ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();String uid = request.getHeader(HeaderConstant.UID);List<Object> params = new ArrayList<>();if (args != null && args.length > 0) {for (Object arg : args) {if (arg instanceof HttpServletRequest || arg instanceof HttpServletResponse) {continue;} else if (arg instanceof MultipartFile) {continue;} else {params.add(arg);}}}//保存请求参数request.setAttribute("params", JSONUtil.toJsonStr(params));log.info("接口方法:{},uid:{},请求参数:{}", request.getRequestURL().toString(), uid, JSONUtil.toJsonStr(params));proceed = joinPoint.proceed(args);log.info("响应结果:{},耗时:{}ms", JSONUtil.toJsonStr(proceed), System.currentTimeMillis() - startTime);} finally {}return proceed;}
}

可以在 joinPoint(连接点) 获取到请求参数。

异常告警机器人全局异常拦截器埋点

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {@Autowiredprivate ExceptionMsgBot bot;@ExceptionHandler(value = Exception.class)public void handle(Exception e, HttpServletRequest request, HttpServletResponse response) {log.error("接口[{}]异常, ", request.getRequestURI(), e);CommonResult<Object> result = CommonResult.failed("系统出了点小问题");//埋点bot.send(e, request);String json = JSONUtil.toJsonStr(result);response.setHeader("Content-Type", "application/json; charset=UTF-8");try {response.getWriter().write(json);} catch (IOException ex) {log.error("接口[{}]IO异常, ", request.getRequestURI(), ex);}}
}

当有异常信息被全局异常拦截器捕获时,保存异常日志的同时,发送告警信息通知开发等相关人员处理。

效果:

异常告警,请相关同事注意!【url】: http://172.18.139.x:9001/xxx 【参数】: ["uid",{"f1":9,"f2":2,"f3":2377,"f4":false,"f5":"","f6":1}] 【时间】: 2022-04-14 16:35:28 【serverIp】: 172.18.139.x 【clientIp】: 172.18.139.x 【message】: xxx不能为空 【cause】: null 【StackTrace】: com.xxx.common.component.exception.ApiException: xxx不能为空

完美~

springboot+企微实现项目异常告警相关推荐

  1. Docker Compose配置springboot微服务项目

    [Docker那些事]系列文章 docker 安装 与 卸载 centos Dockerfile 文件结构.docker镜像构建过程详细介绍 Dockerfile文件中CMD指令与ENTRYPOINT ...

  2. SCRM:SpringBoot + RabbitMQ + 企微 实现发送消息到企业微信

    使用MQ实现企业微信应用程序发送消息到指定人或部门 提前部署好RabbitMQ服务,不会的同学请看我的另一篇部署文章 引入相关依赖 代码实现 提前部署好RabbitMQ服务,不会的同学请看我的另一篇部 ...

  3. 【Springboot+vue项目开发】:网盘系统项目开发流程(03 微服务项目的划分及构建)

    03 微服务项目的划分及构建 项目链接 问题1:IDEA如何将git下来的是工程转为maven工程 IDEA如何将git下来的是工程转为maven工程 问题2:jdk1.8的选用 问题3:Maven工 ...

  4. 七个开源的 SpringBoot 前后端分离项目,Star过千,快去收藏夹吃灰吧!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 微信公众号:江南一点雨 前后端分离已经在慢慢走进各公司的技 ...

  5. 商城项目02_环境搭建、安装VAGRANT、DOCKER、MYSQL、REDIS、从0搭建各个微服务项目、数据库初始化、安装NGINX

    文章目录 ①. virtualBox - 管理虚拟机 ②. vagrant - 安装虚拟机 ③. 虚拟机安装 - docker ④. docker上安装mysql ⑤. docker上安装redis ...

  6. 微服务项目后台技术栈

    微服务项目后台相关技术整理 主要技术 ORM框架-Mybatis Plus Mybatis Plus核心功能 MyBatis Plus与SpringBoot集成 MyBatis Plus集成Sprin ...

  7. SpringBoot整合AlertManager,实现自定义的告警收敛以及邮件处理,告警风暴,解决重复告警问题

    SpringBoot整合AlertManager,实现自定义的告警收敛以及邮件处理,告警风暴,解决重复告警问题 需求 将传感器通过Http发送到微服务(SpringBoot项目)的警报消息,通知给对应 ...

  8. java调tapd-api获取Bug并发企微通知

    需求 线上报障定时推送: 定时任务:每天上午9点半.下午5点半 基于企微机器人做推送 未处理线上报障 判断条件: [tapd]项目(workspace_id): 68331031 (用户产品部(C端) ...

  9. 三、美团大众点评CAT监控系列文章---Springboot集成CAT并实现邮件告警

    文章目录 一.配置过程 二.相关的参考文档 三.系列文章 一.配置过程 登录自己的cat服务端 默认登录用户名和密码都是 catadmin添加一个监控规则: 如下面的监控规则就是说,如果在一分钟以内访 ...

最新文章

  1. mycat是什么_MYCAT学习2
  2. 【ASP.NET开发】ASP.NET(MVC)三层架构知识的学习总结
  3. 深度学习中Attention机制的“前世今生”
  4. 软件测试:homework2
  5. 【渝粤教育】国家开放大学2019年春季 1248公共部门人力资源管理 参考试题
  6. BZOJ 4241 历史研究
  7. windows下安装VM虚拟机和Ubuntu系统(附注册密钥)
  8. excel计算机快捷键大全,excel表格使用技巧快捷键大全
  9. css td中画斜线,css 模拟表格斜线
  10. ES笔记_转自尚硅谷_其中有JAVA操作_ES
  11. 天气数据API接口记录
  12. Excel去掉函数错误值#VALUE!的方法
  13. 诈骗又出新套路,微信借钱语音确认仍被骗
  14. matlab中如何转动三维图_matlab如何画三维图
  15. matlab摄氏度fuhao,chemdraw温度符号
  16. 《项目管理就是这么简单》--读书笔记
  17. 用友u8 12.1服务器硬件要求,用友U8软硬件环境要求
  18. 近代物理实验 液晶电光效应 (含数据和参考题)
  19. spring session、spring security和redis整合的简单使用
  20. 人生中第一个自制游戏

热门文章

  1. ARToolKit-unity
  2. insert键与delete键重合了(笔记本)】:如何点击insert?
  3. 【翻译】使用Sencha Ext JS 6打造通用应用程序
  4. 10.7 抽象类最佳实践-模板设计模式
  5. 微软xp停止服务器,微软无奈:XP依然能获取Windows Update
  6. 学习“orang's 一个操作系统的实现”的朋友必看
  7. Unity3D MineCraft 我的世界 类似游戏的地形编辑器
  8. Vectorcast 2021 sp8 windows
  9. 感谢CSDN提名我候选2006最有价值博客,感谢朋友们的投票
  10. 字节跳动上千道精选面试题还不刷起来!2019-2020大厂高级面试题集合(Handler,性能优化,自定义View等)