关于log4j错误日志的保存
因为最近着手了项目里面日志的规范化工作,之前开发的时候都是System.out.println("xxxxx")这种打印语句一了百了,十分常见和简便~~
但是一旦项目进行到了后期,开发工作基本完成,日志的规范化就该提上日程啦。日志存在的意义就是记录用户在使用的过程中的操作和问题,尤其是问题,因为错误日志是更有价值的。打印到控制台的
System.out.println("xxxxx")语句只是暂时的调试功能,我们需要把错误保存起来,以便出现了问题的时候,可以去历史的错误日志中查看问题,定位问题的节点~~~
对于异常(错误),我们常常在try{...}catch(Exception e) {...}结构中catch异常。最常见的是e.printStackTrace()将错误的堆栈信息打印出来,但是问题是,打印的堆栈信息是在控制台的,
起不到日志的保存作用,想要保存到日志中,不能只e.printStackTrace(),所以log.error就很有必要啦。
在catch模块中使用log.error也需要注意一些重要的问题,下面使用一个小例子来说明下。
常见写法一:log.error(Exception e);
try{ String str = null; System.out.println(str.length()); } catch(Exception e) { log.error(e); e.printStackTrace(); }
打印结果:
2016-05-06 18:10:15,414 com.bcs.amp.action.alarm.Test ERROR java.lang.NullPointerException
java.lang.NullPointerException
at com.bcs.amp.action.alarm.Test.main(Test.java:16)
结果说明:log.error只打印了异常类型,异常堆栈信息由e.printStackTrace();产生而同时打印。
(即使你把log.error(e);改成log.error("错误:" + e);——log.error接收到的依然是只一个参数。
错误日志的打印变成:
2016-05-06 18:11:53,661 com.bcs.amp.action.alarm.Test ERROR 错误:java.lang.NullPointerException,还是依然打印异常类型而已。)
常见写法二:log.error("异常详细信息", Exception e);
try{ String str = null; System.out.println(str.length()); } catch(Exception e) { log.error("错误:", e); e.printStackTrace(); }
打印结果:
2016-05-06 18:14:38,151 com.bcs.amp.action.alarm.Test ERROR 错误:
java.lang.NullPointerException
at com.bcs.amp.action.alarm.Test.main(Test.java:16)
java.lang.NullPointerException
at com.bcs.amp.action.alarm.Test.main(Test.java:16)
结果说明:log.error此时和e.printStackTrace()的作用一样,也打印出了堆栈信息。区别于写法一,它有2个参数传入log.error函数,并且第二个参数是Exception对象。
显而易见,写法二的错误日志打印更具实际意义,因为我们排错的化,肯定是需要异常的堆栈信息的,只有一个异常类型名称实际意义并不大;
说完了2种常见的错误日志打印,接下来我要来看下方法的调用对日志保存的影响,先看:
public static void main(String[] args) { try{ String str = null; test(str); } catch(Exception e) { log.error("错误:", e); e.printStackTrace(); } } public static void test(String str) { try{ System.out.println(str.length()); } catch(Exception e) { log.error("test方法调用异常:" , e); e.printStackTrace(); } }
打印结果:
2016-05-06 18:20:43,654 com.bcs.amp.action.alarm.Test ERROR test方法调用异常:
java.lang.NullPointerException
at com.bcs.amp.action.alarm.Test.test(Test.java:26)
at com.bcs.amp.action.alarm.Test.main(Test.java:16)
java.lang.NullPointerException
at com.bcs.amp.action.alarm.Test.test(Test.java:26)
at com.bcs.amp.action.alarm.Test.main(Test.java:16)
结果表明:在主方法中调用其他方法,如果其他方法已经有try{...} catch(Exception e) {...}并且在catch中保存了错误日志,则主方法对于错误日志的保存操作将不再进行,这是需要注意的,
因为在实际的错误日志保存过程中,很有可能因此导致你在主方法的catch模块进行的log.error()操作不起作用。。不明白这层机制会令人很郁闷。。。
再看:
public static void main(String[] args) { try{ String str = null; test(str); } catch(Exception e) { log.error("错误:", e); e.printStackTrace(); } } public static void test(String str) { try{ System.out.println(str.length()); } catch(Exception e) { } }
此时被调用的方法test()在catch里啥都不做,打印结果竟然会是一片空白!这说明:在主方法中调用test()方法,只要test()方法有try{...} catch(Exception e) {...}结构,test()方法的catch模块啥也不处理,
主方法的catch模块的错误日志处理或堆栈信息打印操作也不会进行~~