Qt 之 自定义日志文件,QtMessageHandler应用

目录

一、前言

二、头文件代码

三、源文件代码

四、使用示例

五、使用效果


一、前言

在qt程序发布后,还需要查看一些调试输出信息,一般将输出信息写入日志文件,本文通过自定义函数实现将Debug、Warning、Critical、Fatal及Info信息自动输出到日志文件内,只需在main函数加两行代码即可。

另外为了防止日志文件输出太多,防止文件过大,加入了文件超过最大限度自动覆盖重写功能,例如设置的日志文件大小不超过1M,那么超过1M后可以将之前的内容清除掉,只保留最新的1M。

二、头文件代码

loger.h

cpp 复制代码
#pragma once

#include <QMutex>
#include <QString>

#define LOG_FILE_NAME QString("/Log/") + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss") + QString(".log")
#define MAX_SIZE 1024 * 1024 //文件最大1M

static int s_logLevel = QtDebugMsg;
static QMutex s_logMutex;
static QString s_logPath;

void setLogPath(const QString& path);
void setLogLevel(int level);
void customLogMessageHandler(QtMsgType type, const QMessageLogContext& ctx, const QString& msg);

三、源文件代码

loger.cpp

cpp 复制代码
#include "loger.h"
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QTextStream>
#include <QDateTime>


void setLogPath(const QString& path)
{
	s_logPath = path;
}

void setLogLevel(int level)
{
	s_logLevel = level;
}

bool static ensureDirExist(const QString& dirPath)
{
	QDir dir(dirPath);
	if (dir.exists())
	{
		return true;
	}

	return dir.mkpath(dirPath);
}

void customLogMessageHandler(QtMsgType type, const QMessageLogContext& ctx, const QString& msg)
{
	if (type < s_logLevel)
	{
		return;
	}

	QString logInfo;
	QString logTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss.zzz");
	switch (type)
	{
	case QtDebugMsg:
		logInfo = QString("%1 [Debug] %2").arg(logTime, msg);
		break;

	case QtWarningMsg:
		logInfo = QString("%1 [Warning] %2").arg(logTime, msg);
		break;

	case QtCriticalMsg:
		logInfo = QString("%1 [Critical] %2").arg(logTime, msg);
		break;

	case QtFatalMsg:
		logInfo = QString("%1 [Fatal] %2").arg(logTime, msg);
		abort();
	case QtInfoMsg:
		logInfo = QString("%1 [Info] %2").arg(logTime, msg);
		break;
	}

	s_logMutex.lock();
	QFile outFile(s_logPath);
	QFileInfo fileInfo(outFile);
	if (!ensureDirExist(fileInfo.absoluteDir().absolutePath()))
		return;

	if (outFile.size() > MAX_SIZE)
	{
		if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text))
			return;
	}
	else
	{
		if (!outFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
			return;
	}

	QTextStream ts(&outFile);
	ts << logInfo.toUtf8() << endl;
	outFile.close();
	s_logMutex.unlock();
}

四、使用示例

cpp 复制代码
#include "loger.h"

int main(int argc, char *argv[])
{
    setLogPath("./" + LOG_FILE_NAME);
    qInstallMessageHandler(customLogMessageHandler);

    //...其他代码.....

}

在main函数加上上述代码即可,后面运行代码,使用qDebug、qInfo...等输出的内容将不会在控制台再输出,全部在日志文件内。

五、使用效果

相关推荐
向宇it34 分钟前
【从零开始入门unity游戏开发之——C#篇26】C#面向对象动态多态——接口(Interface)、接口里氏替换原则、密封方法(`sealed` )
java·开发语言·unity·c#·游戏引擎·里氏替换原则
@菜鸟进阶记@38 分钟前
java根据Word模板实现动态填充导出
java·开发语言
卖芒果的潇洒农民40 分钟前
Lecture 6 Isolation & System Call Entry
java·开发语言
SomeB1oody1 小时前
【Rust自学】6.1. 定义枚举
开发语言·后端·rust
SomeB1oody1 小时前
【Rust自学】5.3. struct的方法(Method)
开发语言·后端·rust
无 证明2 小时前
new 分配空间;引用
数据结构·c++
Kisorge2 小时前
【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数
c语言·开发语言
轻口味3 小时前
命名空间与模块化概述
开发语言·前端·javascript
晓纪同学4 小时前
QT-简单视觉框架代码
开发语言·qt
威桑4 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略