欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Log4Qt快速入門(mén)——Log4Qt日志輸出重定向源碼解析

Log4Qt快速入門(mén)——Log4Qt日志輸出重定向源碼解析

一、Appender簡(jiǎn)介

1、Appender簡(jiǎn)介

Appender是所有Appender的抽象類,是對(duì)記錄日志形式的抽象。Log4Qt(Qt4版本)中Appender繼承體系如下:
Log4Qt快速入門(mén)——Log4Qt日志輸出重定向源碼解析

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比德江網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式德江網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋德江地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。

2、Appender接口

virtual Filter *filter() const = 0;
virtual QString name() const = 0;
virtual Layout *layout() const = 0;
virtual bool requiresLayout() const = 0;
virtual void setLayout(Layout *pLayout) = 0;
virtual void setName(const QString &rName) = 0;
virtual void addFilter(Filter *pFilter) = 0;
virtual void clearFilters() = 0; 
virtual void close() = 0;
virtual void doAppend(const LoggingEvent &rEvent) = 0;

二、AppenderSkeleton

1、AppenderSkeleton簡(jiǎn)介

AppenderSkeleton繼承自Appender類,實(shí)現(xiàn)了Appender的通用功能,但沒(méi)有實(shí)現(xiàn)繼承自Appender的部分接口,所以仍然是一個(gè)抽象類,不能實(shí)例化。AppenderSkeleton的所有函數(shù)都是線程安全的。

2、AppenderSkeleton接口

virtual Filter *filter() const;
virtual Layout *layout() const;
bool isActive() const;
bool isClosed() const;
virtual QString name() const;
Level threshold() const;
virtual void setLayout(Layout *pLayout);
virtual void setName(const QString &rName);
void setThreshold(Level level);
virtual void activateOptions();
virtual void addFilter(Filter *pFilter);
virtual void clearFilters();
virtual void close();
virtual void doAppend(const LoggingEvent &rEvent);
Filter* firstFilter() const;
bool isAsSevereAsThreshold(Level level) const;

自定義Appender可以從AppenderSkeleton派生,須要實(shí)現(xiàn)以下三個(gè)接口:

virtual void append(const LoggingEvent &rEvent) = 0;
virtual bool requiresLayout() const = 0;
virtual QDebug debug(QDebug &rDebug) const = 0;

append接口負(fù)責(zé)處理LoggingEvent對(duì)象,將格式化的日志信息輸出到不同的輸出地,如文本流、文件流、數(shù)據(jù)庫(kù)等,如果需要將日志信息重定向到QWidget組件,需要在append函數(shù)發(fā)送信號(hào),日志信息作為信號(hào)參數(shù),在相應(yīng)的QWidget組件的槽函數(shù)接收處理日志信息。
也可以根據(jù)需要從WriterAppender、ConsoleAppender、
FileAppender、RollingFileAppender、DailyRollingFileAppender派生類進(jìn)行實(shí)現(xiàn)。

三、WriterAppender

1、WriterAppender簡(jiǎn)介

WriterAppender類繼承自AppenderSkeleton類,在其實(shí)現(xiàn)的append函數(shù)中會(huì)將LoggingEvent對(duì)象的日志信息輸出到QTextStream對(duì)象。WriterAppender的所有函數(shù)是線程安全的。

void WriterAppender::append(const LoggingEvent &rEvent)
{
    QString message(layout()->format(rEvent));
    //輸出格式化的日志信息到QTextStream對(duì)象
    *mpWriter << message;
    if (handleIoErrors())
        return;
    // 是否刷新
    if (immediateFlush())
    {
        mpWriter->flush();
        if (handleIoErrors())
            return;
    }
}

2、WriterAppender常用接口

QTextCodec *encoding() const;
獲取輸出文本流的編碼器
bool immediateFlush() const;
獲取是否立即刷新
QTextStream *writer() const;
獲取輸出文本流對(duì)象
void setEncoding(QTextCodec *pTextCodec);
設(shè)置文本流的編碼器
void setImmediateFlush(bool immediateFlush);
設(shè)置是否立即刷新
void setWriter(QTextStream *pTextStream);
設(shè)置輸出文本流
virtual void close();
關(guān)閉文本流,如果有設(shè)置頁(yè)腳,會(huì)打印出頁(yè)腳信息

四、ConsoleAppender

1、ConsoleAppender簡(jiǎn)介

ConsoleAppender類繼承自WriterAppender類,ConsoleAppender定義了標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯(cuò)誤兩種控制臺(tái)的輸出目的地。ConsoleAppender的所有函數(shù)是線程安全的。

enum Target
{
    STDOUT_TARGET,//標(biāo)準(zhǔn)輸出
    STDERR_TARGET//標(biāo)準(zhǔn)錯(cuò)誤
};

2、ConsoleAppender日志重定向的實(shí)現(xiàn)

在ConsoleAppender配置完成后,需要對(duì)其配置選項(xiàng)進(jìn)行激活,ConsoleAppender的activateOptions函數(shù)中會(huì)將文本流指向相應(yīng)控制臺(tái)的文本流對(duì)象。

void ConsoleAppender::activateOptions()
{
    QMutexLocker locker(&mObjectGuard);
    closeStream();

    if (mTarget == STDOUT_TARGET)
        mpTextStream = new QTextStream(stdout);
    else
        mpTextStream = new QTextStream(stderr);
    // 調(diào)用WriterAppender的setWriter函數(shù),
    // 將日志信息重定向到控制臺(tái)對(duì)應(yīng)的文本流
    setWriter(mpTextStream);

    WriterAppender::activateOptions();
}

當(dāng)Logger進(jìn)行日志輸出時(shí),會(huì)在WriterAppender的append函數(shù)將格式化的日志信息輸出到相應(yīng)控制臺(tái)對(duì)應(yīng)的文本流,完成輸出目的地的重定向。

3、ConsoleAppender常用接口

QString target() const;
獲取輸出目的地
void setTarget(const QString &rTarget);
設(shè)置rTarget字符串為輸出目的地
void setTarget(Target target);
設(shè)置target為輸出目的地
virtual void activateOptions();
激活ConsoleAppender設(shè)置的選項(xiàng)
virtual void close();
關(guān)閉ConsoleAppender

4、ConsoleAppender示例

#include <QCoreApplication>
#include <QTextCodec>
#include <log4qt/logger.h>
#include <log4qt/ttcclayout.h>
#include <log4qt/consoleappender.h>
#include <log4qt/loggerrepository.h>
#include <QThread>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QThread::currentThread()->setObjectName("MainThread");

    // 創(chuàng)建TTCCLayout
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
    layout->setDateFormat("yyyy-mm-dd hh:mm:ss");
    // 激活選項(xiàng)
    layout->activateOptions();

    // 創(chuàng)建ConsoleAppender
    Log4Qt::ConsoleAppender *appender = new Log4Qt::ConsoleAppender();
    appender->setLayout(layout);
    // 設(shè)置編碼
    appender->setEncoding(QTextCodec::codecForName("UTF-8"));
    // 設(shè)置輸出目的地為stdout
    appender->setTarget(Log4Qt::ConsoleAppender::STDOUT_TARGET);
    appender->setImmediateFlush(true);
    // 設(shè)置閾值級(jí)別為INFO
    appender->setThreshold(Log4Qt::Level::INFO_INT);
    // 激活選項(xiàng)
    appender->activateOptions();
    logger->addAppender(appender);
    // 設(shè)置級(jí)別為 DEBUG
    logger->setLevel(Log4Qt::Level::DEBUG_INT);

    // 輸出信息
    logger->debug("你好, Log4Qt!");
    logger->info("你好, Qt!");

    // 關(guān)閉 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}
// output:
// 2018-03-12 18:03:48 [MainThread] INFO  root  - 你好, Qt!

五、FileAppender

1、FileAppender簡(jiǎn)介

FileAppender類繼承自WriterAppender類,用于將日志輸出到文件。
FileAppender的所有函數(shù)是線程安全的。

2、FileAppender日志重定向的實(shí)現(xiàn)

在FileAppender配置完成后,需要對(duì)其配置選項(xiàng)進(jìn)行激活,F(xiàn)ileAppender的activateOptions函數(shù)中會(huì)打開(kāi)指定的輸出文件,并將WriterAppender的文本流綁定到輸出文件的文件流,實(shí)現(xiàn)將WriterAppender的文本流重定向到輸出文件中。

void FileAppender::activateOptions()
{
    QMutexLocker locker(&mObjectGuard);

    if (mFileName.isEmpty())
    {
        LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of Appender '%1' that requires file and has no file set"),
                                         APPENDER_ACTIVATE_MISSING_FILE_ERROR);
        e << name();
        logger()->error(e);
        return;
    }
    closeFile();
    // 打開(kāi)文件
    openFile();
    WriterAppender::activateOptions();
}

void FileAppender::openFile()
{
    Q_ASSERT_X(mpFile == 0 && mpTextStream == 0, "FileAppender::openFile()", "Opening file without closing previous file");

    QFileInfo file_info(mFileName);
    QDir parent_dir = file_info.dir();
    if (!parent_dir.exists())
    {
        logger()->trace("Creating missing parent directory for file %1", mFileName);
        QString name = parent_dir.dirName();
        parent_dir.cdUp();
        parent_dir.mkdir(name);
    }

    mpFile = new QFile(mFileName);
    QFile::OpenMode mode = QIODevice::WriteOnly | QIODevice::Text;
    //配置文件流的寫(xiě)入模式
    if (mAppendFile)
        mode |= QIODevice::Append;
    else
        mode |= QIODevice::Truncate;
    if (!mBufferedIo)
        mode |= QIODevice::Unbuffered;
    if (!mpFile->open(mode))
    {
        LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to open file '%1' for appender '%2'"),
                                         APPENDER_OPENING_FILE_ERROR);
        e << mFileName << name();
        e.addCausingError(LogError(mpFile->errorString(), mpFile->error()));
        logger()->error(e);
        return;
    }
    // 將文件流綁定文本流
    mpTextStream = new QTextStream(mpFile);
    // 將WriterAppender的文本流重定向到文本文件的文件流對(duì)應(yīng)的文本流
    // 完成輸出目的地的重定向
    setWriter(mpTextStream);
    logger()->debug("Opened file '%1' for appender '%2'", mpFile->fileName(), name());
}

當(dāng)Logger進(jìn)行日志輸出時(shí),會(huì)在WriterAppender的append函數(shù)將格式化的日志信息輸出到文本流綁定的輸出文件中,完成輸出目的地的重定向。

3、FileAppender接口

bool appendFile() const;
獲取是否追加文件
QString file() const;
獲取輸出目的地的文件名
bool bufferedIo() const;
獲取是否為緩存IO
void setAppendFile(bool append);
設(shè)置是否為追加文件
void setBufferedIo(bool buffered);
設(shè)置是否為緩存IO
void setFile(const QString &rFileName);
設(shè)置輸出目的地的文件名
virtual void close();
關(guān)閉文件
4、FileAppender示例

#include <QCoreApplication>
#include <QTextCodec>
#include <log4qt/logger.h>
#include <log4qt/ttcclayout.h>
#include <log4qt/fileappender.h>.h>
#include <log4qt/loggerrepository.h>
#include <QThread>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QThread::currentThread()->setObjectName("MainThread");

    // 創(chuàng)建TTCCLayout
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
    layout->setDateFormat("yyyy-mm-dd hh:mm:ss");
    // 激活選項(xiàng)
    layout->activateOptions();

    // 創(chuàng)建ConsoleAppender
    Log4Qt::FileAppender *appender = new Log4Qt::FileAppender;
    // 設(shè)置輸出目的地為應(yīng)用程序所在目錄下的logFile.log
    appender->setFile("logFile.log");
    appender->setLayout(layout);
    // 設(shè)置編碼
    appender->setEncoding(QTextCodec::codecForName("UTF-8"));

    appender->setImmediateFlush(true);
    // 設(shè)置閾值級(jí)別為INFO
    appender->setThreshold(Log4Qt::Level::INFO_INT);
    // 激活選項(xiàng)
    appender->activateOptions();
    logger->addAppender(appender);
    // 設(shè)置級(jí)別為 DEBUG
    logger->setLevel(Log4Qt::Level::DEBUG_INT);

    // 輸出信息
    logger->debug("你好, Log4Qt!");
    logger->info("你好, Qt!");

    // 關(guān)閉 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}
// logFile:
// 2018-06-12 18:06:45 [MainThread] INFO  root  - 你好, Qt!

六、RollingFileAppender

1、RollingFileAppender簡(jiǎn)介

RollingFileAppender類繼承自FileAppender類,是對(duì)FileAppender功能的擴(kuò)展。RollingFileAppender允許輸出的日志文件達(dá)到指定大小時(shí)進(jìn)行日志文件的滾動(dòng)備份。
RollingFileAppender的所有函數(shù)都是線程安全的。

2、RollingFileAppender日志重定向的實(shí)現(xiàn)

在RollingFileAppender配置完成后,需要對(duì)其配置選項(xiàng)進(jìn)行激活,RollingFileAppender調(diào)用FileAppender::activateOptions函數(shù)中會(huì)中會(huì)打開(kāi)指定的輸出文件,并將WriterAppender的文本流綁定到輸出文件的文件流,實(shí)現(xiàn)將WriterAppender的文本流重定向到輸出文件中。
RollingFileAppender實(shí)現(xiàn)了append函數(shù)。

void RollingFileAppender::append(const LoggingEvent &rEvent)
{
    // Q_ASSERT_X(, "RollingFileAppender::append()", "Lock must be held by caller")
    // 使用FileAppender將輸出文件綁定到WidgetAppender的輸出文本流
    FileAppender::append(rEvent);
    // 如果日志文件大小已經(jīng)大于日志文件指定的最大值,進(jìn)行會(huì)滾備份操作
    if (writer()->device()->size() > this->mMaximumFileSize)
        rollOver();
}

當(dāng)Logger進(jìn)行日志輸出時(shí),RollingFileAppender使用FileAppender::append(實(shí)際為WriterAppender::append)函數(shù)將將格式化的日志信息輸出到文本流綁定的輸出文件中,完成輸出目的地的重定向。如果輸出文件的大小大于指定的最大值時(shí),進(jìn)行會(huì)滾備份操作。

3、RollingFileAppender接口

int maxBackupIndex() const;
獲取最大備份索引
qint64 maximumFileSize() const;
獲取輸出日志文件大小的最大值
void setMaxBackupIndex(int maxBackupIndex);
設(shè)置備份文件索引的最大值
void setMaximumFileSize(qint64 maximumFileSize);
設(shè)置單個(gè)輸出日志文件的最大值為maximumFileSize字節(jié)
void setMaxFileSize(const QString &rMaxFileSize);
設(shè)置單個(gè)輸出日志文件的最大值為rMaxFileSize的值,可以使用KB,MB,GB等單位

4、RollingFileAppender示例

#include <QCoreApplication>
#include <QTextCodec>
#include <log4qt/logger.h>
#include <log4qt/ttcclayout.h>
#include <log4qt/rollingfileappender.h>.h>.h>
#include <log4qt/loggerrepository.h>
#include <QThread>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QThread::currentThread()->setObjectName("MainThread");

    // 創(chuàng)建TTCCLayout
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
    layout->setDateFormat("yyyy-mm-dd hh:mm:ss");
    // 激活選項(xiàng)
    layout->activateOptions();

    // 創(chuàng)建ConsoleAppender
    Log4Qt::RollingFileAppender *appender = new Log4Qt::RollingFileAppender;
    // 設(shè)置輸出目的地為應(yīng)用程序所在目錄下的logFile.log
    appender->setFile("logFile.log");
    // 設(shè)置日志為追加方式寫(xiě)入輸出文件
    appender->setAppendFile(true);
    // 設(shè)置備份文件的最大數(shù)量為10個(gè)
    appender->setMaxBackupIndex(10);
    // 設(shè)置輸出文件的最大值為1KB
    appender->setMaxFileSize("1KB");
    appender->setLayout(layout);
    // 設(shè)置編碼
    appender->setEncoding(QTextCodec::codecForName("UTF-8"));

    appender->setImmediateFlush(true);
    // 設(shè)置閾值級(jí)別為INFO
    appender->setThreshold(Log4Qt::Level::INFO_INT);
    // 激活選項(xiàng)
    appender->activateOptions();
    logger->addAppender(appender);
    // 設(shè)置級(jí)別為 DEBUG
    logger->setLevel(Log4Qt::Level::DEBUG_INT);

    // 輸出信息
    for(int i = 0 ; i < 100; i++)
    {
        logger->debug("你好, Log4Qt!");
        logger->info("你好, Qt!");
    }

    // 關(guān)閉 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}

程序最近的日志輸出到logFile.log,并備份有5個(gè)文件,分別為logFile.log.1、logFile.log.2、logFile.log.3、logFile.log.4、logFile.log.5

七、DailyRollingFileAppender

1、DailyRollingFileAppender簡(jiǎn)介

DailyRollingFileAppender類繼承自FileAppender類,是對(duì)FileAppender功能的擴(kuò)展。DailyRollingFileAppender允許輸出的日志文件按照指定的頻率進(jìn)行會(huì)滾備份。
DailyRollingFileAppender的所有函數(shù)都是線程安全的。
DailyRollingFileAppender定義了六種日期模式。

enum DatePattern
{
    MINUTELY_ROLLOVER = 0,// 每分鐘,'yyyy-MM-dd-hh-mm"
    HOURLY_ROLLOVER,// 每小時(shí),yyyy-MM-dd-hh
    HALFDAILY_ROLLOVER,// 每半天,yyyy-MM-dd-a
    DAILY_ROLLOVER,// 每天,yyyy-MM-dd
    WEEKLY_ROLLOVER,// 每周,yyyy-ww
    MONTHLY_ROLLOVER// 每月,yyyy-MM
};

2、DailyRollingFileAppender日志重定向的實(shí)現(xiàn)

在DailyRollingFileAppender配置完成后,需要對(duì)其配置選項(xiàng)進(jìn)行激活,DailyRollingFileAppender的activateOptions函數(shù)中會(huì)計(jì)算輸出文件回滾的頻率,并調(diào)用FileAppender::activateOptions()函數(shù)將WriterAppender的文本流綁定到輸出文件的文件流,實(shí)現(xiàn)將WriterAppender的文本流重定向到輸出文件中。

void DailyRollingFileAppender::activateOptions()
{
    QMutexLocker locker(&mObjectGuard);
    // 計(jì)算輸出文件回滾的頻率,
    computeFrequency();
    if (!mActiveDatePattern.isEmpty())
    {
        //計(jì)算輸出文件回滾的時(shí)間
        computeRollOverTime();
        // 調(diào)用FileAppender::activateOptions重定向輸出文本流到輸出文件
        FileAppender::activateOptions();
    }
}

DailyRollingFileAppender實(shí)現(xiàn)了append函數(shù)。

void DailyRollingFileAppender::append(const LoggingEvent &rEvent)
{
    // 如果當(dāng)前時(shí)間大于輸出文件回滾時(shí)間,進(jìn)行輸出文件回滾
    if (QDateTime::currentDateTime() > mRollOverTime)
        rollOver();
    // 調(diào)用FileAppender::append將格式化的日志輸出到輸文件
    FileAppender::append(rEvent);
}

當(dāng)Logger進(jìn)行日志輸出時(shí),DailyRollingFileAppender會(huì)在append函數(shù)內(nèi)處理LoggingEvent對(duì)象。如果當(dāng)前時(shí)間大于輸出文件需要進(jìn)行回滾的時(shí)間,DailyRollingFileAppender會(huì)進(jìn)行輸出文件的回滾備份操作,創(chuàng)建新的日志輸出文件。然后調(diào)用FileAppender::append函數(shù)將格式化的日志輸出到指定的輸出文件中。

3、DailyRollingFileAppender接口

QString datePattern() const;
獲取日期匹配模式字符串
void setDatePattern(DatePattern datePattern);
設(shè)置日期匹配模式
void setDatePattern(const QString &rDatePattern);
設(shè)置rDatePattern為日期匹配模式

4、DailyRollingFileAppender示例

#include <QCoreApplication>
#include <QTextCodec>
#include <log4qt/logger.h>
#include <log4qt/ttcclayout.h>
#include <log4qt/dailyrollingfileappender.h>>
#include <log4qt/loggerrepository.h>
#include <QThread>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QThread::currentThread()->setObjectName("MainThread");

    // 創(chuàng)建TTCCLayout
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
    layout->setDateFormat("yyyy-mm-dd hh:mm:ss");
    // 激活選項(xiàng)
    layout->activateOptions();

    // 創(chuàng)建ConsoleAppender
    Log4Qt::DailyRollingFileAppender *appender = new Log4Qt::DailyRollingFileAppender;
    // 設(shè)置輸出目的地為應(yīng)用程序所在目錄下的logFile.log
    appender->setFile("logFile.log");
    // 設(shè)置日志文件每天回滾
    //appender->setDatePattern(Log4Qt::DailyRollingFileAppender::MINUTELY_ROLLOVER);
    appender->setDatePattern("'.'yyyy-MM-dd-hh-mm");
    // 設(shè)置日志為追加方式寫(xiě)入輸出文件
    appender->setAppendFile(true);
    appender->setLayout(layout);
    // 設(shè)置編碼
    appender->setEncoding(QTextCodec::codecForName("UTF-8"));

    appender->setImmediateFlush(true);
    // 設(shè)置閾值級(jí)別為INFO
    appender->setThreshold(Log4Qt::Level::INFO_INT);
    // 激活選項(xiàng)
    appender->activateOptions();
    logger->addAppender(appender);
    // 設(shè)置級(jí)別為 DEBUG
    logger->setLevel(Log4Qt::Level::DEBUG_INT);

    // 輸出信息
    for(int i = 0; i < 10; i++)
    {
        logger->debug("你好, Log4Qt!");
        logger->info("你好, Qt!");
        for(int i = 0; i < 1000000000; i++)
            ;
        logger->debug("你好, Log4Qt2!");
        logger->info("你好, Qt2!");
    }

    // 關(guān)閉 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}

程序執(zhí)行時(shí),日志輸出到logFile.log,輸出日志每分鐘會(huì)回滾備份一次,備份文件名稱如下:logFile.log.2018-10-12-18-30。

八、重定向日志到QWidget

1、Log4Qt源碼導(dǎo)入

將Log4Qt源碼工程下的src/log4qt目錄拷貝到自己的工程中,并在自己的工程文件中添加如下配置:

# 定義所需的宏
DEFINES += LOG4QT_LIBRARY

# 將Log4Qt源碼工程下的src/log4qt目錄拷貝到自己的工程src目錄中
# 定義Log4Qt源碼根目錄
LOG4QT_ROOT_PATH = $$PWD/log4qt

# 指定編譯項(xiàng)目時(shí)應(yīng)該被搜索的#include目錄
INCLUDEPATH += $$LOG4QT_ROOT_PATH

# 將Log4Qt源代碼添加至項(xiàng)目中
include($$LOG4QT_ROOT_PATH/log4qt.pri)

2、WidgetAppender實(shí)現(xiàn)

WidgetAppender從AppenderSkeleton進(jìn)行實(shí)現(xiàn)。
WidgetAppender.h文件:

#ifndef WIDGETAPPENDER_H
#define WIDGETAPPENDER_H

#include <QObject>
#include <QWidget>
#include "appenderskeleton.h"
#include <QDebug>

namespace Log4Qt
{
/**
 * @brief WidgetAppender繼承自AppenderSkeleton類,用于將日志信息重定向到QWidget組件
 * @author scorpio
 * @note WidgetAppender的使用注意事項(xiàng):
 *      1、必須使用setLogWidget接口設(shè)置日志信息的重定向位置,即輸出窗口組件
 *      2、必須實(shí)現(xiàn)一個(gè)槽函數(shù)onAppendLog(const QString& msg),用于接收WidgetAppender
 *      發(fā)送的logAppend(const QString& msg)信號(hào),參數(shù)msg即接收的日志信息,輸出窗口組件
 *      需要將msg輸出到相應(yīng)窗體。
 */
class WidgetAppender : public AppenderSkeleton
{
    Q_OBJECT
public:
    WidgetAppender(QObject *parent = NULL);
    ~WidgetAppender();
    /**
     * @brief 設(shè)置日志信息輸出的QWidget組件
     * @param widget,輸入?yún)?shù),日志信息輸出窗口,需要開(kāi)發(fā)者自己實(shí)現(xiàn)
     */
    void setLogWidget(const QWidget& widget);

signals:
    /**
     * @brief 新增加一條日志信息的信號(hào)
     * @param msg,輸入?yún)?shù),格式化后的日志信息
     * @note logAppend信號(hào)由QWidget輸出窗口組件接收,開(kāi)發(fā)者需要在輸出窗口組件實(shí)現(xiàn)
     *      槽函數(shù)onAppendLog(const QString& msg)。
     */
    void logAppend(const QString& msg);
protected:
    virtual bool requiresLayout() const;
    virtual void append(const Log4Qt::LoggingEvent &rEvent);

#ifndef QT_NO_DEBUG_STREAM
    virtual QDebug debug(QDebug &rDebug) const;
#endif //QT_NO_DEBUG_STREAM

private:
    QWidget *m_logWidget;
};

}
#endif // WIDGETAPPENDER_H

WidgetAppender.cpp文件:

#include "WidgetAppender.h"
#include "loggingevent.h"
#include <log4qt/ttcclayout.h>

namespace Log4Qt
{

WidgetAppender::WidgetAppender(QObject *parent): AppenderSkeleton(parent)
{
    m_logWidget = NULL;
}

WidgetAppender::~WidgetAppender()
{

}

void WidgetAppender::setLogWidget(const QWidget &widget)
{
    m_logWidget = const_cast<QWidget*>(&widget);
    //連接槽函數(shù)到輸出窗口的onAppendLog(const QString&)槽函數(shù)
    connect(this, SIGNAL(logAppend(const QString&)), m_logWidget, SLOT(onAppendLog(const QString&)));

}

bool WidgetAppender::requiresLayout() const
{
    return true;
}

void WidgetAppender::append(const LoggingEvent &rEvent)
{
    // 格式化日志信息
    QString message = dynamic_cast<TTCCLayout*>(layout())->format(rEvent);
    emit logAppend(message);
}
#ifndef QT_NO_DEBUG_STREAM
QDebug WidgetAppender::debug(QDebug &rDebug) const
{
    return rDebug.space();
}
#endif //QT_NO_DEBUG_STREAM

}

3、QWidget輸出窗口實(shí)現(xiàn)

Widget.h文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTextEdit>
#include <QMutex>
#include <QVBoxLayout>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    /**
     * @brief 接收日志信息的槽函數(shù)
     * @param log,輸入?yún)?shù),格式化后的日志信息
     */
    void onAppendLog(const QString& log);

private:
    QTextEdit* m_logEdit;
    QMutex m_mutex;
};

#endif // WIDGET_H

Widget.cpp文件:

#include "Widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    m_logEdit = new QTextEdit();
    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(m_logEdit);
    setLayout(layout);
    resize(600, 400);
}

Widget::~Widget()
{

}

void Widget::onAppendLog(const QString &log)
{
    QMutexLocker lock(&m_mutex);
    //將日志信息輸出到窗口組件
    m_logEdit->insertPlainText(log);
}

4、應(yīng)用示例

#include "Widget.h"
#include <QApplication>
#include <log4qt/basicconfigurator.h>
#include <log4qt/logger.h>
#include <log4qt/WidgetAppender.h>
#include <log4qt/ttcclayout.h>
#include <log4qt/logmanager.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    Log4Qt::BasicConfigurator::configure();
    Log4Qt::LogManager::setHandleQtMessages(true);
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    logger->removeAllAppenders();
    Log4Qt::WidgetAppender *appender = new Log4Qt::WidgetAppender();
    appender->setName("WidgetAppender");
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout(Log4Qt::TTCCLayout::ISO8601);
    layout->setThreadPrinting(true);
    appender->setLayout(layout);
    appender->activateOptions();
    //設(shè)置日志信息輸出的窗口組件
    appender->setLogWidget(w);
    logger->addAppender(appender);

    logger->warn("hello Log4Qt");
    logger->info("hello Log4Qt");
    logger->debug("hello Log4Qt");
    logger->info("你好 Log4Qt");

    logger->removeAllAppenders();
    return a.exec();
}
// output:
// 2018-10-09 10:27:18.542 [] WARN  root  - hello Log4Qt
// 2018-10-09 10:27:18.542 [] INFO  root  - hello Log4Qt
// 2018-10-09 10:27:18.542 [] DEBUG root  - hello Log4Qt
// 2018-10-09 10:27:18.542 [] INFO  root  - 你好 Log4Qt

本文標(biāo)題:Log4Qt快速入門(mén)——Log4Qt日志輸出重定向源碼解析
本文地址:http://chinadenli.net/article46/gidheg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、搜索引擎優(yōu)化關(guān)鍵詞優(yōu)化、建站公司移動(dòng)網(wǎng)站建設(shè)、面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)