在VS10中使用log4cpp

用printf打印程序运行日志, 输出到控制台, 一个大问题是cmd最大接受行数是9999行, 如果一次性输出大量的消息, 一部分消息无法看到, 因为被截断了. 当然可以将输出定向到文件, 不过自己实现的话太麻烦. 用Log4cpp的话就非常简单了, 只要修改appender就可以重定向输出. 下面介绍如何在VS10项目中使用Log4cpp.

可以选择sourcefoge或者github下载项目, 我喜欢git.

 
git clone https://github.com/jsternberg/log4cpp.git
 

首先用VS10构建log4cpp, 生成log4cppd.lib文件. 项目只提供了MSVC7的项目文件, 用VS10打开, 进行转换, 转换之后需要进行一点修改才能正常编译. 用记事本打开log4cppLIB.vcxproj. 找到Debug with boost下的Command标签. 修改为.

 
      <Command Condition="'$(Configuration)|$(Platform)'=='Debug with Boost|Win32'">if not exist "$(OutDir)" md "$(OutDir)"
mc.exe -h "$(ProjectDir)$(OutDir)." -r "$(ProjectDir)$(OutDir)." "$(ProjectDir)..\%(Filename).mc"
RC.exe -r -fo "$(OutDir)%(Filename).res" "$(OutDir)%(Filename).rc"
link.exe /MACHINE:IX86 -dll -noentry -out:"$(OutDir)NTEventLogAppender.dll" "$(OutDir)%(Filename).res"
</Command>
 

这三个命令工具对带有空格的路径都不能很好的支持, 所以加上双引号.

第二个要修改的是PatternLayout.cpp. append函数使用了localtime, 使用的时候会造成麻烦, 将其改为

 
            //localtime(&t, &currentTime);
            localtime_s(&currentTime,&t );
 

然后构建项目log4cppLIB.

现在转到要使用log4cpp的项目, 添加include目录和库目录.

 
包含目录:
F:\My Documents\Visual Studio 2005\Projects\log4cpp-master\include;
 
附加依赖项:
"F:\My Documents\Visual Studio 2005\Projects\log4cpp-master\msvc7\log4cppLIB\Debug\log4cppD.lib";
 

声明一个全局log4cpp::Category对象的指针, 然后再初始化序列中构建实例.

 
// log4cpp
 
#include "log4cpp/Portability.hh"
#ifdef LOG4CPP_HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <iostream>
#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/OstreamAppender.hh"
#ifdef LOG4CPP_HAVE_SYSLOG
#include "log4cpp/SyslogAppender.hh"
#endif
#include "log4cpp/Layout.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/PatternLayout.hh"
#include "log4cpp/SimpleLayout.hh"
#include "log4cpp/Priority.hh"
#include "log4cpp/NDC.hh"
log4cpp::Category * root = NULL;
#define printf root->debug
 

如果项目中已经大量使用了printf, #define宏将其全部替换为root->debug调用.

初始化代码:

 
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
 
    log4cpp::OstreamAppender* osAppender = new log4cpp::OstreamAppender("osAppender", &cout);
    osAppender->setLayout(new log4cpp::BasicLayout());
 
    log4cpp::Category & root1 = log4cpp::Category::getRoot();
    root = &root1;
 
    log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "program.log");
 
    log4cpp::PatternLayout * layout = new log4cpp::PatternLayout();
    layout->setConversionPattern("%m");
    appender2->setLayout(layout);
 
 
    root->addAppender(appender2);
    root->setPriority(log4cpp::Priority::DEBUG);
 
    root->error("Hello log4cpp in a Error Message!");
    root->warn("Hello log4cpp in a Warning Message!");
    root->debug("This is a debug message");
    root->debug("this is %s, %d\n", "haha", 3);
 
 
    // ... 其他代码
 
    log4cpp::Category::shutdown();
    return 0;
 
}
 

如果你的项目是将警告视为错误, 可能要禁用, 因为log4cpp的编译时没有将警告视为错误的, 而VS10编译器比较严格, log4cpp的代码并不完全符合VS10的编译要求.