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)