Log4Qt快速入门——Log4Qt日志输出重定向源码解析

栏目: 编程工具 · 发布时间: 7年前

内容简介:AppenderSkeleton继承自Appender类,实现了Appender的通用功能,但没有实现继承自Appender的部分接口,所以仍然是一个抽象类,不能实例化。AppenderSkeleton的所有函数都是线程安全的。自定义Appender可以从AppenderSkeleton派生,须要实现以下三个接口:append接口负责处理LoggingEvent对象,将格式化的日志信息输出到不同的输出地,如文本流、文件流、数据库等,如果需要将日志信息重定向到QWidget组件,需要在append函数发送信

Log4Qt快速入门——Log4Qt日志输出重定向源码解析

一、Appender简介

1、Appender简介

Appender是所有Appender的抽象类,是对记录日志形式的抽象。Log4Qt(Qt4版本)中Appender继承体系如下:

Log4Qt快速入门——Log4Qt日志输出重定向源码解析

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简介

AppenderSkeleton继承自Appender类,实现了Appender的通用功能,但没有实现继承自Appender的部分接口,所以仍然是一个抽象类,不能实例化。AppenderSkeleton的所有函数都是线程安全的。

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派生,须要实现以下三个接口:

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

append接口负责处理LoggingEvent对象,将格式化的日志信息输出到不同的输出地,如文本流、文件流、数据库等,如果需要将日志信息重定向到QWidget组件,需要在append函数发送信号,日志信息作为信号参数,在相应的QWidget组件的槽函数接收处理日志信息。

也可以根据需要从WriterAppender、ConsoleAppender、

FileAppender、RollingFileAppender、DailyRollingFileAppender派生类进行实现。

三、WriterAppender

1、WriterAppender简介

WriterAppender类继承自AppenderSkeleton类,在其实现的append函数中会将LoggingEvent对象的日志信息输出到QTextStream对象。WriterAppender的所有函数是线程安全的。

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

2、WriterAppender常用接口

QTextCodec *encoding() const;

获取输出文本流的编码器

bool immediateFlush() const;

获取是否立即刷新

QTextStream *writer() const;

获取输出文本流对象

void setEncoding(QTextCodec *pTextCodec);

设置文本流的编码器

void setImmediateFlush(bool immediateFlush);

设置是否立即刷新

void setWriter(QTextStream *pTextStream);

设置输出文本流

virtual void close();

关闭文本流,如果有设置页脚,会打印出页脚信息

四、ConsoleAppender

1、ConsoleAppender简介

ConsoleAppender类继承自WriterAppender类,ConsoleAppender定义了标准输出、标准错误两种控制台的输出目的地。ConsoleAppender的所有函数是线程安全的。

enum Target
{
    STDOUT_TARGET,//标准输出
    STDERR_TARGET//标准错误
};

2、ConsoleAppender日志重定向的实现

在ConsoleAppender配置完成后,需要对其配置选项进行激活,ConsoleAppender的activateOptions函数中会将文本流指向相应控制台的文本流对象。

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

    if (mTarget == STDOUT_TARGET)
        mpTextStream = new QTextStream(stdout);
    else
        mpTextStream = new QTextStream(stderr);
    // 调用WriterAppender的setWriter函数,
    // 将日志信息重定向到控制台对应的文本流
    setWriter(mpTextStream);

    WriterAppender::activateOptions();
}

当Logger进行日志输出时,会在WriterAppender的append函数将格式化的日志信息输出到相应控制台对应的文本流,完成输出目的地的重定向。

3、ConsoleAppender常用接口

QString target() const;

获取输出目的地

void setTarget(const QString &rTarget);

设置rTarget字符串为输出目的地

void setTarget(Target target);

设置target为输出目的地

virtual void activateOptions();

激活ConsoleAppender设置的选项

virtual void close();

关闭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");

    // 创建TTCCLayout
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
    layout->setDateFormat("yyyy-mm-dd hh:mm:ss");
    // 激活选项
    layout->activateOptions();

    // 创建ConsoleAppender
    Log4Qt::ConsoleAppender *appender = new Log4Qt::ConsoleAppender();
    appender->setLayout(layout);
    // 设置编码
    appender->setEncoding(QTextCodec::codecForName("UTF-8"));
    // 设置输出目的地为stdout
    appender->setTarget(Log4Qt::ConsoleAppender::STDOUT_TARGET);
    appender->setImmediateFlush(true);
    // 设置阈值级别为INFO
    appender->setThreshold(Log4Qt::Level::INFO_INT);
    // 激活选项
    appender->activateOptions();
    logger->addAppender(appender);
    // 设置级别为 DEBUG
    logger->setLevel(Log4Qt::Level::DEBUG_INT);

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

    // 关闭 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

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

五、FileAppender

1、FileAppender简介

FileAppender类继承自WriterAppender类,用于将日志输出到文件。

FileAppender的所有函数是线程安全的。

2、FileAppender日志重定向的实现

在FileAppender配置完成后,需要对其配置选项进行激活,FileAppender的activateOptions函数中会打开指定的输出文件,并将WriterAppender的文本流绑定到输出文件的文件流,实现将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();
    // 打开文件
    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;
    //配置文件流的写入模式
    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的文本流重定向到文本文件的文件流对应的文本流
    // 完成输出目的地的重定向
    setWriter(mpTextStream);
    logger()->debug("Opened file '%1' for appender '%2'", mpFile->fileName(), name());
}

当Logger进行日志输出时,会在WriterAppender的append函数将格式化的日志信息输出到文本流绑定的输出文件中,完成输出目的地的重定向。

3、FileAppender接口

bool appendFile() const;

获取是否追加文件

QString file() const;

获取输出目的地的文件名

bool bufferedIo() const;

获取是否为缓存IO

void setAppendFile(bool append);

设置是否为追加文件

void setBufferedIo(bool buffered);

设置是否为缓存IO

void setFile(const QString &rFileName);

设置输出目的地的文件名

virtual void close();

关闭文件

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");

    // 创建TTCCLayout
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
    layout->setDateFormat("yyyy-mm-dd hh:mm:ss");
    // 激活选项
    layout->activateOptions();

    // 创建ConsoleAppender
    Log4Qt::FileAppender *appender = new Log4Qt::FileAppender;
    // 设置输出目的地为应用程序所在目录下的logFile.log
    appender->setFile("logFile.log");
    appender->setLayout(layout);
    // 设置编码
    appender->setEncoding(QTextCodec::codecForName("UTF-8"));

    appender->setImmediateFlush(true);
    // 设置阈值级别为INFO
    appender->setThreshold(Log4Qt::Level::INFO_INT);
    // 激活选项
    appender->activateOptions();
    logger->addAppender(appender);
    // 设置级别为 DEBUG
    logger->setLevel(Log4Qt::Level::DEBUG_INT);

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

    // 关闭 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

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

六、RollingFileAppender

1、RollingFileAppender简介

RollingFileAppender类继承自FileAppender类,是对FileAppender功能的扩展。RollingFileAppender允许输出的日志文件达到指定大小时进行日志文件的滚动备份。

RollingFileAppender的所有函数都是线程安全的。

2、RollingFileAppender日志重定向的实现

在RollingFileAppender配置完成后,需要对其配置选项进行激活,RollingFileAppender调用FileAppender::activateOptions函数中会中会打开指定的输出文件,并将WriterAppender的文本流绑定到输出文件的文件流,实现将WriterAppender的文本流重定向到输出文件中。

RollingFileAppender实现了append函数。

void RollingFileAppender::append(const LoggingEvent &rEvent)
{
    // Q_ASSERT_X(, "RollingFileAppender::append()", "Lock must be held by caller")
    // 使用FileAppender将输出文件绑定到WidgetAppender的输出文本流
    FileAppender::append(rEvent);
    // 如果日志文件大小已经大于日志文件指定的最大值,进行会滚备份操作
    if (writer()->device()->size() > this->mMaximumFileSize)
        rollOver();
}

当Logger进行日志输出时,RollingFileAppender使用FileAppender::append(实际为WriterAppender::append)函数将将格式化的日志信息输出到文本流绑定的输出文件中,完成输出目的地的重定向。如果输出文件的大小大于指定的最大值时,进行会滚备份操作。

3、RollingFileAppender接口

int maxBackupIndex() const;

获取最大备份索引

qint64 maximumFileSize() const;

获取输出日志文件大小的最大值

void setMaxBackupIndex(int maxBackupIndex);

设置备份文件索引的最大值

void setMaximumFileSize(qint64 maximumFileSize);

设置单个输出日志文件的最大值为maximumFileSize字节

void setMaxFileSize(const QString &rMaxFileSize);

设置单个输出日志文件的最大值为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");

    // 创建TTCCLayout
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
    layout->setDateFormat("yyyy-mm-dd hh:mm:ss");
    // 激活选项
    layout->activateOptions();

    // 创建ConsoleAppender
    Log4Qt::RollingFileAppender *appender = new Log4Qt::RollingFileAppender;
    // 设置输出目的地为应用程序所在目录下的logFile.log
    appender->setFile("logFile.log");
    // 设置日志为追加方式写入输出文件
    appender->setAppendFile(true);
    // 设置备份文件的最大数量为10个
    appender->setMaxBackupIndex(10);
    // 设置输出文件的最大值为1KB
    appender->setMaxFileSize("1KB");
    appender->setLayout(layout);
    // 设置编码
    appender->setEncoding(QTextCodec::codecForName("UTF-8"));

    appender->setImmediateFlush(true);
    // 设置阈值级别为INFO
    appender->setThreshold(Log4Qt::Level::INFO_INT);
    // 激活选项
    appender->activateOptions();
    logger->addAppender(appender);
    // 设置级别为 DEBUG
    logger->setLevel(Log4Qt::Level::DEBUG_INT);

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

    // 关闭 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}

程序最近的日志输出到logFile.log,并备份有5个文件,分别为logFile.log.1、logFile.log.2、logFile.log.3、logFile.log.4、logFile.log.5

七、DailyRollingFileAppender

1、DailyRollingFileAppender简介

DailyRollingFileAppender类继承自FileAppender类,是对FileAppender功能的扩展。DailyRollingFileAppender允许输出的日志文件按照指定的频率进行会滚备份。

DailyRollingFileAppender的所有函数都是线程安全的。

DailyRollingFileAppender定义了六种日期模式。

enum DatePattern
{
    MINUTELY_ROLLOVER = 0,// 每分钟,'yyyy-MM-dd-hh-mm"
    HOURLY_ROLLOVER,// 每小时,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日志重定向的实现

在DailyRollingFileAppender配置完成后,需要对其配置选项进行激活,DailyRollingFileAppender的activateOptions函数中会计算输出文件回滚的频率,并调用FileAppender::activateOptions()函数将WriterAppender的文本流绑定到输出文件的文件流,实现将WriterAppender的文本流重定向到输出文件中。

void DailyRollingFileAppender::activateOptions()
{
    QMutexLocker locker(&mObjectGuard);
    // 计算输出文件回滚的频率,
    computeFrequency();
    if (!mActiveDatePattern.isEmpty())
    {
        //计算输出文件回滚的时间
        computeRollOverTime();
        // 调用FileAppender::activateOptions重定向输出文本流到输出文件
        FileAppender::activateOptions();
    }
}

DailyRollingFileAppender实现了append函数。

void DailyRollingFileAppender::append(const LoggingEvent &rEvent)
{
    // 如果当前时间大于输出文件回滚时间,进行输出文件回滚
    if (QDateTime::currentDateTime() > mRollOverTime)
        rollOver();
    // 调用FileAppender::append将格式化的日志输出到输文件
    FileAppender::append(rEvent);
}

当Logger进行日志输出时,DailyRollingFileAppender会在append函数内处理LoggingEvent对象。如果当前时间大于输出文件需要进行回滚的时间,DailyRollingFileAppender会进行输出文件的回滚备份操作,创建新的日志输出文件。然后调用FileAppender::append函数将格式化的日志输出到指定的输出文件中。

3、DailyRollingFileAppender接口

QString datePattern() const;

获取日期匹配模式字符串

void setDatePattern(DatePattern datePattern);

设置日期匹配模式

void setDatePattern(const QString &rDatePattern);

设置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");

    // 创建TTCCLayout
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
    layout->setDateFormat("yyyy-mm-dd hh:mm:ss");
    // 激活选项
    layout->activateOptions();

    // 创建ConsoleAppender
    Log4Qt::DailyRollingFileAppender *appender = new Log4Qt::DailyRollingFileAppender;
    // 设置输出目的地为应用程序所在目录下的logFile.log
    appender->setFile("logFile.log");
    // 设置日志文件每天回滚
    //appender->setDatePattern(Log4Qt::DailyRollingFileAppender::MINUTELY_ROLLOVER);
    appender->setDatePattern("'.'yyyy-MM-dd-hh-mm");
    // 设置日志为追加方式写入输出文件
    appender->setAppendFile(true);
    appender->setLayout(layout);
    // 设置编码
    appender->setEncoding(QTextCodec::codecForName("UTF-8"));

    appender->setImmediateFlush(true);
    // 设置阈值级别为INFO
    appender->setThreshold(Log4Qt::Level::INFO_INT);
    // 激活选项
    appender->activateOptions();
    logger->addAppender(appender);
    // 设置级别为 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!");
    }

    // 关闭 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}

程序执行时,日志输出到logFile.log,输出日志每分钟会回滚备份一次,备份文件名称如下:logFile.log.2018-10-12-18-30。

八、重定向日志到QWidget

1、Log4Qt源码导入

将Log4Qt源码工程下的src/log4qt目录拷贝到自己的工程中,并在自己的工程文件中添加如下配置:

# 定义所需的宏
DEFINES += LOG4QT_LIBRARY

# 将Log4Qt源码工程下的src/log4qt目录拷贝到自己的工程src目录中
# 定义Log4Qt源码根目录
LOG4QT_ROOT_PATH = $$PWD/log4qt

# 指定编译项目时应该被搜索的#include目录
INCLUDEPATH += $$LOG4QT_ROOT_PATH

# 将Log4Qt源代码添加至项目中
include($$LOG4QT_ROOT_PATH/log4qt.pri)

2、WidgetAppender实现

WidgetAppender从AppenderSkeleton进行实现。

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的使用注意事项:
 *      1、必须使用setLogWidget接口设置日志信息的重定向位置,即输出窗口组件
 *      2、必须实现一个槽函数onAppendLog(const QString& msg),用于接收WidgetAppender
 *      发送的logAppend(const QString& msg)信号,参数msg即接收的日志信息,输出窗口组件
 *      需要将msg输出到相应窗体。
 */
class WidgetAppender : public AppenderSkeleton
{
    Q_OBJECT
public:
    WidgetAppender(QObject *parent = NULL);
    ~WidgetAppender();
    /**
     * @brief 设置日志信息输出的QWidget组件
     * @param widget,输入参数,日志信息输出窗口,需要开发者自己实现
     */
    void setLogWidget(const QWidget& widget);

signals:
    /**
     * @brief 新增加一条日志信息的信号
     * @param msg,输入参数,格式化后的日志信息
     * @note logAppend信号由QWidget输出窗口组件接收,开发者需要在输出窗口组件实现
     *      槽函数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);
    //连接槽函数到输出窗口的onAppendLog(const QString&)槽函数
    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输出窗口实现

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 接收日志信息的槽函数
     * @param log,输入参数,格式化后的日志信息
     */
    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、应用示例

#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();
    //设置日志信息输出的窗口组件
    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

以上所述就是小编给大家介绍的《Log4Qt快速入门——Log4Qt日志输出重定向源码解析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro JavaScript Design Patterns

Pro JavaScript Design Patterns

Dustin Diaz、Ross Harmes / Apress / 2007-12-16 / USD 44.99

As a web developer, you’ll already know that JavaScript™ is a powerful language, allowing you to add an impressive array of dynamic functionality to otherwise static web sites. But there is more power......一起来看看 《Pro JavaScript Design Patterns》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具