前段时间,公司的一个项目,需要做很多的数据接口和同步程序,于是就遇到了日志记录的问题,何时记录,如何记录,哪些要记哪些不用记等问题。针对日志记录的问题,经过一系列讨论,终于达成了统一的处理办法。解决了各个模块系统,不同的开发人员,日志记录不统一,随意的问题。今天终于抽出时间把这个问题总结并结合网络上的资料,进行整理。
为什么要记录日志
记录日志是调试程序,监视程序运行的一种重要的方式,主要有两个目的:bug的及时发现和定位,显示程序运行状态。正确详细的日志记录能够快速的定位问题。同样,通过查看日志,可以看出程序正在做什么,是不是按预期的设计在执行,所以记录下程序的运行状态是必要的。
哪些地方需要记日志
1. 调用或封装外部程序或接口 程序中对外部系统与模块的依赖调用前后都应该记下日志,方便接口调试。出问题时也可以很快查出是哪里出的问题
LOG.debug("Calling external system:" + parameters); Object result = null; try { result = callRemoteSystem(params); LOG.debug("Called successfully. result is " + result); } catch (Exception e) { LOG.warn("Failed at calling xxx system . exception : " + e); } 2.对重要对象或变量被修改,要以INFO记录修改前的信息和修改后的状态。 程序中重要的状态信息的变化应该记录下来,方便查问题时还原现场,推断程序运行过程
boolean isRunning; isRunning = true; LOG.info("System is running"); //... isRunning = false; LOG.info("System was interrupted by " + Thread.currentThread().getName()); 3.系统入口与出口: 系统的入口和出口,重要方法或模块的执行。记录它的输入与输出,方便定位。
4.业务异常或者重要的业务处理: 任何业务异常都应该记下来,还有系统中一些重要的业务,比如结算等业务,也最好能记录下来。
5.非预期执行: 为程序在“有可能”执行到的地方打印日志。如果我想删除一个文件,结果返回成功。但事实上,那个文件在你想删除之前就不存在了。最终结果是一致的,但程序得让我们知道这种情况,要查清为什么文件在删除之前就已经不存在
int myValue = xxxx; int absResult = Math.abs(myValue); if (absResult < 0) { LOG.info("Original int " + myValue + "has nagetive abs " + absResult); } 6.很少出现的else情况: 代码中,一定要有完整的if else,如果else 里面没有要执行的,记录日志,这样避免else吞掉你的请求,或是返回给你难以理解的结果。
Object result = null; if (running) { result = xxx; } else { result = yyy; LOG.debug("System does not running, we change the final result"); }
7. 批量数据的执行进度:
LOG.debug("current progress: " + (currentPos * 100 / totalAmount) + "%"); 日志记录的方式
1. 日志信息应该包含记录程序运行时间和错误发生的时间.
2. 日志信息清晰准确有意义 日志应该是清晰准确的: 当看到日志的时,就能准确的知道错误是因为连接池取不到连接导致的问题。
Connection connection = ConnectionFactory.getConnection(); if (connection == null) { LOG.warn("System initialized unsuccessfully"); } 3. 记录错误的位置 代码中,一定要记录下错误所在的文件名和函数名(必须能区分开重载函数),有行数最好。
4. 区分日志级别 在程序中Log进行分级是很重要的,通常可以分为6 级:TRACE<DEBUG<INFO<WARN<ERROR<FATAL。 DEBUG用来输出调试信息,一般是在程序中不是非常重要的地方;INFO代表一些比较重要的信息,比如程序初始化完毕,ERROR一般指程序本身引起的,可以恢复的错误;FATAL一般指程序所依赖的环境出现错误,使的程序不恢复。其中常用的是DEBUG和 ERROR。
5. 信息详细准确 一定要记录下完整准确的信息,否则还不如记录,因为错误的信息可能会误导开发人员。所以最简单的办法就是记录完整的stack trace. 6. 最好能给log带上上下文 没有相应的上下文的log,不过是噪音,它们不会对调试过程中有意义的数值或是空间起作用。 Transaction failed 这样的log信息比没有记录更让人抓狂。
|