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...等输出的内容将不会在控制台再输出,全部在日志文件内。

五、使用效果

相关推荐
Yyyyyy~15 小时前
[C语言]break和continue作业
c语言·开发语言
此生决int15 小时前
深入理解C++系列(10)——lsit
开发语言·c++
NoteStream15 小时前
【C语言基础】分支和循环(上)
c语言·开发语言·c++·经验分享·笔记·算法·c#
2401_8274999915 小时前
C++(黑马)05-提高编程
java·开发语言·c++
进击的程序猿~16 小时前
Go Interface源码深度解析指南
开发语言·后端·golang
hold?fish:palm16 小时前
链表的基本原理和实现(C++版本)
数据结构·c++·链表
jufeng130716 小时前
【系列:MiniKV 原理剖析 · 第 5 篇】
linux·网络·c++·软件工程
Data_Journal17 小时前
如何使用 Java 和 Jsoup 解析 HTML
大数据·开发语言·数据库·python·scrapy
吃好睡好便好17 小时前
MATLAB仿真框图2
开发语言·matlab·仿真·simulink
豆沙沙包?17 小时前
C++-程序的内存模型(P84-P88)
java·jvm·c++