ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

log4cxx增加时间回滚模式写maxBackUpIndex属性

2021-01-23 16:03:39  阅读:268  来源: 互联网

标签:文件 maxBackUpIndex currentActiveFile 回滚 LogString strtemp pool 日志 log4cxx


在使用日志功能时,选择了目前比较常见的log4cxx,配置过程完全按照部分网上的经验进行配置。后续在使用过程中发现,配置的maxBackUpIndex属性并未生效,日志文件的数量还是在不停的增加。

使用的日志生成模式是DailyRollingFileAppender。

解决此问题时,摒弃了网上的经验,通过阅读源码发现。

log4cxx 日志新增模式有两种:

一种是按照文件大小生成:RollingFileAppender,此模式下,日志按照文件大小新增,日志文件大小在达到设定的阈值后会进行回滚,生成新文件,并且maxBackUpIndex属性正常生效,即日志文件数量达到设定的阈值后会自动进行删除,使日志文件始终保存在设定的阈值范围之内。

另一种是按照日期生成:DailyRollingFileAppender,此模式下,日志文件按照生成的配置生成文件,并且该模式下并没有maxBackUpIndex属性,即不会维护日志文件的数量。

鉴于此原因,对源码进行修改,增加类似RollingFileAppender模式下maxBackUpIndex属性,进行日志文件的管理,新增属性,maxBackUpDay,保持日志文件的数量为设定的天数之内的文件,超过次天数的日志在自动回滚时进行删除。

代码比较简单,模仿maxBackUpIndex属性的实现。

在dailyrollingfileappender.h文件中,新增成员变量:maxBackupDay

class LOG4CXX_EXPORT DailyRollingFileAppender : public log4cxx::rolling::RollingFileAppenderSkeleton {

private:
	int maxBackupDay;   //表示保留至少该天数之内的文件
};

在dailyrollingfileappender.cpp文件中,首先进行变量的初始化。

DailyRollingFileAppender::DailyRollingFileAppender() :
	maxBackupDay(0)
{
}

然后从配置文件中读取配置数据:

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("MAXBACKUPDAY"), LOG4CXX_STR("maxbackupday"))
		 || StringHelper::equalsIgnoreCase(option,
		 LOG4CXX_STR("MAXIMUMBACKUPDAY"), LOG4CXX_STR("maximumbackupday")))
	 {
		 maxBackupDay = StringHelper::toInt(value);     //读取配置文件的配置
	 }
	 else {
         RollingFileAppenderSkeleton::setOption(option, value);
     }
}

然后在设置回滚策略时设置该参数:

void DailyRollingFileAppender::activateOptions(log4cxx::helpers::Pool& pool) {
  
  policy->setFileNamePattern(pattern);
  policy->setMaxDay(maxBackupDay);
  policy->activateOptions(pool);
  setTriggeringPolicy(policy);
  setRollingPolicy(policy);

  RollingFileAppenderSkeleton::activateOptions(pool);
}

在基于时间的回滚策略中,进行该配置的处理与实现。

在timebasedrollingpolicy.h文件中,新增成员函数:

class LOG4CXX_EXPORT TimeBasedRollingPolicy : public RollingPolicyBase, public TriggeringPolicy 
{
private:
    int maxBackupDay;

    void deleteOldFiles(const LogString& currentActiveFile, log4cxx::helpers::Pool& pool);
    LogString extractFileDir(const LogString& In);  //获取当前日志目录
    LogString extractFileName(const LogString& In); //获取当前正在记录的日志文件名称

public:
        void setMaxDay(int newVal);   
};

在timebasedrollingpolicy.cpp文件中,实现文件的回滚删除。

void TimeBasedRollingPolicy::setMaxDay(int newVal)
{
	maxBackupDay = newVal;
}
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);
}
oid TimeBasedRollingPolicy::deleteOldFiles(const LogString& currentActiveFile, log4cxx::helpers::Pool& pool)
{
	if (maxBackupDay <= 0)
	{
		return;
	}

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

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


    /**获取到当前日志目录下面的所有文件列表,起初自己写了比较挫的使用WINAPI获取的代码,后面发现工程中已经有了比较简单的获取方法**/

	File toRenameBase;
	toRenameBase.setPath(curLogFileDir);
	std::vector<LogString> filename;
	std::vector<LogString> aryDelFiles;
	filename = toRenameBase.list(pool);

	__int64 sec1 = time(NULL);

	logchar t[] = { '.'};
	logchar tm[] = { '..' };

    //遍历获取到的文件列表,将最后一次修改时间与当前比较,时间差大于设置的天数的文件路径存入待删除的容器中,然后删除。

	for (int nIndex = 0; nIndex < filename.size(); ++nIndex)
	{
		if (filename[nIndex] == LogString(t) || filename[nIndex] == LogString(tm) || filename[nIndex] == curLogFileName)
		{
			continue;
		}

		File file;
		file.setPath(curLogFileDir + filename[nIndex]);
		log4cxx_time_t time = file.lastModified(pool) / 1000000;
		if (sec1 - time > maxBackupDay * 24 * 3600)
		{
			aryDelFiles.push_back(curLogFileDir + filename[nIndex]);
		}
	}

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

回滚函数中有一点是需要注意的,就是我们删除文件的函数调用位置,在调试的时候,发现有一些代码在单步调试的时候不执行。

RolloverDescriptionPtr TimeBasedRollingPolicy::rollover( const LogString& currentActiveFile, Pool& pool)
{
    ...
    LogString buf;
    ObjectPtr obj(new Date(n));
    formatFileName(obj, buf, pool);

    deleteOldFiles(currentActiveFile, pool);

    LogString newFileName(buf);

    //
    //  if file names haven't changed, no rollover
    //
    if (newFileName == lastFileName) {
    RolloverDescriptionPtr desc;
    return desc;
    }

    //  deleteOldFiles(currentActiveFile, pool);    调用放在此处时,发现单步调试时,不会被调用
    ...

    if (currentActiveFile != lastBaseName) {
    renameAction =
    new FileRenameAction(
    File().setPath(currentActiveFile), File().setPath(lastBaseName), true);
    nextActiveFile = currentActiveFile;
    }
    ...
}

道听途说,可能只是获取了一半的信息,另一半还在向你奔来的路上,你却直接转身返回了。找一找根源。更方便解决问题。站在系统的角度,而不是问题的角度。

标签:文件,maxBackUpIndex,currentActiveFile,回滚,LogString,strtemp,pool,日志,log4cxx
来源: https://blog.csdn.net/tax10240809163com/article/details/113053072

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有