在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. CSS3 背景

    CSS3包含多个新的背景属性,他们提供了对背景更强大的控制. 本章将学到一下背景属性: background-size background-origin 你也将学到如何使用多重背景图片. 浏览器支持 ...

  2. 黑马程序员-out和ref

    C# 方法参数关键字:ref.out 当希望方法返回多个值时,声明 out方法很有用.使用 out参数的方法仍然可以将变量用作返回类型(请参见 return),但它还可以将一个或多个对象作为 out参 ...

  3. oracle 复制一条记录只改变主键不写全部列名

    场景:表TEST中有C1,C2,C3...字段,其中C1为主键,先需要复制表TEST中一条(C1='1'的)记录,修改主键列C1和需要变更的列后,再插入到表TEST中. procedure P_TES ...

  4. iOS 网络与多线程--6.下载并保存网络图片

    使用二进制数据对象的,从制定网站获取数据的方法,下载网络图片,并转化为二进制数据,然后将二进制数据保存到磁盘 按照注释需要进行阅读以下代码 // Created by JinXin on 15/12/ ...

  5. PHP Directory 函数

    PHP 5 Directory 函数 函数 描述 chdir() 改变当前的目录. chroot() 改变根目录. closedir() 关闭目录句柄. dir() 返回 Directory 类的实例 ...

  6. 编写css代码的方式

            css(层叠样式表) 在一个网页中主要负责了页面的数据样式.       编写css代码的方式:       第一种: 在style标签中编写css代码. 只能用于本页面中,复用性不强 ...

  7. 【学习笔记】【oc】类和对象及类的三大基本特征

    1.类和对象 类是抽象化,对象是具体化. (1)定义类: 分为两个步骤,类的声明:定义类的成员变量和方法:@interface 用于声明定义类的接口部分,@end表面定义结束:. 成员变量的定义:{} ...

  8. webuploader文件上传问题总结

    webuploader百度的一个很好的上传文件插件: 选择它的原因: 1.浏览器兼容性好,支持IE8,这是我最主要的,好多上传插件都不支持: 2.跨域访问,因为我的上传需要到图片服务器上,这就需要跨域 ...

  9. lua编码转换

    lua编码转换, 这个要记录下:http://www.lpfrx.com/archives/4918/ ,总是觉得lua没python甘方便,应该说没这么顺手吧,可能先入为主吧,python库多, 编 ...

  10. Attach file to database

    D:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA databaseName.mdf databaseName.l ...