在Log4Qt中存在一个比较大的问题,当使用 DailyRollingFileAppender对日志进行输出时,会无限输出文件,也就是说,当系统运行很久时,日志文件有可能很大,大到无法想象。因此,很多开发者希望在DailyRollingFileAppender中加一个属性,用于配置日志文件的个数。

  但是如何做呢?

  在Java语言中,我找到一个实例,但是在QT中,没能找到,因此,只能通过自己看源代码,分析从而进行改进。

  主要代码如下:

  dailyrollingfileappender.h:

class DailyRollingFileAppender : public FileAppender
{
Q_OBJECT /*!
* The property holds the date pattern used by the appender.
*
* The default is DAILY_ROLLOVER for rollover at midnight each day.
*
* \sa datePattern(), setDatePattern()
*/
Q_PROPERTY(QString datePattern READ datePattern WRITE setDatePattern) /*!
* The property holds the maximum backup count used by the appender.
*
* The default is 1.
*
* \sa maxBackupIndex(), setMaxBackupIndex()
*/
Q_PROPERTY(int maxBackupIndex READ maxBackupIndex WRITE setMaxBackupIndex)
public:
/*!
* The enum DatePattern defines constants for date patterns.
*
* \sa setDatePattern(DatePattern)
*/
enum DatePattern
{
/*! The minutely date pattern string is "'.'yyyy-MM-dd-hh-mm". */
MINUTELY_ROLLOVER = ,
/*! The hourly date pattern string is "'.'yyyy-MM-dd-hh". */
HOURLY_ROLLOVER,
/*! The half-daily date pattern string is "'.'yyyy-MM-dd-a". */
HALFDAILY_ROLLOVER,
/*! The daily date pattern string is "'.'yyyy-MM-dd". */
DAILY_ROLLOVER,
/*! The weekly date pattern string is "'.'yyyy-ww". */
WEEKLY_ROLLOVER,
/*! The monthly date pattern string is "'.'yyyy-MM". */
MONTHLY_ROLLOVER
};
Q_ENUMS(DatePattern) DailyRollingFileAppender(QObject *pParent = );
DailyRollingFileAppender(Layout *pLayout,
const QString &rFileName,
const QString &rDatePattern,
const int rmaxBackupIndex = ,
QObject *pParent = );
virtual ~DailyRollingFileAppender(); private:
DailyRollingFileAppender(const DailyRollingFileAppender &rOther); // Not implemented
DailyRollingFileAppender &operator=(const DailyRollingFileAppender &rOther); // Not implemented void removeFiles(); public:
int maxBackupIndex() const;
void setMaxBackupIndex(int maxBackupIndex);
QString datePattern() const; /*!
* Sets the datePattern to the value specified by the \a datePattern
* constant.
*/
void setDatePattern(DatePattern datePattern); void setDatePattern(const QString &rDatePattern); virtual void activateOptions(); protected:
virtual void append(const LoggingEvent &rEvent); /*!
* Tests if all entry conditions for using append() in this class are
* met.
*
* If a conditions is not met, an error is logged and the function
* returns false. Otherwise the result of
* FileAppender::checkEntryConditions() is returned.
*
* The checked conditions are:
* - A valid pattern has been set (APPENDER_USE_INVALID_PATTERN_ERROR)
*
* The function is called as part of the checkEntryConditions() chain
* started by AppenderSkeleton::doAppend().
*
* \sa AppenderSkeleton::doAppend(),
* AppenderSkeleton::checkEntryConditions()
*/
virtual bool checkEntryConditions() const; protected:
#ifndef QT_NO_DEBUG_STREAM
/*!
* Writes all object member variables to the given debug stream
* \a rDebug and returns the stream.
*
* <tt>
* %DailyRollingFileAppender(name:"DRFA" activedatepattern:"'.'yyyy-MM-dd-hh-mm"
* appendfile:false bufferedio:true
* datepattern:"'.'yyyy-MM-dd-hh-mm"
* encoding:"" frequency:"MINUTELY_ROLLOVER"
* file:"/log.txt" filter:0x0 immediateflush:true
* isactive:true isclosed:false layout:"TTCC"
* referencecount:1
* rollovertime:QDateTime("Mon Oct 22 05:23:00 2007")
* threshold: "NULL" writer: 0x0 )
* </tt>
* \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject)
*/
virtual QDebug debug(QDebug &rDebug) const;
#endif // QT_NO_DEBUG_STREAM private:
void computeFrequency();
void computeRollOverTime();
QString frequencyToString() const;
void rollOver(); private:
QString mDatePattern;
DatePattern mFrequency;
QString mActiveDatePattern;
QDateTime mRollOverTime;
QString mRollOverSuffix; protected:
int mMaxBackupIndex;
}; /**************************************************************************
* Operators, Helper
**************************************************************************/ /**************************************************************************
* Inline
**************************************************************************/ inline QString DailyRollingFileAppender::datePattern() const
{ QMutexLocker locker(&mObjectGuard);
return mDatePattern; } inline void DailyRollingFileAppender::setDatePattern(const QString &rDatePattern)
{ QMutexLocker locker(&mObjectGuard);
mDatePattern = rDatePattern; } inline int DailyRollingFileAppender::maxBackupIndex() const
{ QMutexLocker locker(&mObjectGuard);
return mMaxBackupIndex; } inline void DailyRollingFileAppender::setMaxBackupIndex(int maxBackupIndex)
{ QMutexLocker locker(&mObjectGuard);
mMaxBackupIndex = maxBackupIndex; }

  其中,Q_PROPERTY(int maxBackupIndex READ maxBackupIndex WRITE setMaxBackupIndex)这句话什么重要。

  dailyrollingfileappender.cpp:

DailyRollingFileAppender::DailyRollingFileAppender(QObject *pParent) :
FileAppender(pParent),
mDatePattern()
{
setDatePattern(DAILY_ROLLOVER);
} DailyRollingFileAppender::DailyRollingFileAppender(Layout *pLayout,
const QString &rFileName,
const QString &rDatePattern,
const int rmaxBackupIndex,
QObject *pParent) :
FileAppender(pLayout, rFileName, pParent),
mDatePattern(), mMaxBackupIndex(rmaxBackupIndex)
{
setDatePattern(rDatePattern);
} DailyRollingFileAppender::~DailyRollingFileAppender()
{
close();
} void DailyRollingFileAppender::setDatePattern(DatePattern datePattern)
{
switch (datePattern)
{
case MINUTELY_ROLLOVER:
setDatePattern(QLatin1String("'.'yyyy-MM-dd-hh-mm"));
break;
case HOURLY_ROLLOVER:
setDatePattern(QLatin1String("'.'yyyy-MM-dd-hh"));
break;
case HALFDAILY_ROLLOVER:
setDatePattern(QLatin1String("'.'yyyy-MM-dd-a"));
break;
case DAILY_ROLLOVER:
setDatePattern(QLatin1String("'.'yyyy-MM-dd"));
break;
case WEEKLY_ROLLOVER:
setDatePattern(QLatin1String("'.'yyyy-ww"));
break;
case MONTHLY_ROLLOVER:
setDatePattern(QLatin1String("'.'yyyy-MM"));
break;
default:
Q_ASSERT_X(false, "DailyRollingFileAppender::setDatePattern()", "Invalid datePattern constant");
setDatePattern(DAILY_ROLLOVER);
};
} void DailyRollingFileAppender::activateOptions()
{
QMutexLocker locker(&mObjectGuard); computeFrequency();
if (!mActiveDatePattern.isEmpty())
{
computeRollOverTime();
FileAppender::activateOptions();
}
} void DailyRollingFileAppender::append(const LoggingEvent &rEvent)
{
// Q_ASSERT_X(, "DailyRollingFileAppender::append()", "Lock must be held by caller") if (QDateTime::currentDateTime() > mRollOverTime)
rollOver();
FileAppender::append(rEvent);
} bool DailyRollingFileAppender::checkEntryConditions() const
{
// Q_ASSERT_X(, "DailyRollingFileAppender::checkEntryConditions()", "Lock must be held by caller") if (mActiveDatePattern.isEmpty())
{
LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without having a valid date pattern set"),
APPENDER_USE_INVALID_PATTERN_ERROR);
e << name();
logger()->error(e);
return false;
} return FileAppender::checkEntryConditions();
} #ifndef QT_NO_DEBUG_STREAM
QDebug DailyRollingFileAppender::debug(QDebug &rDebug) const
{
QString layout_name;
if (layout())
layout_name = layout()->name();
QString codec_name;
if (encoding())
codec_name = QLatin1String(encoding()->name()); rDebug.nospace() << "DailyRollingFileAppender("
<< "name:" << name() << " "
<< "activedatepattern:" << mActiveDatePattern << " "
<< "appendfile:" << appendFile() << " "
<< "bufferedio:" << bufferedIo() << " "
<< "datepattern:" << datePattern() << " "
<< "encoding:" << codec_name << " "
<< "frequency:" << frequencyToString() << " "
<< "file:" << file() << " "
<< "filter:" << firstFilter() << " "
<< "immediateflush:" << immediateFlush() << " "
<< "isactive:" << isActive() << " "
<< "isclosed:" << isClosed() << " "
<< "layout:" << layout_name << " "
<< "referencecount:" << referenceCount() << " "
<< "rollovertime:" << mRollOverTime
<< "threshold:" << threshold().toString()
<< "writer:" << writer()
<< ")";
return rDebug.space();
}
#endif // QT_NO_DEBUG_STREAM void DailyRollingFileAppender::computeFrequency()
{
// Q_ASSERT_X(, "DailyRollingFileAppender::computeFrequency()", "Lock must be held by caller") const DateTime start_time(QDate(, , ), QTime(, ));
const QString start_string = start_time.toString(mDatePattern);
mActiveDatePattern.clear(); if (start_string != static_cast<DateTime>(start_time.addSecs()).toString(mDatePattern))
mFrequency = MINUTELY_ROLLOVER;
else if (start_string != static_cast<DateTime>(start_time.addSecs( * )).toString(mDatePattern))
mFrequency = HOURLY_ROLLOVER;
else if (start_string != static_cast<DateTime>(start_time.addSecs( * * )).toString(mDatePattern))
mFrequency = HALFDAILY_ROLLOVER;
else if (start_string != static_cast<DateTime>(start_time.addDays()).toString(mDatePattern))
mFrequency = DAILY_ROLLOVER;
else if (start_string != static_cast<DateTime>(start_time.addDays()).toString(mDatePattern))
mFrequency = WEEKLY_ROLLOVER;
else if (start_string != static_cast<DateTime>(start_time.addMonths()).toString(mDatePattern))
mFrequency = MONTHLY_ROLLOVER;
else
{
LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("The pattern '%1' does not specify a frequency for appender '%2'"),
APPENDER_INVALID_PATTERN_ERROR);
e << mDatePattern << name();
logger()->error(e);
return;
} mActiveDatePattern = mDatePattern;
logger()->trace("Frequency set to %2 using date pattern %1",
mActiveDatePattern,
frequencyToString());
} void DailyRollingFileAppender::computeRollOverTime()
{
// Q_ASSERT_X(, "DailyRollingFileAppender::computeRollOverTime()", "Lock must be held by caller")
Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::computeRollOverTime()", "No active date pattern"); QDateTime now = QDateTime::currentDateTime();
QDate now_date = now.date();
QTime now_time = now.time();
QDateTime start; switch (mFrequency)
{
case MINUTELY_ROLLOVER:
{
start = QDateTime(now_date,
QTime(now_time.hour(),
now_time.minute(),
, ));
mRollOverTime = start.addSecs();
}
break;
case HOURLY_ROLLOVER:
{
start = QDateTime(now_date,
QTime(now_time.hour(),
, , ));
mRollOverTime = start.addSecs(*);
}
break;
case HALFDAILY_ROLLOVER:
{
int hour = now_time.hour();
if (hour >= )
hour = ;
else
hour = ;
start = QDateTime(now_date,
QTime(hour, , , ));
mRollOverTime = start.addSecs(**);
}
break;
case DAILY_ROLLOVER:
{
start = QDateTime(now_date,
QTime(, , , ));
mRollOverTime = start.addDays();
}
break;
case WEEKLY_ROLLOVER:
{
// QT numbers the week days 1..7. The week starts on Monday.
// Change it to being numbered 0..6, starting with Sunday.
int day = now_date.dayOfWeek();
if (day == Qt::Sunday)
day = ;
start = QDateTime(now_date,
QTime(, , , )).addDays(- * day);
mRollOverTime = start.addDays();
}
break;
case MONTHLY_ROLLOVER:
{
start = QDateTime(QDate(now_date.year(),
now_date.month(),
),
QTime(, , , ));
mRollOverTime = start.addMonths();
}
break;
default:
Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant");
mRollOverTime = QDateTime::fromTime_t();
} mRollOverSuffix = static_cast<DateTime>(start).toString(mActiveDatePattern);
Q_ASSERT_X(static_cast<DateTime>(now).toString(mActiveDatePattern) == mRollOverSuffix,
"DailyRollingFileAppender::computeRollOverTime()", "File name changes within interval");
Q_ASSERT_X(mRollOverSuffix != static_cast<DateTime>(mRollOverTime).toString(mActiveDatePattern),
"DailyRollingFileAppender::computeRollOverTime()", "File name does not change with rollover"); logger()->trace("Computing roll over time from %1: The interval start time is %2. The roll over time is %3",
now,
start,
mRollOverTime);
} QString DailyRollingFileAppender::frequencyToString() const
{
QMetaEnum meta_enum = metaObject()->enumerator(metaObject()->indexOfEnumerator("DatePattern"));
return QLatin1String(meta_enum.valueToKey(mFrequency));
} void DailyRollingFileAppender::removeFiles()
{
QDir dir("./logs");
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Time | QDir::Reversed); QFileInfoList list = dir.entryInfoList();
QFileInfo fileInfo; if(list.size() >= mMaxBackupIndex)
{
int index = ;
int diff = list.size() - mMaxBackupIndex;
for (int i = ; i < list.size(); ++i)
{
fileInfo = list.at(i);
if(index >= diff)
{
break;
} QFile file(fileInfo.absoluteFilePath());
QByteArray ba = fileInfo.absoluteFilePath().toLatin1();
cout<<ba.data()<<endl;
file.remove();
index++;
} }
} void DailyRollingFileAppender::rollOver()
{
// Q_ASSERT_X(, "DailyRollingFileAppender::rollOver()", "Lock must be held by caller")
Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::rollOver()", "No active date pattern"); QString roll_over_suffix = mRollOverSuffix;
computeRollOverTime();
if (roll_over_suffix == mRollOverSuffix)
return; closeFile(); QString target_file_name = file() + roll_over_suffix;
QFile f(target_file_name);
if (f.exists() && !removeFile(f))
return;
f.setFileName(file());
if (!renameFile(f, target_file_name))
return;
openFile(); removeFiles();
//huabo }

Log4Qt使用(三)在DailyRollingFileAppender类中增加属性mMaxBackupIndex的更多相关文章

  1. 正确停止线程的方式三 使用Thread类中的内置的中断标记位-----------不熟悉

    package charpter10; public class Processor implements Runnable { @Override public void run() { for ( ...

  2. Java反射机制demo(三)—获取类中的构造函数

    Java反射机制demo(三)—获取类中的构造函数 1,获取类中所有的构造函数 如下面的代码中所示,这个类中显式的构造函数有五个. 空构造: public UserInfo() 带参构造有四个: pu ...

  3. 转载:java 中对类中的属性使用set/get方法的意义和用法

    经常看到有朋友提到类似:对类中的属性使用set/get方法的作用?理论的回答当然是封闭性之类的,但是这样对我们有什么作用呢?为什么要这样设计?我直接使用属性名来访问不是更直接,代码更简洁明了吗?下面我 ...

  4. 尚硅谷面试第一季-11MyBatis中当实体类中的属性名和表中的字段名不一样怎么办

    问题: MyBatis中当实体类中的属性名和表中的字段名不一样 ,怎么办 ? 解决方案: 1.写sql语句时起别名 <!-- id属性:必须是接口中方法的方法名 resultType属性:必须是 ...

  5. 关于System类中out属性 实例化的问题

    System类中out属性的声明是这样的: public final static PrintStream out = nullPrintStream(); private static PrintS ...

  6. 使用反射获取类中的属性(可用于动态返回PO类的列,当做表格的表头)

    //利用反射取类中的属性字段 try { Class clazz = Class.forName("houji.bean.model.TaskModel"); Field[] fi ...

  7. Delphi 遍历类中的属性

    http://blog.csdn.net/easyboot/article/details/8004954 Delphi 遍历类中的属性 标签: delphistringbuttonclassform ...

  8. Python 简明教程 --- 20,Python 类中的属性与方法

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 与客户保持良好的关系可以使生产率加倍. -- Larry Bernstain 目录 类中的变量称为属 ...

  9. Java初学者作业——定义英雄类(Hero),英雄类中的属性包括:姓名、攻击力、防御力、生命值和魔法值;方法包括:攻击、介绍。

    返回本章节 返回作业目录 需求说明: 定义英雄类(Hero),英雄类中的属性包括:姓名.攻击力.防御力.生命值和魔法值:方法包括:攻击.介绍. 实现思路: 分析类的属性及其变量类型. 分析类的方法及其 ...

随机推荐

  1. phpmyadmin导出数据库为什么是php文件

    你的迅雷在作怪,把它卸载了,或者在迅雷的高级设置中,关闭监听浏览器,就不会触发迅雷下载,就没问题了.或者360浏览器的话,把急速模式改为兼容模式

  2. PL/SQL中文显示都显示成“?”的问题

    PL/SQL中文显示都显示成“?”的问题  首先我在sqlplus里面查询到的中文是正常的,然后再oracle里面的注册表里面看得nls_lang是SIMPLIFIED CHINESE_CHINA.Z ...

  3. JavaScript 显示弹出窗口(二)

    window. open ( sURL , sName , sFeatures , bReplace ) sURL:可选项,被加载页面的html sName:可选项,指定打开的窗口的名字 _media ...

  4. JAVA-6-简单的模拟ATM使用

    public static void main(String[] args) { in = new Scanner(System.in); int count = 1; int pwd = 11111 ...

  5. JQuery连接地址

    <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script> http://co ...

  6. dede仿站笔记

    仿站步骤查看是否为dedecms的方法,看引用路径src="/templets/default2012/images/toutiao.png" 0查看仿站编码,选择utf8或gbk ...

  7. Java接口和抽象类的实现方法

    一.java中的接口本质上是加约束的抽象类 //抽象类 public abstract class AExample { public abstract int add(int x,int y); p ...

  8. 怎么用visual studio2010编写c++程序|用visual studio2010编写c++程序的步骤

    如何通过visual studio 2010编写一个简单的c++程序,随小编不一起看看如何编写. 首先打开visual studio 2010 点击软件左上角“文件-新建-项目”,选择“win32-w ...

  9. GitHub与VS2013完成项目管理

    https://github.com 程序员应该去注册一个账号的网站 1.创建一个仓库 登录你的github网站:找到新建一个仓库的入口 一些基本信息填写完毕后,点击创建,即可拥有一个仓库 2. 让V ...

  10. IOS编程教程(八):在你的应用程序添加启动画面

    IOS编程教程(八):在你的应用程序添加启动画面   虽然你可能认为你需要编写闪屏的代码,苹果已经可以非常轻松地把它做在Xcode中.不需要任何编码.你只需要做的是设置一些配置. 什么是闪屏 对于那些 ...