qDebug日志写入本地文件

Table of Contents

    在Qt中使用qDebug打印日志信息是非常方便的,它可以直接打印Qt提供的复杂数据结构,如:QStringList,QVariantMap等。不做处理的话它只能在编辑器中打印调试信息,下面介绍将日志信息写入文件的实现方法。

    static struct LogWrap {
    	LogWrap::LogWrap() { reset(); }
    	LogWrap::~LogWrap() { reset(); }
    	void reset() {
    		isInit = false;
    		level = "";
    		date = "";
    		if (ts) {
    			delete ts;
    			ts = nullptr;
    		}
    		if (file) {
    			delete file;
    			file = nullptr;
    		}
    	}
    	bool isInit;
    	QMutex locker;
    	QString level;
    	QString date;
    	QFile *file;
    	QTextStream *ts;
    } s_logWrap;
    
    #define _TIME_ qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"))
    QStringList s_outputFileNames = QStringList() << "view.cpp" << "store.cpp";
    void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
    {
    	bool isFilter = true;
    	QString file(context.file);
    	for (auto iter = s_outputFileNames.begin(); iter != s_outputFileNames.end(); ++iter) {
    		if (file.contains(*iter)) {
    			isFilter = false;
    			break;
    		}
    	}
    	if (isFilter) {
    		return;
    	}
    
    	QString formatMsg;
    	switch (type) {
    	case QtDebugMsg:
    		formatMsg = "Debug:" + msg;
    		break;
    	case QtWarningMsg:
    		formatMsg = "Warning:" + msg;
    		break;
    	case QtCriticalMsg:
    		formatMsg = "Critical:" + msg;
    		break;
    	case QtFatalMsg:
    		formatMsg = "Fatal:" + msg;
    		break;
    	default:
    		return;
    	}
    
    	QString curDate = QDate::currentDate().toString("yyyyMMdd");
    	if (curDate != s_logWrap.date) {
    		s_logWrap.reset();
    	}
    
    	if (!s_logWrap.isInit) {
    		s_logWrap.isInit = true;
    		QDir().mkpath("log");
    		s_logWrap.level = "debug";
    		s_logWrap.date = QDate::currentDate().toString("yyyyMMdd");
    		s_logWrap.file = new QFile(QString("log\\log%1.log").arg(s_logWrap.date));
    		if (s_logWrap.file->open(QIODevice::WriteOnly | QIODevice::Append)) {
    			s_logWrap.ts = new QTextStream(s_logWrap.file);
    		}
    	}
    
    	if (s_logWrap.ts) {
    		QString text = _TIME_ + QString("[%1:%2]%3\n").arg(context.file).arg(context.line).arg(formatMsg);
    		OutputDebugString(text.toStdWString().c_str());
    		QMutexLocker locker(&s_logWrap.locker);
    		(*s_logWrap.ts << text).flush();
    	}
    }
    

    在Application创建之前调用:

    qInstallMessageHandler(myMessageOutput);
    
    • 使用当天日期作为日志文件名,一天一个文件
    • s_outputFileNames可以指定打印哪些文件中的日志
    • OutputDebugString打印到调试面板
    • 日志信息头包括:时间,文件,行号