系统总有出现异常的时候,那么出现异常时应该如何处理?

一直以来,我都以为这么处理就足够的:

  • 在日志中打印Exception的堆栈信息,以便排查原因
  • 反馈给用户系统xxx出现问题
package com.nicchagil.util.requestlogger;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; public class RequestDemoServlet extends HttpServlet { private final Logger logger = Logger.getLogger(RequestDemoServlet.class); public RequestDemoServlet() {
super();
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ResultSet rs = null;
PreparedStatement pstmt = null;
Connection conn = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@hostname:port:sid", "username",
"password"); pstmt = conn.prepareStatement("select * from t_xxx t where t.id = ? "); pstmt.setString(1, "paramter");
rs = pstmt.executeQuery(); while (rs.next()) {
System.out.println("'" + rs.getString("result1") + "' - " + "'" + rs.getString("result2") + "'");
} } catch (ClassNotFoundException e) {
// Print exception logs
logger.error("Failed to query xxx", e); // Prompt that system error
response.getWriter().write("Failed to query xxx!"); } catch (SQLException e) {
// Print exception logs
logger.error("Failed to query xxx", e); // Prompt that system error
response.getWriter().write("Failed to query xxx!"); } catch (Throwable t) {
// Print exception logs
logger.error("System error", t); // Prompt that system error
response.getWriter().write("System error!"); } finally {
try {
if (rs != null) {
rs.close();
rs = null;
}
if (pstmt != null) {
pstmt.close();
pstmt = null;
}
if (conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
// Print exception logs
logger.error("System error", e); // Prompt that system error
response.getWriter().write("System error!");
}
} } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
} }

RequestDemoServlet

日前,得到一位资深同事Glen的指点,深知以上的操作是不足够的。

简单来说,我们需要记录,谁在什么时候做了什么事情

尽量详细地记录这些信息,让我们拥有更详细的信息用于排查问题(不知道请求参数的情况下,确实难以定位问题);在和其他团队作联合调试时,我们也可以提供足够的信息,不致陷于尴尬、被动地位。

  • 当前登录用户的ID或代号(在系统需要登录并用户已登录的前提下)
  • 当前请求的URL
  • 当前的请求参数

一般情况下,Web Project是在Servlet(或使用框架时所称的Action、Controller、Ctrl)处理Exception的。

除了“当前的请求参数”外,其他的都较好处理。因为每个请求的参数不尽一致,在每个Servlet都hardcode来打印各个参数,这是一个累人的活。

这里,分享一个静态方法用于打印HttpServletRequest的全部请求参数,这样就不致于每次都hardcode打印请求参数了。

package com.nicchagil.util.requestlogger;

import java.util.Iterator;
import java.util.Map; import javax.servlet.http.HttpServletRequest; public class RequestLogger { /**
* toString for HttpServletRequest Parameters
* @param request
* @return
*/
public static String toString(HttpServletRequest request) { Map map = request.getParameterMap(); /* Since there are String[] in the map, can not return map.toString() directly. */ if (map == null || map.isEmpty()) {
return "";
} StringBuffer sb = new StringBuffer();
Object key = null;
String[] value = null;
Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) {
key = iterator.next();
value = (String[])map.get(key); sb.append(key.toString()).append(" : ").append(toString(value, true));
sb.append("\n");
} return sb.toString();
} /**
* toString for String Array
* @param stringArray
* @return
*/
public static String toString(String[] stringArray, boolean alwaysArray) { if (stringArray == null || stringArray.length == 0) {
return "";
} if (!alwaysArray) {
if (stringArray.length == 1) {
return stringArray[0];
}
} StringBuffer sb = new StringBuffer();
sb.append("["); for (int i = 0; i < stringArray.length; i++) {
sb.append(stringArray[i]); if (i < stringArray.length - 1) {
sb.append(", ");
}
} sb.append("]"); return sb.toString();
} }

RequestLogger

Exception时信息的记录的更多相关文章

  1. u-boot从nand 启动时的问题解决记录

    u-boot从nand 启动时的问题解决记录 问题描述: 使用u-boot-1.1.6版本u-boot移植到JZ2440开发板上,当前已经能够从Nor启动,但是不能从Nand正常启动(u-boot大小 ...

  2. Python中获取异常(Exception)信息

    异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置.下面介绍几种python中获取异常信息的方法,这里获取异常(Exception)信息采用try...except...程序 ...

  3. Python中获取异常(try Exception)信息

    异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置. 这里获取异常(Exception)信息采用try...except...程序结构.如下所示: try: ... exce ...

  4. datagrid返回记录为0时显示“没有记录”

    datagrid返回记录为0时显示“没有记录”,此问题的 <script>var myview = $.extend({},$.fn.datagrid.defaults.view,{ on ...

  5. 利用神器BTrace 追踪线上 Spring Boot应用运行时信息

    概述 生产环境中的服务可能会出现各种问题,但总不能让服务下线来专门排查错误,这时候最好有一些手段来获取程序运行时信息,比如 接口方法参数/返回值.外部调用情况 以及 函数执行时间等信息以便定位问题.传 ...

  6. delphi 中Adoquery ,在打开时能否让记录指针不移动? [问题点数:40分,结帖人microd]

    delphi 中Adoquery ,在打开时能否让记录指针不移动?由于数据集Adoquery 时,它的针指称动会废时,能否在打开完成之前不让记录指针不移动.打开完毕之后再回复移动? 这样用:self. ...

  7. 怎么启用apache的mod_log_sql模块将所有的访问信息直接记录在mysql中

    怎么启用apache的mod_log_sql模块将所有的访问信息直接记录在mysql中

  8. java的异常(Exception)信息的详细记录

    下面的三个方法都是获取异常的详细信息,或许的异常详细信息以字符串的形式返回,保持栈堆载的风格 方法一: public static String getExceptionAllinformation( ...

  9. 通过拦截器Interceptor实现Spring MVC中Controller接口访问信息的记录

    java web工程项目使用了Spring+Spring MVC+Hibernate的结构,在Controller中的方法都是用于处理前端的访问信息,Controller通过调用Service进行业务 ...

随机推荐

  1. 解决windows10 启动蓝屏 ntfs file system

    启动 --> 疑难解答 -->高级工具 --> 命令行--> chkdsk /x /f c: cd c: ok ^_-

  2. 解决 maven 项目启动 提示 class not find

    第一种方法: 项目 --> .classpath <classpathentry exported="true" kind="con" path=& ...

  3. 纯jascript解决手机端拍照、选图后图片被旋转问题

    需要的js1 需要的js2 这里主要用到Orientation属性. Orientation属性说明如下: 旋转角度 参数 0° 1 顺时针90° 6 逆时针90° 8 180° 3 <!DOC ...

  4. while(cin>>word)时的结束方法

    有一个要注意的地方,以前不理解在while里面用cin >> val是什么意思,用这个当条件的话,通过检测其流的状态来判断结束: (1)若流是有效的,即流未遇到错误,那么检测成功: (2) ...

  5. sybase数据库学习笔记(一)

    sybase的基本框架 sybase数据库由系统数据库.用户数据库.数据库设备和辅助文件组成. 1. 系统数据库 sybase数据库是多个数据库结构的数据库管理系统.分为系统数据库和用户数据库. 系统 ...

  6. 自定义AppServer

    TelnetSever.cs public class TelnetServer : AppServer<TelnetSession> { protected override bool ...

  7. Linux下通用线程池的创建与使用

    线程池:简单地说,线程池 就是预先创建好一批线程,方便.快速地处理收到的业务.比起传统的到来一个任务,即时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率更高. 在linux中,使用的 ...

  8. 将Gradle项目公布到maven仓库

    将Gradle项目公布到maven仓库 1 Gradle简单介绍 1.1 Ant.Maven还是Gradle? 1.1.1 Ant和Maven介绍 全称为Apache Maven,是一个软件(特别是J ...

  9. 使用DotNetBarcode制作基本常用条码

    核心代码: /// <summary> /// 打印一维码 /// </summary> /// <param name="codeText"> ...

  10. IE浏览器SCRIPT5拒绝访问,谷歌浏览器XMLHttpRequest can't load file:/......

    一.背景 在测试ajax时,写了一个ajax.html,目的是访问example.txt中的文本,写好后,右键该html选择在浏览器中打开,浏览器页面上无内容.调出调试窗口: IE浏览器:SCRIPT ...