zoukankan      html  css  js  c++  java
  • 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
    
        }
  • 相关阅读:
    Cocos2d-x教程(34)-三维物体OBB碰撞检測算法
    POJ 2485 Highways 最小生成树 (Kruskal)
    LintCode-分糖果
    云存储市场布局已定,怎样助力企业互联网转型
    HDU 1853 Cyclic Tour(最小费用最大流)
    windows下基于bat的每1分钟执行一次一个程序
    python中匹配中文,解决不匹配,乱码等问题
    bytes,packet区别 字节数据包
    wmic
    paramiko 模块封装
  • 原文地址:https://www.cnblogs.com/wiessharling/p/3753972.html
Copyright © 2011-2022 走看看