##################### C++ 快速实现开源日志系统-Log4cplus ########################
### 说 明 ###
由于网络上对 log4cplus讲解的文档并不多,而且或多或少都有些缺陷、疏漏或者错误。本文是根据
本人实践经验加上前人的指点而总结的,目的只是为了能对Log4cplus有个直观的了解。想要深入的了解需要查看更多相关文档。
### 简 介 ###
log4cplus是C++编写的开源的日志系统,前身是java编写的log4j系统.受Apache Software License保护。作者是Tad E. Smith。
log4cplus具有线程安全、灵活、以及多粒度控制的特点,通过将信息划分优先级使其可以面向程序调试、运行、测试、和维护等全生命周期;你可以选择将信息输出到屏幕、文件、NT event log、甚至是远程服务器;通过指定策略对日志进行定期备份等等。
### 下 载 ###
最新的log4cplus可以从以下网址下载 http://log4cplus.sourceforge.net 本文使用的版本为:log4cplus-1.0.4。
### 安 装 ###
1. linux下安装
tar xvzf log4cplus-x.x.x.tar.gz
cd log4cplus-x.x.x
./configure --prefix=/where/to/install
make
make install
这里假设采用缺省安装路径:/usr/local,下文如无特别说明,均以此路径为准。
2. windows下安装
有一个msvc存放包括源代码和用例在内的开发工程,如果使用VC++ 6可以对应的使用msvc6版本。如果使用VC8以上,可以使用msvc8中的版本。使用之前请先编译"log4cplus_dll class"工程生成dll,或者编译"log4cplus_static class"工程生成lib。
### 配 置 ###
1. linux下的配置
确保你的Makefile中包含 /usr/local/lib/liblog4cplus.a(静态库)或-llog4cplus(动态库)即可,
头文件在/usr/local/include/log4cplus目录下。对于动态库,要想正常使用,还得将库安装路径加入到LD_LIBRARY_PATH 中,我一般是这样做的:以管理员身份登录,在/etc/ld.so.conf中加入安装路径,这里是/usr/local/lib,然后执行ldconfig使设置生效即可。
2. windows下的配置
将"log4cplus_dll class"工程或"log4cplus_static class"工程的dsp 文件插入到你的工程中,或者直接把两个工程编译生成的库以及头文件所在目录放到你的工程的搜索路径中,如果使用静态库,需要在工程中"project/setting/C++"的preprocessor definitions中加入LOG4CPLUS_STATIC。除此之外,在运行实例程序的时候,常需要添加一个windows的网络库ws2_32.lib,如果不添加可能会报socket相关的错误。
### 构成要素介绍 ###
虽然功能强大,应该说log4cplus用起来还是比较复杂的,为了更好地使用它,先介绍一下它的基本要素。
Layouts :布局器,控制输出消息的格式.
Appenders :挂接器,与布局器紧密配合,将特定格式的消息输出到所挂接的设备终端
(如屏幕,文件等等)。
Logger :记录器,保存并跟踪对象日志信息变更的实体,当你需要对一个对象进行
记录时,就需要生成一个logger。
Categories :分类器,层次化(hierarchy)的结构,用于对被记录信息的分类,层次中
每一个节点维护一个logger的所有信息。
Priorities :优先权,包括TRACE, DEBUG, INFO, WARNING, ERROR, FATAL。
### 基本使用 ###
完整的使用log4cplus有六个基本步骤:
1. 实例化一个appender对象
2. 实例化一个layout对象
3. 将layout对象绑定(attach)到appender对象
4. 实例化一个logger对象,并且通过调用它的静态函数来实例化这个对象 log4cplus::Logger::getInstance("logger_name")
5. 将appender对象绑定(attach)到logger对象,如省略此步骤,标准输出(屏幕)appender 对象会绑定到logger
6. 设置logger的优先级,如省略此步骤,各种有限级的消息都将被记录
### 实例程序 ###
(所有程序均在VS2008EXPRESS下经过验证)
一、文件模式,appender输出到文件。
#include <log4cplus/logger.h>
#include <log4cplus/fileappender.h>
using namespace log4cplus;
int main()
{
/* step 1: Instantiate an appender object */
SharedAppenderPtr _append(new FileAppender("Test.log"));
_append->setName("file log test");
/* step 2: Instantiate a logger object */
Logger _logger = Logger::getInstance("test.subtestof_filelog");
/* step 3: Attach the appender object to the logger */
_logger.addAppender(_append); /* log activity */
int i; for( i = 0; i < 5; ++i )
{
LOG4CPLUS_DEBUG(_logger, "Entering loop #" << i << "End line #");
}
return 0;
}
运行结果:
工程中增加了一个Test.log文件,内容如下
DEBUG - Entering loop #0End line #
DEBUG - Entering loop #1End line #
DEBUG - Entering loop #2End line #
DEBUG - Entering loop #3End line #
DEBUG - Entering loop #4End line #
二、简洁使用模式,appender输出到屏幕。
#include <log4cplus/logger.h>
#include <log4cplus/consoleappender.h>
using namespace log4cplus;
using namespace log4cplus::helpers;
int aain(){
/* step 1: Instantiate an appender object */
SharedAppenderPtr _append(new ConsoleAppender());
_append->setName("append test");
/* step 2: Instantiate a logger object */
Logger _logger = Logger::getInstance("test");
/* step 3: Attach the appender object to the logger */
_logger.addAppender(_append);
/* log activity */
LOG4CPLUS_DEBUG(_logger, "This is the FIRST log message...");
sleep(1);
LOG4CPLUS_WARN(_logger, "This is the SECOND log message...");
return 0;
}
运行结果:
DEBUG - This is the FIRST log message...
WARN - This is the SECOND log message...
三、实现相隔一秒的日志格式化输出
#include <log4cplus/logger.h>
#include <log4cplus/consoleappender.h>
#include <log4cplus/layout.h>
using namespace log4cplus;
using namespace log4cplus::helpers;
int main(){
/* step 1: Instantiate an appender object */
log4cplus::SharedAppenderPtr _append (new ConsoleAppender());
_append->setName("append for test");
/* step 2: Instantiate a layout object */
std::string pattern = "%d{%m/%d/%y %H:%M:%S} - %m [%l]%n";
std::auto_ptr<log4cplus::Layout> _layout(new PatternLayout(pattern));
/* step 3: Attach the layout object to the appender */
_append->setLayout( _layout );
/* step 4: Instantiate a logger object */
Logger _logger = Logger::getInstance("test");
/* step 5: Attach the appender object to the logger */
_logger.addAppender(_append);
/* step 6: Set a priority for the logger */
_logger.setLogLevel(ALL_LOG_LEVEL);
/* log activity */
LOG4CPLUS_DEBUG(_logger, "This is the FIRST log message...");
sleep(1);
LOG4CPLUS_WARN(_logger, "This is the SECOND log message...");
return 0;
}
运行结果:
08/10/09 14:56:23 - This is the FIRST log message... [test2.cpp:31]
08/10/09 14:56:24 - This is the SECOND log message... [test2.cpp:33]