Exception时信息的记录
系统总有出现异常的时候,那么出现异常时应该如何处理?
一直以来,我都以为这么处理就足够的:
- 在日志中打印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时信息的记录的更多相关文章
- u-boot从nand 启动时的问题解决记录
u-boot从nand 启动时的问题解决记录 问题描述: 使用u-boot-1.1.6版本u-boot移植到JZ2440开发板上,当前已经能够从Nor启动,但是不能从Nand正常启动(u-boot大小 ...
- Python中获取异常(Exception)信息
异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置.下面介绍几种python中获取异常信息的方法,这里获取异常(Exception)信息采用try...except...程序 ...
- Python中获取异常(try Exception)信息
异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置. 这里获取异常(Exception)信息采用try...except...程序结构.如下所示: try: ... exce ...
- datagrid返回记录为0时显示“没有记录”
datagrid返回记录为0时显示“没有记录”,此问题的 <script>var myview = $.extend({},$.fn.datagrid.defaults.view,{ on ...
- 利用神器BTrace 追踪线上 Spring Boot应用运行时信息
概述 生产环境中的服务可能会出现各种问题,但总不能让服务下线来专门排查错误,这时候最好有一些手段来获取程序运行时信息,比如 接口方法参数/返回值.外部调用情况 以及 函数执行时间等信息以便定位问题.传 ...
- delphi 中Adoquery ,在打开时能否让记录指针不移动? [问题点数:40分,结帖人microd]
delphi 中Adoquery ,在打开时能否让记录指针不移动?由于数据集Adoquery 时,它的针指称动会废时,能否在打开完成之前不让记录指针不移动.打开完毕之后再回复移动? 这样用:self. ...
- 怎么启用apache的mod_log_sql模块将所有的访问信息直接记录在mysql中
怎么启用apache的mod_log_sql模块将所有的访问信息直接记录在mysql中
- java的异常(Exception)信息的详细记录
下面的三个方法都是获取异常的详细信息,或许的异常详细信息以字符串的形式返回,保持栈堆载的风格 方法一: public static String getExceptionAllinformation( ...
- 通过拦截器Interceptor实现Spring MVC中Controller接口访问信息的记录
java web工程项目使用了Spring+Spring MVC+Hibernate的结构,在Controller中的方法都是用于处理前端的访问信息,Controller通过调用Service进行业务 ...
随机推荐
- iphone openssh
安装openssh 用户名:默认是 root 密码:默认是 alpine 修改登陆密码:passwd
- python之函数用法xrange()
# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法xrange() #xrange() #说明:返回一个生成器 #xrange做循环的性 ...
- HTTP报文01
#xiaodeng #HTTP报文01 #HTTP权威指南 45 报文向下游流动- 不管是请求报文还是响应报文,所有报文都会向下游流动. 所有报文的发送者都在接收者的上游. 报文的组成部分 对报文进行 ...
- Opcode查看利器之vld
简介 在PHP的生命周期中 词法分析(zend_language_scanner),将PHP代码转换为语言片段(Tokens) 语法分析(zend_language_parser)将Tokens转换成 ...
- MySQL中的共享锁
MySQL对外提供了一种应用层级别的共享锁,通过这个共享锁,数据库之上的应用程序可以实现互斥功能.这个共享锁通过一组MySQL 内置函数实现. GET_LOCK(str,timeout) 这个函数的 ...
- 由select/epoll返回的非阻塞connect还会是EINPROGRESS状态吗?
一般情况下,我们像下面代码中所示的这样使用非阻塞connect: #include <stdio.h> #include <stdlib.h> #include <str ...
- mac下安装mysql 1820 重置默认密码
mac安装mysql时会给出一个临时密码 记录下来 2018-03-17T02:14:10.809431Z 1 [Note] A temporary password is generated for ...
- IIS7的应用程序池详细解析
在 IIS 7 中,应用程序池有两种运行模式:集成模式和经典模式.应用程序池模式会影响服务器处理托管代码请求的方式 在IIS 7中,添加一个应用程序或者单独的网站,默认会自动新建一个对应的“应用程序池 ...
- pythonl练习笔记——threading线程中的事件Event
1 事件Event 使用方法:e = threading.Event() Event对象主要用于线程间通信,确切地说是用于主线程控制其他线程的执行. Event事件提供了三个方法:wait等待.cle ...
- JMeter学习笔记---性能分析
图像结果: 通过观察平均采样响应时长,用户可以直观地看到,随着并发压力的加大,以及性能测试时间的延长,系统性能所发生的变化.正常情况下,平均采样响应时长曲线应该是平滑的,并大致平行于图像下边界. 异常 ...