设计log函数库的几个要点

只要留意一下大项目的源码,你会发现,几乎无一例外的包括一个log模块。它的功能很直观:记录一些程序运行时信息,多数情况是用来辅助debug的。大项目都有一套的log的函数,在它的基础上开发,调用它提供的Log函数就行了,比如linux内核、apache等。也有开源log函数库,可以直接拿过用。这里,我们并不鼓励重新发明轮子,但在少数情况下,确实不得不编写自己的log函数。下面是对以前的经验的总结,和大家交流一下。

 

1.        按重要程度过滤log。在调试程序时,当然希望有较多的调试信息,能够为我们分析提供帮助,但使用太多Log是有代价的,它不但要占用空间,还要占用运行时间。我们不希望在Release版本中有太多的Log信息,那会浪费用户的资源。通常的做法是,把Log信息按重要程度分成不同的种类,在不同的情况下,打印不同种类的信息。错误的种类,一般分为严重错误、错误、警告、调试等几个级别。

 

2.        按模块过滤Log。对于大的项目的,可能由数十个甚至上百个模块组成。完成一个复杂的任务,需要在不同模块间切换好几次,得到的Log信息比较庞杂。多数情况下,我们的注意力,都放在几个容易出错的焦点模块上,Log信息太杂,要找出焦点模块中的Log会比较累,输出无用的Log也会增加系统的开销。这时,我们可以按模块过滤,只留下所关注模块的Log。可以设置一个过滤掩码(mask),这个模块占用一位,置1的模块表示打Log开关。

 

3.        Log的格式。Log的格式最好能够统一起来,让人感觉比较舒服,查看时也有个好的心情。同时最好能与调试器配合起来,比如,在VC中,若按文件名(行号):信息的格式输出,双击该信息,VC自动跳到打印该Log的代码位置。

 

4.        Log的内容。Log的内容并不无固定规则,一般来说,Log提供下列信息,对调试会有一些帮助:

a)        模块名。

b)       打印该Log的位置,如文件名、行号、函数名等。

c)       打印该Log的时间。

d)       对由多个模块组成的项目,若这些模块又并不同步发布时,版本不匹配会引发一些问题,这就有必要打印出各模块的build时间或者版本信息。

 

5.        能重定向log的内容。常见的做法是把log信息打印到屏幕上,这也不尽然,特别对于非PC平台的情况,有的输出到串口,有的保存到文件,有的输出到socket,输出的目标多种多样。所以,在设计一个通用的log函数库时,最好考虑到这些需求,抽象出一套输出接口是较为理想的做法。

 

6.        动态配置Log。若每次配置Log的规则,都要重新编译程序,这常常是不能接受的。在设计时要考虑提供动态配置功能。动态配置的方法有多种,可以通过命令行参数,可以通过环境变量,可以通过配置文件,也可以提供一个设置界面,这要根据具体的情况而定。配置的内容常常包括:过滤级别、模块掩码、输出格式和输出目标等。

 

7.        常用的宏。在C语言中,有几个宏,可能对于编写Log函数库有用处:

 

a)        __FILE__ 当前文件名。

b)       __LINE__ 当前行号。

c)       __func__ 当前函数,好像新标准才支持。

d)       __DATE__ 编译日期。

e)        __TIME__ 编译时间。

 

8.        参数可变。一般来说,Log函数的参数都是可以变化的,这很容易实现,C语言支持参数个数可变的函数。有时,为了方便,会定义一些宏包装一下Log函数,可往往不太走运,因为C语言新标准里才支持参数可变的宏,目前常用的gcc版本都支持,而VC这个冤大头却不支持。若非要使用变参宏,一定要考虑可以移植性问题。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值