笔者认为Appender是log4cpp中最精彩的一个部分。我仔细阅读了大部分Appender的源代码并对设计者感到非常敬仰。
Log4cpp中所有可直接使用的Appender列表如下:
log4cpp::IdsaAppender // 发送到IDS或者
log4cpp::FileAppender // 输出到文件
log4cpp::RollingFileAppender // 输出到回卷文件,即当文件到达某个大小后回卷
log4cpp::OstreamAppender // 输出到一个ostream类
log4cpp::RemoteSyslogAppender // 输出到远程syslog服务器
log4cpp::StringQueueAppender // 内存队列
log4cpp::SyslogAppender // 本地syslog
log4cpp::Win32DebugAppender // 发送到缺省系统调试器
log4cpp::NTEventLogAppender // 发送到win 事件日志
|
其中SyslogAppender和RemoteSyslogAppender需要与Syslog配合使用,因此这里不介绍。顺便提一句,Syslog是 类Unix系统的一个核心服务,用来提供日志服务,在Windows系统中并没有直接提供支持,当然可以用相关工具提供Windows系统中的 syslog服务。IdsaAppender的功能是将日志写入Idsa服务
(1)OstreamAppender
在我刚刚学习C/C++编程时,一位老师告诉我,如果没有好用的调试工具,就在代码中加入printf语句,将调试信息打印出来(当时在linux下面,确实没有什么易用的c++调试工具)。现在有了OstreamAppender,一切都好办了,它可以将日志记入一个流,如果该流恰好是cout,则会在标准控制台上输出。比 printf优越的是,除了输出消息外,还可以轻松的输出时间、时钟数、优先级等大量有用信息。
OstreamAppender的使用非常简单,在前面的HelloWorld程序中已经见过,创建一个OstreamAppender的具体方法如下:
log4cpp::OstreamAppender* osAppender = new log4cpp::OstreamAppender("osAppender", &cout); //第一个参数指定OstreamAppender的名称,第二个参数指定它关联的流的指针。 |
(2) FileAppender和RollingFileAppender
FileAppender和RollingFileAppender是log4cpp中最常用的两个Appender,其功能是将日志写入文件中。它们之间唯一的区别就是前者会一直在文件中记录日志(直到操作系统承受不了为止),而后者会在文件长度到达指定值时循环记录日志,文件长度不会超过指定值(默认的指定值是10M byte)。
FileAppender的创建函数如下:
FileAppender(const std::string& name, const std::string& fileName, bool append = true, mode_t mode = 00644);
|
******* 一般仅使用前两个参数,即“名称”和“日志文件名”。第三个参数指示是否在日志文件后继续记入日志,还是清空原日志文件再记录。第四个参数说明文件的打开方式。
RollingFileAppender的创建函数如下:
RollingFileAppender(const std::string& name,
const std::string& fileName,
size_t maxFileSize = 10*1024*1024,
unsigned int maxBackupIndex = 1,
bool append = true,
mode_t mode = 00644);
|
它与FileAppender的创建函数很类似,但是多了两个参数:maxFileSize指出了回滚文件的最大值;maxBackupIndex指出了回滚文件所用的备份文件的最大个数。所谓备份文件,是用来保存回滚文件中因为空间不足未能记录的日志,备份文件的大小仅比回滚文件的最大值大1kb。所 以如果maxBackupIndex取值为3,则回滚文件(假设其名称是rollwxb.log,大小为100kb)会有三个备份文件,其名称分别是 rollwxb.log.1,rollwxb.log.2和rollwxb.log.3,大小为101kb。另外要注意:如果 maxBackupIndex取值为0或者小于0,则回滚文件功能会失效,其表现如同FileAppender一样,不会有大小的限制。这也许是一个 bug.
#include <iostream>
#include<sstream>
#include<log4cpp/Category.hh>
#include<log4cpp/PatternLayout.hh>
#include<log4cpp/FileAppender.hh>
#include<log4cpp/RollingFileAppender.hh>
#include<log4cpp/Priority.hh>
using namespace std;
using namespace log4cpp;
int main()
{
//Layout与Appender是一对一的关系
//Category与Appender是一对多的关系, 可以同时往两个Appender指定的文件写东西
//设置日志格式
PatternLayout * ptnLy1=new PatternLayout();
ptnLy1->setConversionPattern("%d: %p %c %x:%m%n");
PatternLayout * ptnLy2=new PatternLayout();
ptnLy2->setConversionPattern("%d: %p %c %x:%m%n");
//设置日志输出目的地
FileAppender *pFileAppender=new FileAppender("fileAppender","mylog.log");
pFileAppender->setLayout(ptnLy1);
//设置日志输出目的地,回滚文件大小,备份数量
RollingFileAppender *pRollFileAppender=new RollingFileAppender("rollingFileAppender", "mylogrolling.log", 5*1024, 1);
pRollFileAppender->setLayout(ptnLy2);
//设置输出日志
Category & root=Category::getRoot().getInstance("rootCat");
root.addAppender(pFileAppender);
root.addAppender(pRollFileAppender);
root.setPriority(Priority::DEBUG);
//写日志
for(int idx=0;idx!=100;++idx)
{
ostringstream oss;
oss<<idx<<":Root Error Message!";
root.error(oss.str());
}
//关闭Category
Category::shutdown();
return 0;
}
|
#include<iostream>
#include<string>
#include<sstream>
#include<log4cpp/Category.hh>
#include<log4cpp/Appender.hh>
#include<log4cpp/FileAppender.hh>
#include<log4cpp/RollingFileAppender.hh>
#include<log4cpp/PatternLayout.hh>
#include<log4cpp/Priority.hh>
using namespace std;
using namespace log4cpp;
int main(int argc,char **argv)
{
//Layout与Appender是一对一的关系
//Category与Appender是一对多的关系, 可以同时往两个Appender指定的文件写东西
//设置日志的输出目的地,这里是两种不同的输出到文件的方式;
FileAppender* fileAppender = new FileAppender("fileAppender","mylog.log");
RollingFileAppender* rollingfileAppender = new RollingFileAppender(
//设置输出目的地,回滚文件大小,备份数量
"rollingfileAppender","mylogrolling.log",5*1024,1);
//设置日志格式
PatternLayout* pLayout1 = new PatternLayout();
PatternLayout* pLayout2 = new PatternLayout();
pLayout1->setConversionPattern("%d: %p %c %x: %m%n");
pLayout2->setConversionPattern("%d: %p %c %x: %m%n");
fileAppender->setLayout(pLayout1);
rollingfileAppender->setLayout(pLayout2);
//设置输出日志
Category& root = Category::getRoot().getInstance("RootName");
root.addAppender(fileAppender);
root.addAppender(rollingfileAppender);
//写日志
for(int i=0;i<100;i++)
{
string strError;
ostringstream oss;
oss<<i<<":Root Error Message!";
strError = oss.str();
root.error(strError);
}
//关闭日志
Category::shutdown();
return 0;
}
|
程序运行后会产生三个日志文件mylog.log和mylogrolling.log,以及一个备份文件mylogrolling.log.1。mylog.log的大小为6kb,记录了所有100条日志;mylogrolling.log大小为1kb,记录了最新的21条日志;mylogrolling.log.1大小为5kb,记录了旧的79条日志(这就是回卷文件)。
//mylog.log |
//mylogrolling.log.1 |