在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. window.location.href 和self.location的区别

    你从字面上就可以理解到 window 指的是当前窗口 而 self 指的是自己 在HTML 中 由于页面可以镶嵌页面 所以这2个就有了 区别 比如说 我有个页面A.HTML 里面嵌套了一个B.HTML ...

  2. RTSP协议资料

    维基百科: RTSP:http://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol RTP:http://en.wikipedia.org/wik ...

  3. BOM和DOM的联系和区别

    BOM中的对象 Window对象: 是整个BOM的核心,所有对象和集合都以某种方式回接到window对象.Window对象表示整个浏览器窗口,但不必表示其中包含的内容. Document对象: 实际上 ...

  4. codeforces 672 D

    题目链接:http://codeforces.com/problemset/problem/672/D 题目大意:进行k次操作,每次将最大值集合中最大值-1,最小值+1,问你K次操作之后,最大值和最小 ...

  5. oracle双机热备概念

    1. 双机热备概述      双机热备有两种实现模式,一种是基于共享的存储设备的方式,另一种是没有共享的存储设备的方式,一般称为纯软件方式.      基于存储共享的双机热备是双机热备的最标准方案. ...

  6. PHPCMSV9 采集网址后,再采集内容,报错:“采集采集内容 没有找到网址列表,请先进行网址采集”

    解决方法:直接清除v9_collection_history 表里的内容.

  7. Java泛型的基本应用

    一.泛型概述 jdk1.5版本以后出现的新特性,用于解决安全问题,是一个安全机制. 好处: 1,将运行时期的问题ClassCastException转到了编译时期. 2,避免了强制转换的麻烦. 什么时 ...

  8. 2017-1-9css

    2017-1-9css css border-image详解 http://www.360doc.com/content/14/1016/13/2792772_417403574.shtml 最简单的 ...

  9. java获取当前时间

    /////////////////获取时间方法一////////////////////////////// java.util.Date uDate=new java.util.Date(); Sy ...

  10. web UI

    Semantic不错的UI,代码非常详细