考虑对JDK的底层堆栈信息进行处理,一种是重写JDK的Throwable,另一种是在原错误堆栈信息上进行“二次加工”。目前这两种方式我都实现了,效果非常好。

这篇文章主要记录对错误堆栈进行“二次加工”的实现过程。

从大量的实际错误日志分析出发:

首先,追根溯源,找到错误是从哪个地方new出来的。

例如
com.jfinal.plugin.activerecord.ActiveRecordException: java.lang.ClassCastException: com.alibaba.druid.sql.visitor.SQLEvalVisitorImpl cannot be cast to com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor
 at com.jfinal.plugin.activerecord.Db.paginate(Db.java:554)
 at com.jfinal.plugin.activerecord.Db.paginate(Db.java:593)
 at com.simple.sqpt.services.FWCXService.doGetHouseInfo(FWCXService.java:172)

那么是在Db.paginate(Db.java:554)这一行new出来的,后面有:
Caused by: java.lang.ClassCastException: com.alibaba.druid.sql.visitor.SQLEvalVisitorImpl cannot be cast to com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor
 at com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock.accept0(SQLServerSelectQueryBlock.java:39)
 at com.alibaba.druid.sql.ast.SQLObjectImpl.accept(SQLObjectImpl.java:40)
说明这个new出来的错误,是包裹了另外一个错误,可能是有new ActiveRecordException(e);然后这个e是一个ClassCastException类型错误
因为只有一个Caused by,可以肯定,这个(ClassCastException) e 是源头,是从:
SQLServerSelectQueryBlock.accept0(SQLServerSelectQueryBlock.java:39)这里new出来的。

应用的栈信息可能夹在中间,比如:

org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.ibm.websphere.ce.cm.StaleConnectionException: The Network Adapter could not establish the connectionDSRA0010E: SQL State = 61000, Error Code = 20
  at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:82)
  at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:577)
  at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:641)
  at org.springframework.jdbc.core.JdbcTemplate.queryForInt(JdbcTemplate.java:759)
  at com.proj.webc.persist.framework.BaseDAO.queryForCount(BaseDAO.java:142)
  at com.proj.webc.persist.office.dao.OfficeDAO.queryBackUsersCountByCondition(OfficeDAO.java:734)
  at com.proj.webc.logic.office.OfficeManagerImpl.queryCountOfficeByCondition(OfficeManagerImpl.java:79)
  at com.proj.webc.present.orderquery.action.FrontOrderQueryAction.doAction(FrontOrderQueryAction.java:118)
  at com.proj.webc.framework.BaseAction.execute(BaseAction.java:205)
  at sun.reflect.GeneratedMethodAccessor81.invoke(Unknown Source)
  at java.lang.reflect.Method.invoke(Method.java:600)
  at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:450)
  at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:289)

像这种,其实我们只能操纵应用之前的错误信息,应用之后的,超出了我们的管理范围。 比如上面这个例子,在com.proj.**之前的org.springframework.**是我们可以管理的, 但是后面的sun.reflect.**,java.lang.**,com.opensymphony.**都超出了应用的可视范围。 (除非从源头控制,比如com.opensymphony.**的源码,最上层,应该是webContainer,例如websphere下,最外层的栈信息都是com.ibm.**开头)

分析上面的错误信息,我们可以操作的最外层,是 com.proj.webc.framework.BaseAction.execute(BaseAction.java) 我们可以在这个地方做工作,把它管辖之下的错误信息进行整理,例如可以把 org.springframework.**这种信息都过滤掉。

如果是用log工具,我们就有控制权。

综上分析,对于最上层,紧跟着错误信息的地方,只需要追溯到错误new出来之前的前几个轨迹即可。 一般来说,只需要跟踪和new出来错误的那个类在同一个api包之中的,比如上面这个例子, 只需要跟踪到第二行 com.jfinal.plugin.activerecord.Db.paginate(Db.java:593)即可。

对于Caused by,是非常核心的错误出处,一般是在应用之中的,可采取和上面一样的处理方式,如果是调用第三方api抛出的错误,如上面那个例子。 其实捕获栈信息的意义不是很大,但是也可以少量捕捉一些,比如一前一尾。但是尾巴不好判断,所以考虑到性能,只捕捉前面2行就够意思了。后面的话 要逐行判断,如果是本应用的类,则捕捉。

捕捉到最后,是三个点:  ... 39 more 这样,Caused by就处理完成了。如果后面还有Caused by,也用该方法继续捕捉。

综上,其实就一个方法: 检测非\tat开头的字符串,记录其信息。(可设定长度大小,比如小于1000)

对于\tat开头的字符串,判断是否为本应用+特定api的前缀,是则保留。

特殊处理: 保留紧跟着非\tat开头的字符串的2行栈信息,

保留出现本应用+特定api前缀那一行的前3行信息。

算法复杂度,假设有100行,一行比较30次char(用startWith),总共for循环100次,每次比较一个startWith,

每次循环假设还做一个5个if的判断,那么一共比较的次数为500+3000=3500,对CPU来说,应该不成问题。

Java异常处理设计(二)的更多相关文章

  1. Java异常处理设计(一)

    很多次的经验教训,让我不得不重视异常处理.经常遇到的问题如下:1)日志不准确,错误原因难以查明!!2)日志量太大,查找麻烦!!3)哪里需要记录日志,哪里不用记录日志?往往随心所欲!!分析以上问题,深入 ...

  2. Java异常处理设计(三)

    接着上一篇讲. 一个异常日志处理的例子: 抛出异常的地方为: try{ ... ...//省略N行 }catch( Exception e){ throw new RuntimeException ( ...

  3. Java异常处理和设计

    在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常处理,当程序出错从哪里寻 ...

  4. Java异常处理和设计【转】

    Java异常处理和设计 在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常 ...

  5. java异常处理的设计

    有一句这样话:一个衡量Java设计师水平和开发团队纪律性的好方法就是读读他们应用程序里的异常处理代码. 本文主要讨论开发Java程序时,如何设计异常处理的代码,如何时抛异常,捕获到了怎么处理,而不是讲 ...

  6. Java秒杀简单设计二:数据库表和Dao层设计

    Java秒杀简单设计二:数据库表Dao层设计 上一篇中搭建springboot项目环境和设计数据库表  https://www.cnblogs.com/taiguyiba/p/9791431.html ...

  7. JAVA 异常处理机制

    主要讲述几点: 一.异常的简介 二.异常处理流程 三.运行时异常和非运行时异常 四.throws和throw关键字 一.异常简介 异常处理是在程序运行之中出现的情况,例如除数为零.异常类(Except ...

  8. java异常处理机制

    本文从Java异常最基本的概念.语法开始讲述了Java异常处理的基本知识,分析了Java异常体系结构,对比Spring的异常处理框 架,阐述了异常处理的基本原则.并且作者提出了自己处理一个大型应用系统 ...

  9. Java 异常处理机制和集合框架

    一.实验目的 掌握面向对象程序设计技术 二.实验环境 1.微型计算机一台 2.WINDOWS操作系统,Java SDK,Eclipse开发环境 三.实验内容 1.Java异常处理机制涉及5个关键字:t ...

随机推荐

  1. $.cookie is not a function的错误原因

    网上说的原因是:“手残导入2次jquery库文件 ” 是的,就是这个原因.引入了两次jquery.js

  2. (3)The critical role librarians play in the opioid crisis

    https://www.ted.com/talks/chera_kowalski_the_critical_role_librarians_play_in_the_opioid_crisis 00:1 ...

  3. Oracle 除数为0的处理(decode)

    select   (a/b*100)per   from   aa;      当b为0时,提示除数为0,      本人想当除数为0时,不让系统提示出错,结果显示0即可? 解决:select   d ...

  4. vba遗传算法之非一致性突变

    http://www.docin.com/p-959323141-f4.html Sub 非一致性变异() Dim totalGenerate As Integer, currentGenerate ...

  5. php 爬虫简单示例

    <?php error_reporting(E_ALL^E_NOTICE^E_WARNING); $url = "http://cp.360.cn/ssccq/?menu&r_ ...

  6. Edifact 95B报文解读

    PART 1 INTRODUCTION D100_D.95B PART 2 UNIFORM RULES OF CONDUCT FOR INTERCHANGE PART2_D.ZIP(1) OF TRA ...

  7. Warning the user/local/mysql/data directory is not owned by the mysql user

    sudo chown -RL root:mysql /usr/local/mysql sudo chown -RL mysql:mysql /usr/local/mysql/data sudo /us ...

  8. Java Applet在IE中浏览

    1. IE --> 工具 --> Internet选项 --> 取消“将Java1.6.0.4加入Internet”选择项. 2. 开始 --> 控制面板 --> Jav ...

  9. day21(Listener监听器)

    监听器只要分为监听web对象创建与销毁,监听属性变化,感知监听器. 1.监听web对象的创建与销毁 servletContextListener   监听ServletContext对象的创建和销毁 ...

  10. ZUFE2481 神奇的字符串 2017-05-12 16:41 39人阅读 评论(0) 收藏

    2481: 神奇的字符串 时间限制: 3 Sec  内存限制: 256 MB 提交: 8  解决: 3 [提交][状态][讨论版] 题目描述 输入 输出 样例输入 abcb 1000 1100 350 ...