随笔-90  评论-947  文章-0  trackbacks-0

我原先不喜欢加 Log,后来我的头儿希望加 Log,于是乎我手头的项目就全是 Log 了。之前一直是定义一个不定参数的宏或者函数,遇到需要的地方就 LOG(...)。后来越来越感觉对于函数进出的信息比较渴求,于是弄了个固定的 LOG_FUNCTION() 来记录函数进入,因为有 __FUNCTION__ 嘛。

对于函数出口,原先一直是手写的,刚刚前几天在这里讨论的资源释放问题让我学到了新的解决方法——使用类似 Loki::ScopeGuard 的机制来输出函数退出。

晚上重新写了一下。见 http://code.google.com/p/xllog/

使用如下:

void bar()
{
   
XL_LOG_FUNCTION();
   
XL_LOG(L"%s\n", L"In function bar.");
}

void foo()
{
   
XL_LOG_FUNCTION();
   
XL_LOG(L"%s\n", L"In function foo.");

   
bar();
}

int main()
{
   
XL_LOG_FUNCTION();

   
foo();

   
return 0;
}

运行结果:

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Enter Function main
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Enter Function foo
In function foo.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Enter Function bar
In function bar.
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Leave Function bar
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Leave Function foo
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Leave Function main

基本功能我自己已经可以接受了。

有两点我想改进的,不知道能不能实现:

1、每个用到的函数写一句 XL_LOG_FUNCTION() 太麻烦了,而且有可能被用户写到任意地方,而非函数开始。有没有一种机制,使得可以写成类似(要保持函数定义的形式,不要把函数名括号括起来):

void __log foo()
{
}

从而被展开成:

void foo()
{
    XL_LOG_FUNCTION();
}

呢?

或者有没有一种方法可以不用写任何东西就让每个函数体自动加上这么一句呢?

2、我想记录函数的调用层次。如果上面行能够实现的话,就没问题了,我可以自己记录函数进出次数。如果不能,那么依靠用户写 XL_LOG_FUNCTION() 来记录就不可靠了。有没有类似 __CALL_STACK_DEPTH__ 的预定义宏呢?

最后还有一个实际问题。实际使用中,在写代码的时候可能无法确定所写部位到底是偏底层还是偏上层。如果太偏底层而打了 Log,会输出很多 Log 干扰分析;如果太高层的而没打 Log,有可能遇到问题信息不足。这个问题该如何解决好呢?大家有没有成熟的解决思路呢?

posted on 2010-04-04 01:31 溪流 阅读(2315) 评论(14)  编辑 收藏 引用 所属分类: C++

评论:
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-04 02:44 | OwnWaterloo
msvc和gcc都有相应的分析工具。
VS的IDE中有个性能分析工具, 具体是怎么让cl去完成的不了解。
而gcc相应的工具是gprof和gcov。 gprof是使用-pg选项,给每个函数添加hook代码(它是编译器,当然知道如何添加。。。)
gcov的选项有点复杂…… 好像是-ftest-coverge什么的。

只要截获每次函数调用, 除非是搞什么longjmp或者exit, 调用树运行时间等东西都可以得到。

当然, 这不太像log了…… 不过看你的描述, 你需要的功能也不是log了……
就是程序动态分析工具。
  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-04 09:42 | 溪流
@OwnWaterloo
我需要的的确是 Log。会有很多类似 XL_LOG(L"%s\n", L"Message."); 的东西,我想搞清楚哪些东西是在哪些函数里输出的。  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-04 13:32 | wuqq
1.你说的第一个问题,就是打印堆栈嘛,linux下用backtrace,windows 下用WalkStack
2.第二个问题,log信息加上一个优先级,LOG_ERR, LOG_WARNING, LOG_DEBUG 等等  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-04 16:32 | 空明流转
第一个问题:不太可能。除非你有相应的预处理工具。当然,打印堆栈是可以的,楼上也给出了一个相应的解决方案。只不过打印堆栈在Release模式下不一定有效,因为编译器往往会给予代码以一定的优化,使得其作用路径未必与源代码一致。
第二个问题:一般而言,Log是需要分等级的。常见的分级方案包括:
FATAL, ERROR, WARNING, INFORMATION, VERBOSE若干类。等级划分可以是编译器的,可以是运行期的。如果需要,LOG可以组织成继承的结构,可以让下一级的LOG继承上一级的等级,从而实现比较复杂的逻辑。同时还可以开发相应的日志浏览和分析工具,有筛选的进行日志统计、分析、审计等更加复杂的功能。当然,这一切都需要根据需求来定。  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-06 10:53 | 陈梓瀚(vczh)
怎么打log是没什么方便的做法了,但是log太多的干扰大可不必担心。你写一个小程序把你的log转成csv文件,然后用Excel去搞定分析就行了。  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-06 10:56 | 陈梓瀚(vczh)
预处理的话,你可以再写一个小程序,把工程文件和代码文件全部复制到一个新的文件夹,用正则表达式分析所有的代码,然后为他们打XL_LOG_FUNCTION(),最后调用cl.exe编译他们(这一步可以不用做得那么好,在Visual C++里面可以看到编译选项,抄就行了)  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-06 10:56 | 陈梓瀚(vczh)
写这种程序不仅可以解决问题还能锻炼自己,一石二鸟也  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-06 13:08 | 欣萌
我如果需要这个功能,我会直接调试。看堆栈  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-06 14:41 | 溪流
@陈梓瀚(vczh)
这构想挺好,有点写了一部分C++编译前端的感觉。。。不过公司里的项目,我还是不想把编译过程复杂化,要是让头儿郁闷了我可就完了。以后在自己个人的东西上玩哈  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-06 14:43 | 溪流
@欣萌
开发过程中当然可以调试,可是有很多场合不好调试,比如internal release的东西被测到奇怪的现象。。。即使开发过程中,也有不是很方便调试(不是说不可以)的东西,比如NTService  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-06 16:18 | but
这应该是面向切面的编程吧,对c++程序员来说是不可想象的,但是java,c#这些语言可以实现,  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-06 17:44 | hawk
第一个问题aspectc应该可以帮助实现,也是ls说的面向切面编程~  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-09 02:58 | 欲三更
自动加一句日志指令?这个很难想象。。。倒是可以用宏实现。  回复  更多评论
  
# re: 想弄个 Log 类,要能方便地记录函数进出,并且有机制处理 Log 的繁简 2010-04-09 02:59 | 欲三更
第二个问题嘛,通用的解决方案是“优先级”  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理