Log4Qt使用(三)在DailyRollingFileAppender类中增加属性mMaxBackupIndex

  在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 = 0,
/*! 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 = 0);
DailyRollingFileAppender(Layout *pLayout,
const QString &rFileName,
const QString &rDatePattern,
const int rmaxBackupIndex = 7,
QObject *pParent = 0);
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(1999, 1, 1), QTime(0, 0));
const QString start_string = start_time.toString(mDatePattern);
mActiveDatePattern.clear();

if (start_string != static_cast<DateTime>(start_time.addSecs(60)).toString(mDatePattern))
mFrequency = MINUTELY_ROLLOVER;
else if (start_string != static_cast<DateTime>(start_time.addSecs(60 * 60)).toString(mDatePattern))
mFrequency = HOURLY_ROLLOVER;
else if (start_string != static_cast<DateTime>(start_time.addSecs(60 * 60 * 12)).toString(mDatePattern))
mFrequency = HALFDAILY_ROLLOVER;
else if (start_string != static_cast<DateTime>(start_time.addDays(1)).toString(mDatePattern))
mFrequency = DAILY_ROLLOVER;
else if (start_string != static_cast<DateTime>(start_time.addDays(7)).toString(mDatePattern))
mFrequency = WEEKLY_ROLLOVER;
else if (start_string != static_cast<DateTime>(start_time.addMonths(1)).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(),
0, 0));
mRollOverTime = start.addSecs(60);
}
break;
case HOURLY_ROLLOVER:
{
start = QDateTime(now_date,
QTime(now_time.hour(),
0, 0, 0));
mRollOverTime = start.addSecs(60*60);
}
break;
case HALFDAILY_ROLLOVER:
{
int hour = now_time.hour();
if (hour >= 12)
hour = 12;
else
hour = 0;
start = QDateTime(now_date,
QTime(hour, 0, 0, 0));
mRollOverTime = start.addSecs(60*60*12);
}
break;
case DAILY_ROLLOVER:
{
start = QDateTime(now_date,
QTime(0, 0, 0, 0));
mRollOverTime = start.addDays(1);
}
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 = 0;
start = QDateTime(now_date,
QTime(0, 0, 0, 0)).addDays(-1 * day);
mRollOverTime = start.addDays(7);
}
break;
case MONTHLY_ROLLOVER:
{
start = QDateTime(QDate(now_date.year(),
now_date.month(),
1),
QTime(0, 0, 0, 0));
mRollOverTime = start.addMonths(1);
}
break;
default:
Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant");
mRollOverTime = QDateTime::fromTime_t(0);
}

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 = 0;
int diff = list.size() - mMaxBackupIndex;
for (int i = 0; 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

时间: 2024-10-29 19:09:46

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

NSMutableDictionary 类中增加键值对方法分析

在iOS中可变字典增加一个键值对的方法有setObject: forKey: 和setValue : forKey: .为了方便我们把这两个方法简称为方法A和方法B. B这个方法中其中的value值是不能为nil,否则程序会出项崩溃.而A方法中的这个value可以为nil,但是当这个value位nil时,系统会自动调用removeObjectforKey:这个方法.这样就把这个键值对删除掉了.B方法中的key值可以是任意类型的,但是这个类型必须要实现NSCopying协议.而A方法中它的key值

增加、删除类文件或者在一个类中增加、删除方法时,是不能够热部署到服务上的。这时候需要停止服务器重新部署后再启动,就不会出现上面的提示了。

Hot Code Replace Failed 2010-11-05 10:11listquiry | 浏览 14226 次 Some code changes cannot be hot swapped into a running virtual machine, such as changing method names or introducing errors into running code.The current target virtual machine {jboss4Ser

能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么

不能向编译后得到的类中增加实例变量!能向运行时创建的类中添加实例变量! 因为编译后的类已经注册在runtime中,类结构体中的objc_ivar_list 实例变量的链表和instance_size实例变量的内存大小已经确定,同时runtime 会调用class_setIvarLayout 或 class_setWeakIvarLayout来处理strong weak引用,所以不能向存在的类中添加实例变量. 运行时创建的类是可以添加实例变量,调用 class_addIvar 函数,但是得在调用 

Python类中实例属性的通用显示工具

0.说明 以下的思想方法非常有用,可以帮助你在Python开发提高开发和维护效率,所以可能的话,请仔细琢磨一下其中的代码. 之前在用Python编写一个类时,为了显示的友好性,总是需要在每个类中重载__str__或者__repr__方法,现在有了更好的方法,不需要在每个类中都这么做了,下面给出的方法非常实用. 下面使用的例子使用的Python版本都是Python3.5,但实际上在Python2.7中进行也没有任何影响. 1.正常情况下类实例的不友好显示 在Python中编写一个类时,由于没有重载

将source类中的属性值赋给target类中对应的属性

/** * 对象的属性值拷贝 * <p> * 将source对象中的属性值赋值到target对象中的属性,属性名一样,类型一样 * <p> * example: * <p> * source: * <p> * String name; * String address; * Integer age; * Date birthday; * <p> * target: * String name; * String address; * String

实体类、数据访问类中的属性拓展

类中: using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; namespace 实体类_数据访问类.App_Code { public class Users { SqlConnection conn = null; SqlCommand cmd = null; public Users() { conn = new S

C#类中的属性和字段

字段就是类中自定义的一些变量或是常量,用来记录此类的相关信息和属性,通常和外部定义没什么区别,就是需要添加public等修饰符: 属性也是是类中的概念之一,就是外部访问内部私有(private)字段的一个函数方法, 一般分为自定义属性: 使用get,set访问器自定义对字段赋值 默认定义, 只声明get和set不具体指定,则会默认生成属性字段. 注意只读和只写属性可以通过只定义get和set中的一个来实现: 属性也可以设置值来限制对字段的访问,例如在set中可以添加判断,get返回中可以返回其他

在函数中处理html点击事件在标签中增加属性值来解决问题。

backhtml += "  <i onclick='dispshow("+item.newsID+")'>" + item.newTitle + "</i>"; //这行代码相当于“投资还款标签” //下面处理函数 function dispshow(newsID){    $.ajax({        type: "post",        url: "/Information/vie

python隐藏类中的属性

方法一: 效果图一: 代码一: # 定义一个矩形的类 class Rectangle: # 定义初始化方法 def __init__(self,width,height): self.hidden_width = width self.hidden_height = height # 定义获取width.height的方法 def get_width(self): return self.hidden_width def get_height(self): return self.hidden_