您的位置:首页 > 其它

程序那些事:日志记录的作用和方法----如何在程序中记录日志

2014-03-12 10:14 405 查看
转载地址:http://www.infoq.com/cn/articles/why-and-how-log程序中记录日志一般有两个目的:Troubleshooting(故障定位)和显示程序运行状态。好的日志记录方式可以提供我们足够多定位问题的依据。日志记录大家都会认为简单,但如何通过日志可以高效定位问题并不是简单的事情。这里列举下面三个方面的内容,辅以代码示例,总结如何写好日志,希望对他人有所启发和帮助:怎样记日志可以方便Troubleshooting(故障定位)程序运行状态可以记哪些应该避免怎样的日志方式

怎样记日志可以方便Troubleshooting?

1.对外部的调用封装程序中对外部系统与模块的依赖调用前后都记下日志,方便接口调试。出问题时也可以很快理清是哪块的问题
1.LOG.debug("Callingexternalsystem:"+parameters);
2.Objectresult=null;
3.try{
4.result=callRemoteSystem(params);
5.LOG.debug("Calledsuccessfully.resultis"+result);
6.}catch(Exceptione){
7.LOG.warn("Failedatcallingxxxsystem.exception:"+e);
8.}
2.状态变化程序中重要的状态信息的变化应该记录下来,方便查问题时还原现场,推断程序运行过程
1.booleanisRunning;
2.
3.isRunning=true;
4.LOG.info("Systemisrunning");
5.
6.//...
7.
8.isRunning=false;
9.LOG.info("Systemwasinterruptedby"+Thread.currentThread().getName());
3.系统入口与出口:这个粒度可以是重要方法级或模块级。记录它的输入与输出,方便定位
1.voidexecute(Objectinput){
2.LOG.debug("Invokeparames:"+input);
3.Objectresult=null;
4.
5.//businesslogic
6.
7.LOG.debug("Methodresult:"+result);
8.}
4.业务异常:任何业务异常都应该记下来:
1.try{
2.//businesslogical
3.}catch(IOExceptione){
4.LOG.warn("Descriptionxxx",e);
5.}catch(BusinessExceptione){
6.LOG.warn("Letmeknowanything");
7.}catch(Exceptione){
8.LOG.error("Descriptionxxx",e);
9.}
10.
5.非预期执行:为程序在“有可能”执行到的地方打印日志。如果我想删除一个文件,结果返回成功。但事实上,那个文件在你想删除之前就不存在了。最终结果是一致的,但程序得让我们知道这种情况,要查清为什么文件在删除之前就已经不存在
1.intmyValue=xxxx;
2.intabsResult=Math.abs(myValue);
3.if(absResult<0){
4.LOG.info("Originalint"+myValue+"hasnagetiveabs"+absResult);5.}
6.很少出现的else情况:else可能吞掉你的请求,或是赋予难以理解的最终结果1.Objectresult=null;
2.if(running){
3.result=xxx;
4.}else{
5.result=yyy;
6.LOG.debug("Systemdoesnotrunning,wechangethefinalresult");
7.}

程序运行状态可以记哪些?

程序在运行时就像一个机器人,我们可以从它的日志看出它正在做什么,是不是按预期的设计在做,所以这些正常的运行状态是要有的。1.程序运行时间:
1.longstartTime=System.currentTime();
2.
3.//businesslogical
4.
5.LOG.info("executioncost:"+(System.currentTime()-startTime)+"ms");
 
2.大批量数据的执行进度:
1.LOG.debug("currentprogress:"+(currentPos*100/totalAmount)+"%");
3.关键变量及正在做哪些重要的事情:执行关键的逻辑,做IO操作等等
1.StringgetJVMPid(){
2.Stringpid="";
3.//ObtainsJVMprocessID
4.LOG.info("JVMpidis"+pid);
5.returnpid;
6.}
7.
8.voidinvokeRemoteMethod(Objectparams){
9.LOG.info("Callingremotemethod:"+params);
10.//Callingremoteserver
1.}

应该避免怎样的日志方式?

1.混淆信息的Log日志应该是清晰准确的:当看到日志的时候,你知道是因为连接池取不到连接导致的问题么?
1.Connectionconnection=ConnectionFactory.getConnection();
2.if(connection==null){
3.LOG.warn("Systeminitializedunsuccessfully");
4.}
2.记错位置产品代码中,使用console记录日志,导致没有找到日志。1.}catch(ConfigurationExceptione){
2.e.printStackTrace();
3.}
3.记错级别记错级别常常发生,常见的如:混淆代码错误和用户错误,如登录系统中,如果恶意登录,那系统内部会出现太多WARN,从而让管理员误以为是代码错误。可以反馈用户以错误,但是不要记录用户错误的行为,除非想达到控制的目的。
1.LOG.warn("Failedtologinby"+username+");
4.遗漏信息这里可能包含两种情况:1)用户自己少写了信息,导致毫无参考价值;2)用户调用log的方式导致丢失信息,如下例,没有stacktrace.
1.}catch(Exceptionex){
2.log.error(ex);
3.}

总结:

日志记录在程序员日常编程实践中必须面对的事情,本文针对这个话题谈了下自己的体会,希望读者能有所收益。多有不足,请多包涵。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: