在程序中写日志是一件非常重要,但是很容易被开发人员忽视的地方。写好程序的日志可以帮助我们大大减轻后期维护压力。
在实际的工作中,开发人员往往迫于的巨大时间压力,而写日志又是一个非常繁琐的事情,往往没有引起足够的重视。
如果我们的开发人员在一开始就养成一个良好的习惯将非常有帮助。并且在实际的工作中也应当为写日志预留足够的时间。
我们为什要写日志呢?
一般来讲,我们在程序中记录日志出自下面几个方面的需求。
* 记录用户操作的审计日志,甚至有的时候就是监管部门的要求。
* 快速定位问题的根源,
* 追踪程序执行的过程
* 追踪数据的变化
* 数据统计和性能分析
* 采集运行环境数据
多数情况下,在我们的程序上线(Go Live)之后,一旦发生异常,我们要做的第一件事就是要弄清楚当时倒底发生了什么,
例如:用户当时做了什么操作,环境有无异常,数据有什么变化,是不是反复发生,等等。
然后再进一步的确定大致是哪个方面的问题。 确定是程序的问题之后再交由开发人员去重现,研究,提出解决方案。
这个时候日志就给我们提供了第一手的资料。
在生产环境和测试环境分开的情况下,在开发人员拿到日志的时候离问题发生已经过去很长时间。
所以清晰详尽的日志信息对于我们迅速定位问题根源就显得非常重要。它既是我们找寻原因的地图,也是最直接的证据。
对于稍大一点的系统来讲,做维护的人员和开发者通常都不是同一组人,这个过程所花费的时间和人力要远远超过开发本身数倍甚至数十倍。
都有哪些人要看日志?
正如前面所讲,产品支持,运维人员,开发人员,测试人员都需要查看日志。当然自己也是要看的。
写日志有些什么要求?
上面需求对我们在程序中记录日志提出了一定的要求:
* 日志的可读性
日志是给人读的,不仅仅是让自己明白同时也要让没有接触过我们源代码的其他程序员也能够一目了然。
我常常见到很多同事在日志中打印特殊的标识符号,例如 “+++++++++++”,“--------------”和“==============”,这些符号往往让人眼花缭乱。他们的本意也仅仅是在自己调试的时候能一眼就发现这是自己的日志。既然如此,把自己名字写入日志中岂不是更明确?
把日志分类输出到不同的文件中也有利于我们排除干扰,迅速找到我们需要的信息。
* 日志的性能
无论我们把日志写到文件还是数据库,都需要消耗IO资源。适当的控制日志的输出也有利于提高程序的性能。例如:
尽量避免在在大的循环中打印意义不大的日志内容。
输出日志之前最好能判断日志的级别(例如. debug前先调用isDebugEnabled()作出判断)。
* 占用的磁盘空间
通常,我们都是把日志写入磁盘上的日志文件中。适当的使用滚动日志并且定时清除旧文件是有好处的。
我见过这样一个例子,程序运行几次后就跑不起来了,前几次都是正常的。怎么都想不明白程序有什么问题,最后才发现居然是日志文件占满了磁盘空间。
在实际的应用中出现上G的日志文件也往往不少见。要在这样规模的日志文件中找出对解决问题有用的信息也是一大挑战。
* 日志的时效性
有的时候我们并不能及时的发现问题。需要追溯之前的日志。所以我们是需要保留一段时间以内的日志便于追溯。
* 日志的级别
通常我们在产品环境中日志的级别都在INFO以上,所以我们必须保证在这样的情况下程序仍然能够输出足够我们作出判断的信息。
* 日志的内容
我们在写日志的时候,需要注意输出适当的内容。
首先,尽量使用业务相关的描述。我们的程序是实现某种业务的,那么就最好能描述清楚这个时候走到了业务过程的哪一步。
其次,避免在日志中输出一些敏感信息,例如用户名和密码。
以及,要保持编码的一致。如果不能保证就尽量使用英文而不是中文。这样当我们拿到日志之后就不会因为看到一堆乱码而不知所云了。
总结:
程序日志:
对每个执行的方法要写入日志
具体到某个模块,某个方法,日志级别(错误,警告,信息),时间,sql,请求的入参,出参,请求输出
操作日志:
操作人,操作ip,操作业务
nosql,日志监控模块,可按条件查询;定时清除数据,防止内存溢出;对记录可以写备注;
坚持学习,成就自我