记录下系统异常到数据库中,方便查找定位,省去翻日志的麻烦。

将异常消息,产生时间,帧信息,操作信息等存入表中,方便查阅修改。适合小系统。大系统没试过。

在异常通知对象HandlerExceptionResolver解析完异常后,构建一个异常相关信息实体。存入表中。代码如下:

public class ExceptionAdvice implements HandlerExceptionResolver, Ordered {@AutowiredEnableNullprivate ExceptionLogHandler exceptionHandler;@AutowiredEnableNullprivate ExceptionViewCustomizer exceptionViewCustomizer;@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {ModelAndView mv = new ModelAndView();FastJsonJsonView jsonView = new FastJsonJsonView();boolean isMethod = handler instanceof HandlerMethod;if (!isMethod) {jsonView.addStaticAttribute("code", 500);jsonView.addStaticAttribute("message", "访问异常" + request.getRequestURI());mv.setView(jsonView);ZYResponseUtils.allowOrigin(response, request);return mv;}// 格式化记录日志并打印prettyError(ex, request);Integer code = Resp.R_500.getCode();String message;String data = ex.getClass().getSimpleName();if (ex instanceof LocalException) {LocalException localException = (LocalException) ex;code = localException.getCode();message = localException.getMessage();}  if (ex instanceof NullPointerException) {message = "空数据异常,请联系系统管理员";} else if (ex instanceof BadSqlGrammarException) {message = "数据语法有误,请联系管理员";} else if (ex instanceof SQLException) {message = "数据库异常,请联系管理员";} else if (ex instanceof DataIntegrityViolationException) {message = "数据库异常,请联系管理员";} else if (ex instanceof UncategorizedSQLException) {message = "数据库异常,请联系管理员";}else if (ex instanceof DuplicatioKeyException) {message = "唯一键冲突,请联系管理员";} else if (ex instanceof MyBatisSystemException) {message = "数据库异常,请联系管理员";} else if (ex instanceof NestedServletException) {NestedServletException ne = (NestedServletException) ex;message = "类加载异常或静态块逻辑执行异常!";data = ne.getMessage();} else if (ex instanceof RuntimeException) {RuntimeException localException = (RuntimeException) ex;message = localException.getMessage();} else {switch (response.getStatus()) {case 400:code = Resp.R_400.getCode();message = "参数异常,请检查您的参数";data = "请比对您的参数,如接收的类型、日期格式检查或麻烦您友善的找后台开发解决问题,谢谢!!";break;case 403:code = Resp.R_403.getCode();message = "您没有访问本接口的权限";data = "麻烦您友善的找后台开发解决问题,谢谢!!";break;case 404:code = Resp.R_404.getCode();message = "您所请求的接口并没有找到";data = "请检查您的开发文档或麻烦您友善的找后台开发解决问题,谢谢!!";break;case 405:code = Resp.R_405.getCode();message = "您的访问方式GET/POST等不符合接口定义的方法";data = "请检查您的开发文档或麻烦您友善的找后台开发解决问题,谢谢!!";break;default:code = Resp.R_500.getCode();message = getExceptionMessage(ex);data = "麻烦您友善的找后台开发解决问题,谢谢!!";break;}}ExceptionWrapper exceptionWrapper = new ExceptionWrapper();exceptionWrapper.setRequest(request); // 请求对象exceptionWrapper.setResponse(response); // 响应对象exceptionWrapper.setMessage(message); // 响应消息exceptionWrapper.setCode(code); // 响应码exceptionWrapper.setHandler((HandlerMethod) handler);exceptionWrapper.setEx(ex); // 异常if (null != exceptionHandler) {// 记录异常日志exceptionHandler.handleExceptionLog(exceptionWrapper);}if (null != exceptionViewCustomizer) {// 自定义异常视图View view = exceptionViewCustomizer.customize(exceptionWrapper);mv.setView(view);} else {// 默认视图jsonView.addStaticAttribute("code", code);jsonView.addStaticAttribute("message", null == message ? Resp.R_500.getMessage() : message);jsonView.addStaticAttribute("data", null != data ? data : "");mv.setView(jsonView);}return mv;}
public class ExceptionLogRecordProcessor implements ExceptionLogHandler {@Overridepublic void handleExceptionLog(ExceptionWrapper exceptionWrapper) {ExceptionLog exceptionLog = new ExceptionLog();exceptionLog.setId(getLogId()); // 异常idexceptionLog.setCaseLookTime(ZYDateUtils.formart(new Date(), ZYDateUtils.YYYY_MM_DD_HH_MM_SS)); // 异常发生时间Exception ex = exceptionWrapper.getEx();exceptionLog.setCaseMessage(ex.getMessage()); // 异常引发消息exceptionLog.setShowMessage(exceptionWrapper.getMessage()); // 返回页面消息exceptionLog.setUrl(ZYRequestUtils.getApiFromRequest(exceptionWrapper.getRequest())); // 访问路径exceptionLog.setCode(exceptionWrapper.getCode()); // 异常码exceptionLog.setExceptionClass(ex.getClass().getName());// 异常类名exceptionLog.setSessionId(ZYUserHelper.getLoginSessionId()); // sessionIdLoginUser loginUser= ZYUserHelper.getLoginUser();exceptionLog.setUserId(loginUser.getId()); // 访问人exceptionLog.setUserName(loginUser.getUserName()); // 访问用户StackTraceElement[] stackTraces = ex.getStackTrace();List<String> stackInfos = new ArrayList<>();// 只挑选与项目大目录有关的类的栈信息for (StackTraceElement stackTrace : stackTraces) {String className = stackTrace.getClassName();if (className.contains("xxx")) {stackInfos.add(toStackMessage(stackTrace));}}// 没有获取到取帧信息的前10个差不多了if (stackInfos.isEmpty()) {int i = 0;for (StackTraceElement stackTrace : stackTraces) {if (i < 10) {stackInfos.add(toStackMessage(stackTrace));}i++;}}exceptionLog.setStackInfos(ZYStrUtils.join(stackInfos, "\r\n"));// 记录异常至队列或直接存表,按七天一张表存入动态表中LoggingBootstrap.putExceptionLog(exceptionLog);}

异常记录效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/285630.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis-内存模型

参考资料&#xff1a; 极客时间 Redis 亚风 内存管理 从两个问题入手: 1 Redis是如何知道⼀个key是否过期呢&#xff1f; 2 是不是TTL到期就⽴即删除了呢&#xff1f; Redis是K-V内存数据库&#xff0c;所有的K、V都保存在Dict中。不过在其db结构体中有5个Dict&#xff0c;我…

Neural Network——神经网络

1.feature reusing——特征复用 1.1 什么是特征复用 回顾我们之前所学习的模型&#xff0c;本质上都是基于线性回归&#xff0c;但却都可以运用于非线性相关的数据&#xff0c;包括使用了如下方法 增加更多的特征产生新的特征&#xff08;多项式回归&#xff09;核函数 在本身…

C#深拷贝效率对比

对于浅拷贝和深拷贝&#xff0c;前面的文章已经说明了。 C#浅拷贝和深拷贝数据-CSDN博客 本篇说一下&#xff0c;深拷贝的效率问题&#xff0c;效率一直是程序追求的&#xff0c;效率越高肯定越好&#xff0c;有时候功能是实现了&#xff0c;但是运行以及处理数据的效率非常低…

Ubuntu 18.04配置NFS服务器以及配置时遇到NFS问题

1.安装相关软件 sudo apt-get install nfs-kernel-server sudo apt-get install nfs-common 2.配置共享目录 2.1修改exports文件 sudo vi /etc/exports在最后添加如下并保存退出 /home/xiaowu/nfs 192.168.31*(rw,sync,no_root_squash,no_subtree_check) /home/xiaowu/nfs…

【密码学】群的证明(习题)

0.前置知识 1.习题 记录一次密码学作业~群的判定 2.求解

〖大前端 - 基础入门三大核心之JS篇(57)〗- 继承

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

骨传导耳机和气传导耳机有什么区别?谁更值得入手?

先说答案&#xff0c;骨传导耳机和气传导耳机的佩戴方式和传声方式不同&#xff0c;并且骨传导耳机相比于气传导耳机更值得入手。 一、骨传导耳机和气传导耳机有什么区别 1、佩戴方式不同 骨传导耳机采用一体式耳挂佩戴或耳夹式佩戴&#xff0c;气传导耳机采用分体式耳挂设计…

采样率8kHz~96kHz单端输入ADC芯片CJC1808

音频模/数转换器是一种用于将模拟音频信号转换成数字信号的设备&#xff0c;可以提供高质量的音频转换功能&#xff1b;被广泛应用于录音室、数字音频处理、混音、模拟音频处理等应用中&#xff1b;是当今数字音频处理中不可或缺的一部分。 ADC芯片可以提供宽频带的模拟输入&a…

SpringCloud微服务 【实用篇】| Docker镜像、容器、数据卷操作

目录 一&#xff1a;Docker基本操作 1. 镜像操作 镜像相关命令 2. 容器操作 容器相关命令 3. 数据卷&#xff08;容器数据管理&#xff09; 数据卷 操作数据卷 挂载数据卷 挂载的方式区别 前些天突然发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0…

如何利用CHAT写C程序?

问CHAT&#xff1a;用c语言编写在二维字符数组中查找某个字符串 CHAT回复&#xff1a;以下是一个简单的C程序&#xff0c;它将在二维字符数组中查找特定的字符串。 c #include <stdio.h> #include <string.h> void search(char arr[100][100], int r, char* str) …

Java泛型(1)

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

xxl-job 分布式调度学习笔记

1.概述 1.1什么是任务调度 业务场景&#xff1a; 上午10点&#xff0c;下午2点发放一批优惠券 银行系统需要在信用卡到期还款日的前三天进行短信提醒 财务系统需要在每天凌晨0:10分结算前一天的财务数据&#xff0c;统计汇总 不同系统间的数据需要保持一致&#xff0c;这时…