網(wǎng)站首頁 編程語言 正文
1、思路
其實Qt提供了將日志寫入文件的方式,是以接口的形式提供的,我們只需要按照我們的需求完成回調(diào)函數(shù)和我們自己的接口即可。
為方便調(diào)用,我們一般直接寫到log.h中即可。
- 1、創(chuàng)建log.h
- 2、根據(jù)我們自己的需求完成回調(diào)函數(shù)
- 3、根據(jù)需求封裝外部調(diào)用函數(shù)并注冊回調(diào)函數(shù)
2、代碼
我這里按照我的需求,當(dāng)接口傳遞日志文件名和等級時使用傳遞的文件存儲日志,否則以精確到當(dāng)前時間為文件名創(chuàng)建日志文件。
提供給外部的調(diào)用函數(shù)包含日志文件名和日志等級兩個接口,可以不傳遞,直接使用默認(rèn)值。
Log.h
#ifndef LOG_H#define LOG_H#include <QFile>#include <QTextStream>#include <QDateTime>#include <QMutex>//選擇屏幕打印還是輸出到文件可以根據(jù)這個宏控制或者控制函數(shù)調(diào)用位置都可以//#define _DEBUG//默認(rèn)調(diào)試級別為warning,即小于warning級別的都不會寫入日志文件//只有release版本的時候,才會輸出到日志,debug版本正常輸出到終端。namespace QT_LOG{<!--{C}%3C!%2D%2D%20%2D%2D%3E--> //默認(rèn)文件名為當(dāng)前時間命名的log文件 static int m_LogLevel = 1; static QString m_LogFile = QString("%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmss")); QMutex m_LogMutex; void customMessageHandler(QtMsgType type , const QMessageLogContext &context , const QString &msg) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> //設(shè)置輸出日志級別,小于該級別,將不會寫入日志文件,默認(rèn)是warning級別,即debug信息不會寫入日志文件 if (type < m_LogLevel) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> return; } QString log_info; switch (type) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> case QtDebugMsg: log_info = QString("%1[Debug]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); break; case QtWarningMsg: log_info = QString("%1[Warning]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); break; case QtCriticalMsg: log_info = QString("%1[Critical]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); break; case QtFatalMsg: log_info = QString("%1[Fatal]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); abort(); case QtInfoMsg: log_info = QString("%1[Info]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); break; } log_info += QString(context.file) + QString(context.line) + QString("%1").arg(msg); //為了線程安全 m_LogMutex.lock(); QFile outFile(m_LogFile); outFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text); QTextStream ts(&outFile); ts << log_info << endl; outFile.close(); m_LogMutex.unlock(); } //默認(rèn)調(diào)試級別為warning及以上才會寫入日志文件,默認(rèn)log文件名為程序啟動時間命名的log文件 void logInit(QString logFile = "", int logLevel = 1) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> #ifndef _DEBUG //實現(xiàn)debug版本的時候,輸出到終端;release版本的時候輸出到日志文件 if ((logLevel < 0) || (logLevel > 3)) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> m_LogLevel = 1; } else {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> m_LogLevel = logLevel; } if (!logFile.isEmpty()) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> m_LogFile = logFile; } qInstallMessageHandler(customMessageHandler); #endif }}#endif // LOG_H#ifndef LOG_H
#define LOG_H
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QMutex>
//選擇屏幕打印還是輸出到文件可以根據(jù)這個宏控制或者控制函數(shù)調(diào)用位置都可以
//#define _DEBUG
//默認(rèn)調(diào)試級別為warning,即小于warning級別的都不會寫入日志文件
//只有release版本的時候,才會輸出到日志,debug版本正常輸出到終端。
namespace QT_LOG
{
//默認(rèn)文件名為當(dāng)前時間命名的log文件
static int m_LogLevel = 1;
static QString m_LogFile = QString("%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmss"));
QMutex m_LogMutex;
void customMessageHandler(QtMsgType type , const QMessageLogContext &context , const QString &msg)
{
//設(shè)置輸出日志級別,小于該級別,將不會寫入日志文件,默認(rèn)是warning級別,即debug信息不會寫入日志文件
if (type < m_LogLevel)
{
return;
}
QString log_info;
switch (type)
{
case QtDebugMsg:
log_info = QString("%1[Debug]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
break;
case QtWarningMsg:
log_info = QString("%1[Warning]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
break;
case QtCriticalMsg:
log_info = QString("%1[Critical]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
break;
case QtFatalMsg:
log_info = QString("%1[Fatal]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
abort();
case QtInfoMsg:
log_info = QString("%1[Info]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
break;
}
log_info += QString(context.file) + QString(context.line) + QString("%1").arg(msg);
//為了線程安全
m_LogMutex.lock();
QFile outFile(m_LogFile);
outFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
QTextStream ts(&outFile);
ts << log_info << endl;
outFile.close();
m_LogMutex.unlock();
}
//默認(rèn)調(diào)試級別為warning及以上才會寫入日志文件,默認(rèn)log文件名為程序啟動時間命名的log文件
void logInit(QString logFile = "", int logLevel = 1)
{
#ifndef _DEBUG //實現(xiàn)debug版本的時候,輸出到終端;release版本的時候輸出到日志文件
if ((logLevel < 0) || (logLevel > 3))
{
m_LogLevel = 1;
}
else
{
m_LogLevel = logLevel;
}
if (!logFile.isEmpty())
{
m_LogFile = logFile;
}
qInstallMessageHandler(customMessageHandler);
#endif
}
}
#endif // LOG_H
調(diào)用,包含頭文件后直接調(diào)用參數(shù)即可:
QT_LOG::logInit();//或者QT_LOG::logInit("log.txt", 2);QT_LOG::logInit();
//或者
QT_LOG::logInit("log.txt", 2);
3、問題
可能不通Qt版本提供的回調(diào)函數(shù)有差異,我們通過qInstallMessageHandler進(jìn)行源碼查看,看下回調(diào)函數(shù)的樣式,實現(xiàn)對應(yīng)的回調(diào)函數(shù)進(jìn)行測試即可:
4、結(jié)果與擴(kuò)展思路
這個是我使用我上面封裝的函數(shù)后生成的日志文件,每一次啟動創(chuàng)建一個,暫時沒有考慮定時分割創(chuàng)建新文件等問題,如果有需求可以調(diào)整回調(diào)函數(shù)進(jìn)行調(diào)試:
針對上面的日志我們還可以加一些定時任務(wù)或者直接通過內(nèi)存數(shù)據(jù)庫通過線程安全的方式直接存儲到數(shù)據(jù)庫中,這樣便于分布式存儲和分析操作日志。
原文鏈接:https://blog.csdn.net/weixin_39510813/article/details/115421105
相關(guān)推薦
- 2022-08-01 Flutter移動端進(jìn)行多渠道打包發(fā)布的全過程_Android
- 2022-04-10 解析React?中的Virtual?DOM_MsSql
- 2021-12-03 關(guān)于Redis數(shù)據(jù)庫入門詳細(xì)介紹_Redis
- 2022-05-19 Python?Timer和TimerFPS計時工具類_python
- 2023-04-28 react如何獲取URL中參數(shù)_React
- 2022-09-28 React報錯解決之ref返回undefined或null_React
- 2022-11-30 React之錯誤邊界?Error?Boundaries示例詳解_React
- 2022-11-01 Python正則表達(dá)中re模塊的使用_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支