技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 系统运维 --> 警惕程序日志对性能的影响

警惕程序日志对性能的影响

浏览:2952次  出处信息

    做后台系统比做客户端软件的辛苦的地方,就是不能让程序轻易地挂掉。因为在生产环境中无法容易地复现或调试 bug,很多时候需要程序日志提供足够的信息,所以一个后台系统的程序员必须要明白该如何打日志(logging)。

    很多语言都有自己现成的 logging 库,比如 Python 标准库中的 logging 模块,Apache 的 log4cxx(C++), log4j(Java)。如果你愿意找,很容易能找到基本满足自己需求的日志程序库。当然,自己实现一个也不是很困难。难点不在于写这些库,而是如何去使用它们。

    大部分情况下,我们关注的都是日志的级别和内容。即哪些情况下,该打哪个级别的日志,日志语句中,该怎么写。

    在程序开发的过程中,我们需要很多的日志协助分析程序问题;但在生产环境中,我们没有那么多的空间存储丰富的日志,而且日志量太大对于问题排查反而是累赘。有些人使用预处理解决这个问题,在 debug 版本和 release 版本中编译进不同的日志语句。这样能够解决一些问题,但却使得在生产环境中无法轻易地打印更多的日志。大部分人更接受的做法是,使用配置(参数)控制日志的打印级别,在需要更多日志的时候,可以随时打开它们。为了实现日志“少但是足够”的目标,开发人员必须明白日志信息的价值,即哪些日志应该属于哪个级别。

    日志的作用是提供信息,但不同的日志语句,提供的信息量却是不一样的。有的日志里会写“Failed to get sth..”,但却忘记加上失败调用的返回值。同程序一样,日志语句中有的是变量(某个变量内容),有的是常量(提示信息)。常量你总能从程序源代码中获得,但变量不行。所以在一条日志中,信息量最大的是变量,是函数返回值/字符串内容/错误码,因而变量应该尽量放在靠前的位置。常量也不是一点价值没有,写得好的提示语句,会使问题一目了然,可以免去你到代码中 grep,然后重读代码的麻烦。

    上面这两点,几乎所有知道 logging 重要性的同学都会了解。但关于 logging 对性能的影响,很多人没有足够的警惕心。例如有人会在一个按行解析文件的函数中写下这样的日志:

int parseline(...)
{
log_trace("Enter parseline with ...");
DO_SOMETHING;
log_trace("Exit parseline with ...");
return 0;
}

    乍一看,由于 log_trace 级别不高,在生产环境中肯定会关闭,那么这样做看起来对性能没太大影响。但实际上 log_trace 可能是这样实现的:

#define log_trace(fmt, arg...) \\
    xx_log(LVL_TRACE, "[%s:%d][time:%uus]" fmt, __FILE__, __LINE__,\\
           log_getussecond(), ## arg)
#endif

    可以看到 log_trace 宏中自动添加了很多信息,值得注意的是时间参数 log_getussecond()。大家都知道统计时间需要系统调用,那么无论 log_getussecond() 函数是如何实现的,它的代价肯定是高于一般的简单函数。

    我们本以为 log_trace 在 LVL_TRACE 级别被关闭的情况下,消耗的代价仅仅是一个函数调用和分支判断,却没有发现宏参数中还隐藏着一个需要调用系统调用的函数。当文件不大是还算能够忍受,但当这个文件是一个数据库,扫描每一行都要执行两次 log_trace() 时,它对系统性能的影响就绝不可忽视了。

    所以,最佳的做法还是,在性能攸关的代码中,使用可被预处理掉的 logging 语句,仅仅在 debug 发布中才能见到这些日志,release 版本中不把它们编译进来。

    此外,上面这个 log_trace,是一个糟糕的设计。logging 模块只应该干 logging 的事情,开发人员需要时间统计时会自己完成。

建议继续学习:

  1. Xvfb+YSlow+ShowSlow搭建前端性能测试框架    (阅读:53981)
  2. 30分钟3300%性能提升――python+memcached网页优化小记    (阅读:11864)
  3. server日志的路径分析    (阅读:9910)
  4. AWStats简介:Apache/Windows IIS的日志分析工具的下载,安装,配置样例和使用(含6.9中文定义补丁)    (阅读:8639)
  5. 利用脚本分析日志并利用snmp自定义OID,再通过cacti画图    (阅读:8550)
  6. tomcat catalina.out日志切割每天生成一个文件    (阅读:7955)
  7. 分布式日志系统scribe使用手记    (阅读:7885)
  8. 长连接(KeepAlive)在 http 连接中的性能影响    (阅读:6848)
  9. SQL vs NoSQL:数据库并发写入性能比拼    (阅读:6467)
  10. 服务器性能测试工具推荐    (阅读:6186)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1