考虑对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. python模块:sys

    # encoding: utf-8 # module sys # from (built-in) # by generator 1.145 """ This module ...

  2. Linux下启动tomcat报错,WARN org.apache.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect java.net.ConnectException:

    tomcat启动完了之后,一直不停的打印这种错误信息,看表面上,应该是zk节点下的数据是空的,连接不上服务,所以一直在尝试连接,然后一直又连不上: 完整的错误信息: 407662 [usf-ZooKe ...

  3. 查询正在执行的SQL语句DBCCINPUTBUFFER

    DBCC INPUTBUFFER 返回进程下SQL语句 如果查询所有的进程如何呢? 创建一个存储过程 CREATE proc pr_dbccINPUTBUFFER(@spid varchar(200) ...

  4. vue的过渡和动画

    简单过渡 .fade-enter-active, .fade-leave-active { transition: all .5s; } /*.fade-enter, .fade-leave-to { ...

  5. Java EE Servlet 几个path

    ContextPath Context ['kɒntekst] 不识庐山真面目,只缘身在此山中. 相对路径 RealPath 绝对路径 ServletPath 就是servlet-mapping 中 ...

  6. Cron连接正常工作5次后异常原因分析

    目录 目录 1 问题描述 1 分析定位 1 解决方法 2 附1:Cron工作流 3 附2:SIGPIPE发生的位置 3 如果一个shell命令的"$?"值为141,则它是收到了SI ...

  7. C++编译器详解(三)函数调用的区别:_cdecl以及_stdcall

    1._stdcall是Pascal程序的缺省调用方式,通常用于Win32 API中,函数采用从右到左的压栈方式,自己在退出时清空堆栈.VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上&qu ...

  8. (转)JDK安装配置教程

    转自:http://jingyan.baidu.com/article/bea41d435bc695b4c41be648.html JDK作为JAVA开发的环境,不管是做JAVA开发的学生,还是做安卓 ...

  9. wc2016鏖战表达式(可持久treap)

    由运算符有优先级可以想到先算优先级小的,然后两边递归,但符号比较少,有大量相同的,同级之间怎么办呢?因为运算符满足结合律,同级之间选一个然后两边递归也是没问题的,然后我们想到用fhqtreap进行维护 ...

  10. (spfa) Highway Project (zoj 3946 )

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5718   Highway Project Time Limit: 2 Seco ...