log4cxx中DailyRollingFileAppender模式增加类似MaxBackupIndex属性的功能(C++)

log4cxx的RollingFileAppender模式可以设置MaxBackupIndex属性,来限制日志文件的数量,但是,DailyRollingFileAppender模式没有这个属性,无法限制日志文件数量,使用很不方便。所以我给DailyRollingFileAppender增加了一个属性MaxBackupDays,这个属性表示最多可以保留最近多长一段时间的日志,比如最多保留最近3天的日志,超过3天的日志自动删除。

实现的主要思想是,当log4cxx在rollover时,搜索日志目录下的所有日志文件,如果日志文件的修改时间和当前时间之差超过MaxBackupDays天数,则删除该日志文件。搜索的关键字是File属性中的文件名,因此使用者必须保证这个文件名被所有日志文件所包含,并且其他文件不能包含这个文件名。

实现的关键函数是deleteOldFiles,修改的代码如下所示,最后还有一个.properties配置文件:

-- timebasedrollingpolicy.h --

        class LOG4CXX_EXPORT TimeBasedRollingPolicy : public RollingPolicyBase,
             public TriggeringPolicy {
             ...
         private:
						//日志最大保存天数
						int maxBackupDays; //add by pengliqing
				
						//add by pengliqing
						void deleteOldFiles(const LogString& currentActiveFile);
						LogString extractFileDir(const LogString& In);
						LogString extractFileName(const LogString& In);
						...
         public:
					  //add by pengliqing
					  void setMaxBackupDays(int newVal);
					  ...
				};

-- timebasedrollingpolicy.cpp --

TimeBasedRollingPolicy::TimeBasedRollingPolicy() 
: maxBackupDays(0)
{
}

RolloverDescriptionPtr TimeBasedRollingPolicy::rollover(
   const LogString& currentActiveFile,
   Pool& pool) {
	...
  //
  //  if file names haven't changed, no rollover
  //
  if (newFileName == lastFileName) {
    RolloverDescriptionPtr desc;
    return desc;
  }

  //只保存最近MaxBackupIndex天数的日志文件
  deleteOldFiles(currentActiveFile);
	...
}

void TimeBasedRollingPolicy::setMaxBackupDays(int newVal)
{
	maxBackupDays = newVal;
}

void TimeBasedRollingPolicy::deleteOldFiles(const LogString& currentActiveFile)
{
	if (maxBackupDays <= 0)
	{
		return;
	}

	if (currentActiveFile.size() == 0)
	{ 
		return;
	}

#ifdef WIN32
	//将要删除的文件列表
	std::vector<LogString> aryDelFiles;

	//获取当前日志文件的文件名和目录名
	LogString curLogFileName=extractFileName(currentActiveFile);
	LogString curLogFileDir=extractFileDir(currentActiveFile);

	//获取当前时间
	SYSTEMTIME curTimeSys;
	GetSystemTime(&curTimeSys);
	FILETIME curTimeFSys;
	SystemTimeToFileTime(&curTimeSys, &curTimeFSys);
	ULARGE_INTEGER curTimeUL;
	curTimeUL.LowPart = curTimeFSys.dwLowDateTime;
	curTimeUL.HighPart = curTimeFSys.dwHighDateTime;

	//生成搜索文件关键字
	LogString searchKey=curLogFileDir + L"*" + curLogFileName + L"*";

	WIN32_FIND_DATAW FileData; 
	HANDLE hSearch; 

	//开始搜索日志文件
	hSearch = FindFirstFileW(searchKey.c_str(), &FileData); 
	if (hSearch != INVALID_HANDLE_VALUE) 
	{ 
		do 
		{ 
			LogString strFindFile = FileData.cFileName;
			if (strFindFile != curLogFileName) //不包括当前的日志文件
			{
				LogString::size_type pos = strFindFile.find(curLogFileName.c_str());
				if (pos != LogString::npos)
				{
					//找到一个日志文件
					ULARGE_INTEGER fileTimeUL;
					fileTimeUL.LowPart = FileData.ftLastWriteTime.dwLowDateTime;
					fileTimeUL.HighPart = FileData.ftLastWriteTime.dwHighDateTime;
					//把文件修改时间和当前时间比较, 是否超过天数maxBackupDays
					if (curTimeUL.QuadPart > fileTimeUL.QuadPart &&
						(curTimeUL.QuadPart-fileTimeUL.QuadPart)/10000000 > maxBackupDays*24*3600)
					{
						aryDelFiles.push_back(curLogFileDir+strFindFile);
					}
				}
			}
		} 
		while(FindNextFileW(hSearch, &FileData));
	} 

	// Close the search handle. 
	FindClose(hSearch);

	//删除文件
	for (int i=0; i<aryDelFiles.size(); i++)
	{
		DeleteFileW(aryDelFiles[i].c_str());
	}
#endif
}

LogString TimeBasedRollingPolicy::extractFileDir(const LogString& In)
{
	LogString strtemp = In;

	for (int i=strtemp.size()-1; i>=0; i--)
	{
		if ( strtemp[i] == L'\\' || strtemp[i] == L'/' )
		{
			strtemp.erase(i+1);
			return(strtemp);
		}
	}

	return (L"");
}

LogString TimeBasedRollingPolicy::extractFileName(const LogString& In)
{
	const LogString& strtemp = In;

	for (int i=strtemp.size()-1; i>=0; i--)
	{
		if ( strtemp[i] == L'\\' || strtemp[i] == L'/' )
		{	
			return strtemp.substr(i+1);
		}
	}

	return(strtemp);
}
-- dailyrollingfileappender.h --

  class LOG4CXX_EXPORT DailyRollingFileAppender : public log4cxx::rolling::RollingFileAppenderSkeleton {
	...
	private:
	  //日志最大保存天数
	  int maxBackupDays; //add by pengliqing
	...
	};
-- dailyrollingfileappender.cpp --

DailyRollingFileAppender::DailyRollingFileAppender()
: maxBackupDays(0)
{
}


DailyRollingFileAppender::DailyRollingFileAppender(
  const LayoutPtr& layout,
  const LogString& filename,
  const LogString& datePattern1)
  : datePattern(datePattern1),
	maxBackupDays(0)
{
	...
}

void DailyRollingFileAppender::activateOptions(log4cxx::helpers::Pool& pool) {
	...
  policy->setFileNamePattern(pattern);
  policy->setMaxBackupDays(maxBackupDays); //add by pengliqing
  policy->activateOptions(pool);
  setTriggeringPolicy(policy);
  setRollingPolicy(policy);
	...
}

void DailyRollingFileAppender::setOption(const LogString& option,
   const LogString& value) {
     if (StringHelper::equalsIgnoreCase(option,
                     LOG4CXX_STR("DATEPATTERN"), LOG4CXX_STR("datepattern"))) {
             setDatePattern(value);

	 } else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("MAXBACKUPDAYS"), LOG4CXX_STR("maxbackupdays"))) { //add by pengliqing
		 maxBackupDays = StringHelper::toInt(value);
     } else {
         RollingFileAppenderSkeleton::setOption(option, value);
     }
}

-- log4cxx.properties --

log4j.rootLogger=debug,S

#S
log4j.appender.S=org.apache.log4j.DailyRollingFileAppender
log4j.appender.S.File=./hello.log

log4j.appender.S.DatePattern = '.'yyyy-MM-dd
#add by pengliqing
log4j.appender.S.MaxBackupDays=4

log4j.appender.S.layout=org.apache.log4j.PatternLayout
log4j.appender.S.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] [%5p] [%c] - %m%n




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值