个人技术分享

Log4Qt日志框架 - 日志格式化(02)icon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/138417616?spm=1011.2266.3001.6217

一、Log4Qt输出重定向

Log4Qt继承关系图

  1. AppenderSkeleton:实现一般的功能
  2. DebugAppender:将日志附加到平台调试(Window-stdout或Linux-stdrr)
  3. ListAppender:将日志追加到列表
  4. NullAppender:忽略所有附加请求
  5. WriteAppender:将日志附加到QTextStream
    1. ConsoleAppender:附加到stdout或stdrr
    2. FileAppender:将日志信息附加到文件
    3. DailRollingFileAppender:以指定频率滚动日志文件
    4. RollingFileAppender:以达到指定大小时滚动日志文件

1、输出到控制台

#include "log4qt/logger.h"
#include "log4qt/logmanager.h"
#include "log4qt/fileappender.h"
#include "log4qt/loggerrepository.h"
#include "log4qt/patternlayout.h"
#include "log4qt/consoleappender.h"
#include "log4qt/simplelayout.h"
#include "log4qt/ttcclayout.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

#if 1
	// 创建一个 TTCCLayout(输出时间、线程、Logger 以及消息内容)
	Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
	Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
	layout->setName("My Layout");
	layout->activateOptions();

	// 创建一个 ConsoleAppender(将日志内容输出到控制台上)
	Log4Qt::ConsoleAppender *appender = new Log4Qt::ConsoleAppender(layout, Log4Qt::ConsoleAppender::STDOUT_TARGET);
	appender->setName("My Appender");
	appender->activateOptions();
	// 在 logger 上添加 appender
	logger->addAppender(appender);

	// 设置级别为 DEBUG
	logger->setLevel(Log4Qt::Level::DEBUG_INT);

	// 输出信息
	logger->debug("Hello, Log4Qt!");

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

    return a.exec();
}

2、输出到文件

#include "log4qt/logger.h"
#include "log4qt/logmanager.h"
#include "log4qt/fileappender.h"
#include "log4qt/loggerrepository.h"
#include "log4qt/patternlayout.h"
#include "log4qt/consoleappender.h"
#include "log4qt/simplelayout.h"
#include "log4qt/ttcclayout.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

#if 1
	// 创建一个 TTCCLayout(输出时间、线程、Logger 以及消息内容)
	Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
	Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
	layout->setName("My Layout");
	layout->activateOptions();

	// 创建一个 FileAppender(将日志内容输出到文件中)
	QString file = QCoreApplication::applicationDirPath() + "/Logs/out.log";
	Log4Qt::FileAppender *appender = new Log4Qt::FileAppender(layout, file, true);//true:append,false:truncate
	appender->setName("My Appender");
	appender->activateOptions();
	// 在 logger 上添加 appender
	logger->addAppender(appender);

	// 设置级别为 DEBUG
	logger->setLevel(Log4Qt::Level::DEBUG_INT);

	// 输出信息
	logger->debug("Hello, Log4Qt!");

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

    return a.exec();
}

3、以指定频率滚动日志文件

DatePattern参数描述
枚举 模式字符串 描述
MINUTELY_ROLLOVER "'.'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" 每月

 注:单引号内的内容不会被处理,如:'.'

#include <qdir.h>
#include <qdebug.h>
#include <qthread.h>

#include "log4qt/logger.h"
#include "log4qt/logmanager.h"
#include "log4qt/fileappender.h"
#include "log4qt/loggerrepository.h"
#include "log4qt/patternlayout.h"
#include "log4qt/consoleappender.h"
#include "log4qt/simplelayout.h"
#include "log4qt/ttcclayout.h"
#include "log4qt/dailyrollingfileappender.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

#if 1
	qDebug() << "********** Begin **********";

	// 使用 rootLogger 打印日志
	Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();

	// 创建一个 TTCCLayout(输出时间、线程、Logger 以及消息内容)
	Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
	layout->setName("My Layout");
	layout->activateOptions();

	// 创建一个 DailyRollingFileAppender(以指定的频率滚动)
	Log4Qt::DailyRollingFileAppender *appender = new Log4Qt::DailyRollingFileAppender();
	appender->setName("My Appender");
	appender->setLayout(layout);
	appender->setFile(QCoreApplication::applicationDirPath() + "Logs/log.out");
	appender->setImmediateFlush(true);  // 立即刷新
	appender->setThreshold(Log4Qt::Level::INFO_INT);  // 设置阈值级别为 INFO
	appender->setAppendFile(true);  // 追加的方式
	appender->setDatePattern(Log4Qt::DailyRollingFileAppender::MINUTELY_ROLLOVER); // 日期模式
	appender->activateOptions();

	// 在 logger 上添加 appender
	logger->addAppender(appender);

	// 设置级别为 DEBUG
	logger->setLevel(Log4Qt::Level::DEBUG_INT);

	int count = 0;
	while (count < 10) {
		// 输出信息
		logger->info("Hello, Log4Qt!");
		QThread::sleep(30);
		++count;
	}

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

	qDebug() << "********** End **********";
#endif

    return a.exec();
}

4、以达到指定大小时滚动文件

#include <qdir.h>
#include <qdebug.h>
#include <qthread.h>

#include "log4qt/logger.h"
#include "log4qt/logmanager.h"
#include "log4qt/fileappender.h"
#include "log4qt/loggerrepository.h"
#include "log4qt/patternlayout.h"
#include "log4qt/consoleappender.h"
#include "log4qt/simplelayout.h"
#include "log4qt/ttcclayout.h"
#include "log4qt/dailyrollingfileappender.h"
#include "log4qt/rollingfileappender.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

#if 1
	qDebug() << "********** Begin **********";

	// 使用 rootLogger 打印日志
	Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();

	// 创建一个 TTCCLayout(输出时间、线程、Logger 以及消息内容)
	Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
	layout->setName("My Layout");
	layout->activateOptions();

	// 创建一个 RollingFileAppender(滚动多个文件)
	Log4Qt::RollingFileAppender *appender = new Log4Qt::RollingFileAppender();
	appender->setName("My Appender");
	appender->setLayout(layout);
	appender->setFile(QCoreApplication::applicationDirPath() + "/Logs/log.out");
	appender->setImmediateFlush(true);  // 立即刷新
	appender->setThreshold(Log4Qt::Level::INFO_INT);  // 设置阈值级别为 INFO
	appender->setAppendFile(true);  // 追加的方式
	// 等价于 appender->setMaximumFileSize(10 * 1024);
	appender->setMaxFileSize("10KB"); // 在滚动之前设置文件的最大大小
	appender->setMaxBackupIndex(5);  // 设置备份索引
	appender->activateOptions();

	// 在 logger 上添加 appender
	logger->addAppender(appender);

	// 设置级别为 DEBUG
	logger->setLevel(Log4Qt::Level::DEBUG_INT);

	for (int i = 0; i < 1000; i++)
	{
		logger->info("write RollingFileAppender info to file");
	}
	
	// 关闭 logger
	logger->removeAllAppenders();
	logger->loggerRepository()->shutdown();

	qDebug() << "********** End **********";
#endif

    return a.exec();
}

5、输出到界面

        5.1直接输出到界面

============================LogSystem.h===========================
#pragma once

#include <QtWidgets/QWidget>
#include "ui_LogSystem.h"

#include "Common.h"
#include "LogTextBrowserAppender.h"

#define LOG_DEBUG(s)		showMessage(s, Log4Qt::Level::DEBUG_INT);
#define LOG_WARN(s)		showMessage(s, Log4Qt::Level::WARN_INT);
#define LOG_ERROR(s)		showMessage(s, Log4Qt::Level::ERROR_INT);
#define LOG_FATAL(s)		showMessage(s, Log4Qt::Level::FATAL_INT);
#define LOG_INFO(s)		showMessage(s, Log4Qt::Level::INFO_INT);

class LogSystem : public QWidget
{
    Q_OBJECT
	LOG4QT_DECLARE_QCLASS_LOGGER

public:
    LogSystem(QWidget *parent = nullptr);
    ~LogSystem();

public:
	void showMessage(QString message, Log4Qt::Level::Value level = Log4Qt::Level::ALL_INT);

private:
    Ui::LogSystemClass ui;
};

============================LogSystem.cpp=========================
#include "LogSystem.h"
#include "CustomTextBrowser.h"

LogSystem::LogSystem(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

	logger()->setLevel(Log4Qt::Level::ALL_INT);//设置日志显示级别
}

LogSystem::~LogSystem()
{}

void LogSystem::showMessage(QString message, Log4Qt::Level::Value level)
{
    ui.textBrowser_log->append(message);
	logger()->debug(message);

}

============================main.cpp============================
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

	// 一个简单的基础配置
	Log4Qt::BasicConfigurator::configure();

    LogSystem w;
    w.show();
    
    LOG_DEBUG("debug message")
    
    return a.exec();
}

        5.2继承Log4Qt::AppenderSkeleton,重写append-同步

 重写Log4Qt::AppenderSkeleton类

===============================LogTextBrowserAppender.h============================
#pragma once

#include "Common.h"
#include "log4qt/spi/filter.h"

class LogTextBrowserAppender :
	public Log4Qt::AppenderSkeleton
{
	Q_OBJECT

public:
	LogTextBrowserAppender(QObject* parent, QTextBrowser* browser);
	~LogTextBrowserAppender();

protected:
	virtual bool requiresLayout() const;
	virtual void append(const Log4Qt::LoggingEvent &event);

private:
	QTextBrowser* m_textBrowser;
	QMutex m_textBrowserMutex;
};

===============================LogTextBrowserAppender.cpp==========================

#include "LogTextBrowserAppender.h"

LogTextBrowserAppender::LogTextBrowserAppender(QObject* parent, QTextBrowser * browser)
	: Log4Qt::AppenderSkeleton(parent), m_textBrowser(browser)
{
}

LogTextBrowserAppender::~LogTextBrowserAppender()
{
}

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

void LogTextBrowserAppender::append(const Log4Qt::LoggingEvent & event)
{
	if (m_textBrowser)
	{
        QMutexLocker locker(&m_textBrowserMutex);
		QString message = layout()->format(event);
		m_textBrowser->append(message);
	}
}

LogSystem类

============================LogSystem.h===========================
#pragma once

#include <QtWidgets/QWidget>
#include "ui_LogSystem.h"

#include "Common.h"
#include "LogTextBrowserAppender.h"

#define LOG_DEBUG(s)		showMessage(s, Log4Qt::Level::DEBUG_INT);
#define LOG_WARN(s)		showMessage(s, Log4Qt::Level::WARN_INT);
#define LOG_ERROR(s)		showMessage(s, Log4Qt::Level::ERROR_INT);
#define LOG_FATAL(s)		showMessage(s, Log4Qt::Level::FATAL_INT);
#define LOG_INFO(s)		showMessage(s, Log4Qt::Level::INFO_INT);

class LogSystem : public QWidget
{
    Q_OBJECT
	LOG4QT_DECLARE_QCLASS_LOGGER

public:
    LogSystem(QWidget *parent = nullptr);
    ~LogSystem();

public:
	void showMessage(QString message, Log4Qt::Level::Value level = Log4Qt::Level::ALL_INT);

private:
    Ui::LogSystemClass ui;
};

============================LogSystem.cpp=========================
#include "LogSystem.h"

LogSystem::LogSystem(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

	logger()->setLevel(Log4Qt::Level::ALL_INT);//设置日志显示级别

    //输出日志信息到界面	
	Log4Qt::PatternLayout* layout = new Log4Qt::PatternLayout();
	layout->setConversionPattern(Log4Qt::PatternLayout::TTCC_CONVERSION_PATTERN);

	LogTextBrowserAppender* logTextBrowserAppender = new LogTextBrowserAppender(this, ui.textBrowser);
	logTextBrowserAppender->setLayout(layout);
	logger()->addAppender(logTextBrowserAppender);
	logger()->setAdditivity(false);

	logger()->debug("This is a debug message.");
}

LogSystem::~LogSystem()
{}

void LogSystem::showMessage(QString message, Log4Qt::Level::Value level)
{
    ui.textBrowser_log->append(message);
	logger()->debug(message);

}

============================main.cpp============================
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

	// 一个简单的基础配置
	Log4Qt::BasicConfigurator::configure();

    LogSystem w;
    w.show();
    
    LOG_DEBUG("debug message")
    
    return a.exec();
}

        5.3继承Log4Qt::AppenderSkeleton,重写append-异步  

 重写Log4Qt::AppenderSkeleton类

===============================LogTextBrowserAppender.h============================
#pragma once

#include "Common.h"
#include "log4qt/spi/filter.h"

class LogTextBrowserAppender :
	public Log4Qt::AppenderSkeleton
{
	Q_OBJECT

public:
	LogTextBrowserAppender(QObject* parent, QTextBrowser* browser);
	~LogTextBrowserAppender();

protected:
	virtual bool requiresLayout() const;
	virtual void append(const Log4Qt::LoggingEvent &event);

private:
	QTextBrowser* m_textBrowser;
	QMutex m_textBrowserMutex;
};

===============================LogTextBrowserAppender.cpp==========================

#include "LogTextBrowserAppender.h"

LogTextBrowserAppender::LogTextBrowserAppender(QObject* parent, QTextBrowser * browser)
	: Log4Qt::AppenderSkeleton(parent), m_textBrowser(browser)
{
}

LogTextBrowserAppender::~LogTextBrowserAppender()
{
}

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

void LogTextBrowserAppender::append(const Log4Qt::LoggingEvent & event)
{
	if (m_textBrowser)
	{
		QString message = layout()->format(event);
		//该函数将日志信息发送至自定义界面类的槽函数中
		QMetaObject::invokeMethod(m_textBrowser, "slotShowMessage", Qt::QueuedConnection, Q_ARG(QString, message));
	
	}
}

LogSystem类

============================LogSystem.h===========================
#pragma once

#include <QtWidgets/QWidget>
#include "ui_LogSystem.h"

#include "Common.h"
#include "LogTextBrowserAppender.h"

#define LOG_DEBUG(s)		showMessage(s, Log4Qt::Level::DEBUG_INT);
#define LOG_WARN(s)		showMessage(s, Log4Qt::Level::WARN_INT);
#define LOG_ERROR(s)		showMessage(s, Log4Qt::Level::ERROR_INT);
#define LOG_FATAL(s)		showMessage(s, Log4Qt::Level::FATAL_INT);
#define LOG_INFO(s)		showMessage(s, Log4Qt::Level::INFO_INT);

class LogSystem : public QWidget
{
    Q_OBJECT
	LOG4QT_DECLARE_QCLASS_LOGGER

public:
    LogSystem(QWidget *parent = nullptr);
    ~LogSystem();

public:
	void showMessage(QString message, Log4Qt::Level::Value level = Log4Qt::Level::ALL_INT);

private:
    Ui::LogSystemClass ui;
};

============================LogSystem.cpp=========================
#include "LogSystem.h"
#include "CustomTextBrowser.h"

LogSystem::LogSystem(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

	logger()->setLevel(Log4Qt::Level::ALL_INT);//设置日志显示级别

    //输出日志信息到界面	
	Log4Qt::PatternLayout* layout = new Log4Qt::PatternLayout();
	layout->setConversionPattern(Log4Qt::PatternLayout::TTCC_CONVERSION_PATTERN);

	CustomTextBrowser* ctb = new CustomTextBrowser();
	ctb->show();
	LogTextBrowserAppender* logTextBrowserAppender = new LogTextBrowserAppender(this, ctb);
	logTextBrowserAppender->setLayout(layout);
	logger()->addAppender(logTextBrowserAppender);
	logger()->setAdditivity(false);

	logger()->debug("This is a debug message.");
}

LogSystem::~LogSystem()
{}

void LogSystem::showMessage(QString message, Log4Qt::Level::Value level)
{
    ui.textBrowser_log->append(message);
	logger()->debug(message);

}

============================main.cpp============================
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

	// 一个简单的基础配置
	Log4Qt::BasicConfigurator::configure();

    LogSystem w;
    w.show();
    
    LOG_DEBUG("debug message")
    
    return a.exec();
}

6、输出到数据库