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

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

  • 在日志中打印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. Linux内核中网络数据包的接收-第一部分 概念和框架

    与网络数据包的发送不同,网络收包是异步的的.由于你不确定谁会在什么时候突然发一个网络包给你.因此这个网络收包逻辑事实上包括两件事:1.数据包到来后的通知2.收到通知并从数据包中获取数据这两件事发生在协 ...

  2. Oracle查询备注信息

    查询表的备注信息: SELECT TABLE_NAME, TABLE_TYPE, COMMENTS FROM USER_TAB_COMMENTS WHERE TABLE_NAME = 'MR_DEPT ...

  3. dojo之配置dojoconfig

    官方教程:Configuring Dojo with dojoConfig例子: <-- set Dojo configuration, load Dojo --> <script& ...

  4. CAS 5.1.x 的搭建和使用(二)—— 通过Overlay搭建服务端-其它配置说明

    CAS单点登录系列: CAS 5.1.x 的搭建和使用(一)—— 通过Overlay搭建服务端 CAS5.1.x 的搭建和使用(二)—— 通过Overlay搭建服务端-其它配置说明 CAS5.1.x ...

  5. LoadRunner内部结构

    转载自:http://blog.sina.com.cn/s/blog_6da75b980100n2nv.html   英文版地址: http://www.rickyzhu.com/21_princip ...

  6. Linux下TCP最大连接数受限问题

    一. 文件数限制修改1.用户级别查看Linux系统用户最大打开文件限制:# ulimit -n1024 (1) vi /etc/security/limits.confmysql soft nofil ...

  7. 解决python:'ascii' codec can't encode characters in position问题

    今天把一个列表转换成字符串输出的时候出现了UnicodeEncodeError: 'ascii' codec can't encode characters in position 32-34: or ...

  8. 【WebKit内核 CEF3 】 第一篇:下载分支代码并本地编译

    关于CEF  Chromium Embedded Framework 简单说就是  WebKit内核的 对外绑定. 当前主流浏览器内核 一.Trident内核代表产品Internet Explorer ...

  9. Apache POI – Reading and Writing Excel file in Java

    来源于:https://www.mkyong.com/java/apache-poi-reading-and-writing-excel-file-in-java/ In this article, ...

  10. IOS开发之瀑布流照片墙实现

    想必大家已经对互联网传统的照片布局方式司空见惯了,这种行列分明的布局虽然对用户来说简洁明了,但是长久的使用难免会产生审美疲劳.现在网上流行一种叫做“瀑布流”的照片布局样式,这种行与列参差不齐的状态着实 ...