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,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。