逖靖寒的世界

每天进步一点点

导航

[翻译]Log Everything All the Time

前言:

本文翻译来自 Log Everything All the Time,其中个人省略了少量内容,如果有需要,请阅读原文。本文来自 博客园 逖靖寒 http://gpcuster.cnblogs.com

 

译文:

本次的JoelOnSoftware 问答活动中,提到了一个古老的问题,什么是log以及如何去log。平常的trace/error/warning/info方式在大型的分布式系统中不是非常有用。你需要将所有的信息都记录下来才能解决遇到的问题。

为了解释为什么常用的log方式不好用,可以想象这样一种情形:你的网站运行了好几周时间都没有问题,可是突然有1天,凌晨2点的时候出现了一个问题,用户有时无法提交评论,这个现象时断时续。你现在需要去修复这个问题。

那么,我们如何去找到这个问题并修复它呢?监控系统并没有任何异常的现象,你自己提交一个评论去测试,运行正常,没有问题。看来这个问题不是那么好解决的,因为提交一个评论涉及了许多的东西,比如说:负载平衡系统,垃圾过滤,web服务器,数据库服务器,缓存服务器,文件服务器,还有交换机和路由器等等,究竟是什么地方出问题了呢?

这个时候,你所拥有的只有log。你不能关闭你的系统因为用户正在使用它,你不能更新部署一个新的系统因为你没有环境去测试新的系统是否会进入新的问题,添加debugger也无法解决这个问题。

你需要做的事情就是查看这些log,看看会其中记录了什么信息。你不需要函数或是方法的信息,你需要知道系统中所有有意思的事情发生的记录,知道这个叫“func1”的函数被调用没有任何帮助。你需要知道什么参数被传递给了函数,函数的返回值是什么。

所以,这里没有log的级别之分。你需要记录所有的信息来帮助你在将来遇到问题的时候解决问题。你真正需要的是一个时光机,虽然这是不现实的,但是主要我们的log足够详细,那么就可以认为我们拥有一个时光机。他将帮助你了解到期间发生的所有事情:是不是一个接口丢失了一个包数据,是不是相应超时了,是不是互斥锁没有正确使用?等等。

绝大多数系统都是慢慢发展到去记录所有的东西的。它们开始的时候只记录一点点信息甚至什么都不记录。当发生问题以后,它们会增加记录的内容。但是log通常没有很好的分类与整理,这将导致不好的问题覆盖率和降低程序的性能。

程序反常一般通过log来查找,反常就是一些没有预料到的东西,比如说操作,处理顺序,计算时间过长等等。不过这些反常的现象也有好处,它会告诉你如何让自己的程序更加健壮,让你知道如何在真实的环境中去处理相关的问题。

所以,好好想一下你需要调试哪些问题。不要害怕去添加log帮助你了解系统真正是如何工作的。

比如说,给每一个请求需要分配一个全局唯一的ID,这样你就区分不同请求的相关信息了,帮助你提供调试的效率和准确性。

通常log有2个等级:系统级别和开发级别。

系统级别的log会记录所有你需要去调试系统的日志,它将一直存在,不会被关闭。

开发级别的日志将添加更加详细的信息,并且可以以模块为单位开启或者是关闭。

我通常会用一个配置文件,里面定义了默认的输出级别。不过我让每一个进程通过相应的接口改变自己的输出级别。这样在开发的时候就会非常的方便。

我时常听到这样的言论:记录所有的信息效率非常低,会产生过多的数据。我不这么认为。我参加过一些项目,其中有的是实时的嵌入式系统,他们都会记录下所有的信息,甚至是驱动程序,他们都是这么做的。

下面有一些与log相关的技巧(感觉原文说得更加到位,就不翻译了):

  • Make logging efficient from the start so you aren't afraid to use it.
  • Create a dead simple to use log library that makes logging trivial for developers. Document it. Provide example code. Check for it during code reviews.
  • Log to a separate task and let the task push out log data when it can.
  • Use a preallocated buffer pool for log messages so memory allocation is just pop and push.
  • Log integer values for very time sensitive code.
  • For less time sensitive code sprintf'ing into a preallocated buffer is usually quite fast. When it's not you can use reference counted data structures and do the formatting in the logging thread.
  • Triggering a log message should take exactly one table lookup. Then the performance hit is minimal.
  • Don't do any formatting before it is determined the log is needed. This removes constant overhead for each log message.
  • Allow fancy stream based formatting so developers feel free to dump all the data they wish in any format they wish.
  • In an ISR context do not take locks or you'll introduce unbounded variable latency into the system.
  • Directly format data into fixed size buffers in the log message. This way there is no unavoidable overhead.
  • Make the log message directly queueable to the log task so queuing doesn't take more memory allocations. Memory allocation is a primary source of arbitrary latency and dead lock because of the locking. Avoid memory allocation in the log path.
  • Make the logging thread a lower priority so it won't starve the main application thread.
  • Store log messages in a circular queue to limit resource usage.
  • Write log messages to disk in big sequential blocks for efficiency.
  • Every object in your system should be dumpable to a log message. This makes logging trivial for developers.
  • Tie your logging system into your monitoring system so all the logging data from every process on every host winds its way to your centralized monitoring system. At the same time you can send all your SLA related metrics and other stats. This can all be collected in the back ground so it doesn't impact performance.
  • Add meta data throughout the request handling process that makes it easy to diagnose problems and alert on future potential problems.
  • Map software components to subsystems that are individually controllable, cross application trace levels aren't useful.
  • Add a command ports to processes that make it easy to set program behaviors at run-time and view important statistics and logging information.
  • Log information like task switch counts and times, queue depths and high and low watermarks, free memory, drop counts, mutex wait times, CPU usage, disk and network IO, and anything else that may give a full picture of how your software is behaving in the real world.
  • log的数据是你调试绝大多数大型分布式系统的根据。

    所以,从现在开始,记录所有的日志,当开始提到的那个凌晨2点钟的问题再次发生时,你就知道如何应对,修改问题了:)

     

    本文来自 博客园 逖靖寒 http://gpcuster.cnblogs.com

    posted on 2009-08-29 14:53  逖靖寒  阅读(2062)  评论(5编辑  收藏  举报