转载地址1:http://blog.csdn.net/dds_dev_group/article/details/6973847
转载地址2:http://blog.csdn.net/guang11cheng/article/details/7400134
转载地址3:http://www.cppblog.com/API/archive/2011/04/02/143281.html
一、log4cplus server client模式
在多进程使用log4cplus同时向一个日志文件写的时候,官方的FAQ建议使用SoskcetAppender, 即以server client模式来写日志,保证写日志同步。
写了一个小程序,fork出一个server进程,和5个client进程来写日志,当日志大小到达4G的时候做切割。
1,向文件中输出日志
#include
*/
// urconfig.properties文件
log4cplus.logger.filelogger=TRACE, append_1
log4cplus.appender.append_1=log4cplus::DailyRollingFileAppender
log4cplus.appender.append_1.Schedule=MINUTELY
log4cplus.appender.append_1.File=./log/test.log #目录要手动创建!
#log4cplus.appender.append_1.MaxFileSize=512000 #无效果
#log4cplus.appender.append_1.MaxBackupIndex=5 #貌似也无效果
log4cplus.appender.append_1.layout=log4cplus::PatternLayout
log4cplus.appender.append_1.layout.ConversionPattern=[%D{%Y-%m-%d %H:%M:%S %q}] [%-5p] <%l %M> %m%n
2,性能数据:
void performanceTest()
{
#define LOOP_COUNT 100000
PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("log4cplus.properties"));
Logger root = Logger::getRoot();
Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("testlogger"));
LOG4CPLUS_WARN(Logger::getRoot (), "Starting test loop....");
Time start = Time::gettimeofday();
tstring msg(LOG4CPLUS_TEXT("This is a WARNING..."));
int i = 0;
for (i = 0; i < LOOP_COUNT; ++i)
{
LOG4CPLUS_WARN(logger, msg);
}
Time end = Time::gettimeofday();
Time diff = end - start;
LOG4CPLUS_WARN(LOG4CPLUS_TEXT("root"), "Logging " << LOOP_COUNT << " took: " << diff);
LOG4CPLUS_WARN(root, "Logging average: " << (diff / LOOP_COUNT));
}
#log4cplus.properties配置文件
log4cplus.rootLogger=TRACE, STDOUT
log4cplus.logger.testlogger=TRACE, TEST
log4cplus.additivity.testlogger=FALSE
log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
log4cplus.appender.STDOUT.layout.ConversionPattern=%d{%m/%d/%y %H:%M:%S} [%t] %-5p %c - %m %n
log4cplus.appender.TEST=log4cplus::FileAppender
log4cplus.appender.TEST.File=test_output.log
log4cplus.appender.TEST.layout=log4cplus::PatternLayout
log4cplus.appender.TEST.layout.ConversionPattern=%d{%y-%m-%d %H:%M:%S,%q} [%t] %-5p %c <%x> - %m%n
// 程序输出
03/28/12 01:58:35 [3078437120] WARN root - Starting test loop....
03/28/12 01:58:38 [3078437120] WARN root - Logging 100000 took: 2sec 459840usec
03/28/12 01:58:38 [3078437120] WARN root - Logging average: 0sec 24usec -- 向文件中打印每条日志平均需要24微妙
test_output.log日志文件的内容:
12-03-28 01:57:29,677 [3078301952] WARN testlogger <> - This is a WARNING...
三、log4cplus库(三)(将日志写入到文件)
一.如何将日志写入到文件
将log信息记录到文件应该说是日志系统的一个基本功能,log4cplus在此基础上,提供了更多的功能,
可以按照你预先设定的大小来决定是否转储,当超过该大小,后续log信息会另存到新文件中,
依次类推;或者按照日期来决定是否转储。log4cplus提供了三个类用于文件操作,它们是:
FileAppender类、RollingFileAppender类、DailyRollingFileAppender类
二.FileAppender类
实现了基本的文件操作功能,构造函数如下:
FileAppender(const log4cplus::tstring& filename,
LOG4CPLUS_OPEN_MODE_TYPE mode = LOG4CPLUS_FSTREAM_NAMESPACE::ios::trunc,
bool immediateFlush = true);
filename: 文件名
mode : 文件类型,可选择的文件类型包括app、ate、binary、in、out、trunc,
因为实际上只是对stl的一个简单包装,缺省是trunc,表示将先前文件删除。
immediateFlush :缓冲刷新标志,如果为true表示每向文件写一条记录就刷新一次缓存,
否则直到FileAppender被关闭或文件缓存已满才更新文件,一般是要设置true的,
比如你往文件写的过程中出现了错误(如程序非正常退出),即使文件没有正常关闭也可以保证程序终
止时刻之前的所有记录都会被正常保存。
三. RollingFileAppender类
构造函数如下:
log4cplus::RollingFileAppender::RollingFileAppender(
const log4cplus::tstring& filename,
long maxFileSize,
int maxBackupIndex,
bool immediateFlush)
filename : 文件名
maxFileSize : 文件的最大尺寸
maxBackupIndex : 最大记录文件数
immediateFlush : 缓冲刷新标志
RollingFileAppender类可以根据你预先设定的大小来决定是否转储,当超过该大小,后续log信息会另存到新文件中,
除了定义每个记录文件的大小之外,你还要确定在RollingFileAppender类对象构造时最多需要多少个这样的记录文件
(maxBackupIndex+1),当存储的文件数目超过maxBackupIndex+1时,会删除最早生成的文件,保证整个文件数目等于
maxBackupIndex+1。然后继续记录,比如以下代码片段:
运行结果:运行后会产生6个输出文件,Test.log、Test.log.1、Test.log.2、Test.log.3、Test.log.4、Test.log.5
其中Test.log存放着最新写入的信息,而最后一个文件中并不包含第一个写入信息,说明已经被不断更新了。
需要指出的是,这里除了Test.log之外,每个文件的大小都是200K,而不是我们想像中的5K,
这是因为log4cplus中隐含定义了文件的最小尺寸是200K,只有大于200K的设置才生效,<= 200k的设置都会被认为是200K.
四. DailyRollingFileAppender类
构造函数如下:
DailyRollingFileAppender::DailyRollingFileAppender(const log4cplus::tstring& filename,
DailyRollingFileSchedule schedule,
bool immediateFlush,
int maxBackupIndex)
filename : 文件名
schedule : 存储频度
immediateFlush : 缓冲刷新标志
maxBackupIndex : 最大记录文件数
DailyRollingFileAppender类可以根据你预先设定的频度来决定是否转储,当超过该频度,
后续log信息会另存到新文件中,这里的频度包括:
MONTHLY(每月)、WEEKLY(每周)、DAILY(每日)、TWICE_DAILY(每两天)、HOURLY(每时)、MINUTELY(每分)。
maxBackupIndex的含义同上所述,比如以下代码片段:
运行结果:运行后会以分钟为单位,分别生成名为
Test.log.2004-10-17-03-03、Test.log.2004-10-17-03-04和Test.log.2004-10-17-03-05这样的文件。
需要指出的是,刚看到按照频度(如HOURLY、MINUTELY)转储这样的概念,以为log4cplus提供了内部定
时器,感觉很奇怪,因为日志系统不应该主动记录,而loging事件总是应该被动触发的啊。仔细看了源
代码后才知道这里的"频度"并不是你写入文件的速度,其实是否转储的标准并不依赖你写入文件的速度,
而是依赖于写入的那一时刻是否满足了频度条件,即是否超过了以分钟、小时、周、月为单位的时间刻度,
如果超过了就另存。本部分详细介绍log信息的几种文件操作方式,下面将重点介绍一下如何有选择地控
制log信息的输出。