BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

程序那些事:日志记录的作用和方法

| 作者 冶秀刚 关注 0 他的粉丝 发布于 2012年11月7日. 估计阅读时间: 11 分钟 | 都知道硅谷人工智能做的好,你知道 硅谷的运维技术 也值得参考吗?QCon上海带你探索其中的奥义

程序中记录日志一般有两个目的:Troubleshooting和显示程序运行状态。好的日志记录方式可以提供我们足够多定位问题的依据。日志记录大家都会认为简单,但如何通过日志可以高效定位问题并不是简单的事情。这里列举下面三个方面的内容,辅以代码示例,总结如何写好日志,希望对他人有所启发和帮助:

  • 怎样记日志可以方便Troubleshooting
  • 程序运行状态可以记哪些
  • 应该避免怎样的日志方式

怎样记日志可以方便Troubleshooting?

1. 对外部的调用封装

程序中对外部系统与模块的依赖调用前后都记下日志,方便接口调试。出问题时也可以很快理清是哪块的问题

1.  LOG.debug("Calling external system:" + parameters);  
2.  Object result = null;  
3.  try {  
4.      result = callRemoteSystem(params);  
5.      LOG.debug("Called successfully. result is " + result);  
6.  } catch (Exception e) {  
7.      LOG.warn("Failed at calling xxx system . exception : " + e);  
8.  }  

2.状态变化

程序中重要的状态信息的变化应该记录下来,方便查问题时还原现场,推断程序运行过程

1.  boolean isRunning;  
2.    
3.  isRunning = true;  
4.  LOG.info("System is running");  
5.    
6.  //...  
7.    
8.  isRunning = false;  
9.  LOG.info("System was interrupted by " + Thread.currentThread().getName());  

3.系统入口与出口:

这个粒度可以是重要方法级或模块级。记录它的输入与输出,方便定位

1.  void execute(Object input) {  
2.      LOG.debug("Invoke parames : " + input);  
3.      Object result = null;  
4.        
5.      //business logic
6.        
7.      LOG.debug("Method result : " + result);  
8.  }  

4.业务异常:

任何业务异常都应该记下来:

1.  try {  
2.      //business logical  
3.  } catch (IOException e) {  
4.      LOG.warn("Description xxx" , e);  
5.  } catch (BusinessException e) {  
6.      LOG.warn("Let me know anything");  
7.  } catch (Exception e) {  
8.      LOG.error("Description xxx", e);  
9.  }  
10.   

5.非预期执行:

为程序在“有可能”执行到的地方打印日志。如果我想删除一个文件,结果返回成功。但事实上,那个文件在你想删除之前就不存在了。最终结果是一致的,但程序得让我们知道这种情况,要查清为什么文件在删除之前就已经不存在

1.  int myValue = xxxx;  
2.  int absResult = Math.abs(myValue);  
3.  if (absResult < 0) {  
4.      LOG.info("Original int " + myValue + "has nagetive abs " + absResult);  
5.  }  

6.很少出现的else情况:

else可能吞掉你的请求,或是赋予难以理解的最终结果

1.  Object result = null;  
2.  if (running) {  
3.     result = xxx;  
4.  } else {  
5.     result = yyy;  
6.     LOG.debug("System does not running, we change the final result");  
7.  }  

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

程序在运行时就像一个机器人,我们可以从它的日志看出它正在做什么,是不是按预期的设计在做,所以这些正常的运行状态是要有的。

1. 程序运行时间:

1.  long startTime = System.currentTime();  
2.    
3.  // business logical  
4.    
5.  LOG.info("execution cost : " + (System.currentTime() - startTime) + "ms");   

2. 大批量数据的执行进度:

 
1.  LOG.debug("current progress: " + (currentPos * 100 / totalAmount) + "%");  

3.关键变量及正在做哪些重要的事情:

执行关键的逻辑,做IO操作等等

1.  String getJVMPid() {  
2.     String pid = "";  
3.     // Obtains JVM process ID  
4.     LOG.info("JVM pid is " + pid);  
5.     return pid;  
6.  }  
7.    
8.  void invokeRemoteMethod(Object params) {  
9.      LOG.info("Calling remote method : " + params);  
10.     //Calling remote server  
11. }  

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

1. 混淆信息的Log

日志应该是清晰准确的: 当看到日志的时候,你知道是因为连接池取不到连接导致的问题么?

1.  Connection connection = ConnectionFactory.getConnection();  
2.  if (connection == null) {  
3.      LOG.warn("System initialized unsuccessfully");  
4.  }  

2. 记错位置

产品代码中,使用console记录日志,导致没有找到日志。

     1. } catch (ConfigurationException e) {
     2.    e.printStackTrace();
     3. }

3. 记错级别

记错级别常常发生,常见的如:混淆代码错误和用户错误,如登录系统中,如果恶意登录,那系统内部会出现太多WARN,从而让管理员误以为是代码错误。可以反馈用户以错误,但是不要记录用户错误的行为,除非想达到控制的目的。

1.  LOG.warn("Failed to login by "+username+");

4. 遗漏信息

这里可能包含两种情况:(1)用户自己少写了信息,导致毫无参考价值;(2)用户调用log的方式导致丢失信息,如下例,没有stack trace.

     1.  } catch (Exception ex) {
     2.   log.error(ex);
     3.  }

总结:

日志记录在程序员日常编程实践中必须面对的事情,本文针对这个话题谈了下自己的体会,希望读者能有所收益。多有不足,请多包涵。

参考文献

http://www.infoq.com/cn/articles/10-java-questions-easy-to-ignore

作者介绍

冶秀刚,平台工程师,从事分布式收集与存储系统的研究与开发,爱好读书,喜欢涉猎各类能长见识的内容


给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

不够深入 by joe eric

不仅仅这些。

Re: 不够深入 by 陈 建平

写的不错了,基本是个人心得体会。

Re: 不够深入 by cy shun

赞同楼上,是写得不错了,能做到楼主所写,基本上已经很好了,再在一些关键业务处理上,增加一些观察日志,可以更好的了解系统工作或数据异常情况。

不错 by 周 祖林

不错,较全面,遵循5w原则!

by 王 振军

嗯,总结的挺好。

日志记录太多,会不会影响程序的性能? by ye zhwi

总结得很好,不过也纠结了,如果日志打得太多,会不会影响程序的性能?打得少又不能通过日志定位问题和程序的状态。不知道大家怎么解决这个问题?

Re: 日志记录太多,会不会影响程序的性能? by lin bareberry

我也想问这个问题

Re: 日志记录太多,会不会影响程序的性能? by 何 旺

记得多肯定会影响业务流程的执行,我们可以把日志记录的功能看得更大一些,也当做一个程序的功能,比如采集信息,分析数据,监控业务执行,这样任务多起来就不累赘了,,鄙人愚见,

还可以更深度一些 by song xiaoyu

也可以用专业类的软年,如日志易,日志易的SAAS现在免费试用,可以在Rizhiyi官网注册

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

9 讨论

深度内容

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT