MyTetra Share
Делитесь знаниями!
Пример подсистемы логирования в Qt с использованием qInstallMessageHandler()
Время создания: 09.10.2021 12:44
Автор: xintrea
Текстовые метки: c++, Qt, Qt5, логирование, подсистема, qDebug, qWarning, отладка, консоль, файл, лог
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - Принципы написания кода
Запись: xintrea/mytetra_syncro/master/base/1633772699ygnj6dzmz2/text.html на raw.github.com

Ниже приведен код класса, который можно использовать в качестве подсистемы логирования в приложении на Qt. Данный класс перехватывает все отладочные сообщения, генерируемые через qDebug(), qWarning() и прочие функции потокового отладочного вывода, печатает их в консоль и записывает в файл лога.


Заголовок



#ifndef LOGHELPER_H

#define LOGHELPER_H


#include <QDebug>



class LogHelper

{

public:


static void setDebugMessageHandler();

static void myMessageOutput(QtMsgType type,

const QMessageLogContext &context,

const QString &msgText);


protected:


static void smartPrintDebugMessage(QString msg);

static void printToLogFile(const QString &text);

static void clearLogFile();


static QString m_logFileName;

};


#endif // LOGHELPER_H



Реализация



#include <QDebug>

#include <QObject>

#include <QApplication>

#include <QString>

#include <QTime>

#include <QMessageBox>


#include <iostream>


#include "log_helper.h"



QString LogHelper::m_logFileName;



void LogHelper::clearLogFile()

{

// Создание пустого файла лога

FILE *pFile=fopen(qPrintable(m_logFileName), "w+");

if(!pFile)

{

fclose(pFile);

}

}



void LogHelper::printToLogFile(const QString &text)

{

// Лог-файл открывается в режиме добавления данных

FILE *pFile=fopen(qPrintable(m_logFileName), "a+");


if(!pFile)

{

printf("Log %s file not writable\n", qPrintable(m_logFileName));

return;

}


// Быстрый вывод текста в файл лога

fprintf(pFile, "%s", qPrintable(text));


// Лог-файл закрывается

fclose(pFile);

}



void LogHelper::smartPrintDebugMessage(QString msg)

{

// Подготовка текста для вывода

QTime currTime = QTime::currentTime();

QString timeText = currTime.toString("hh:mm:ss.zzz");

msg=timeText+" "+msg;


// Быстрый вывод в консоль

fprintf(stderr, "%s", qPrintable(msg));


// Вывод в файл лога

printToLogFile(msg);

}



// Обработчик (хендлер) вызовов qDebug()

// Внутри этого обработчика нельзя использовать вызовы qDebug(), т. к. получится рекурсия

void LogHelper::myMessageOutput(QtMsgType type,

const QMessageLogContext &context,

const QString &msgText)

{

Q_UNUSED(context)


switch (type) {


case QtDebugMsg:

// Отладочный вывод возможен только при компиляции в режиме отладки

#ifdef QT_DEBUG

smartPrintDebugMessage("[DBG] "+msgText+"\n");

#endif

break;


case QtWarningMsg:

smartPrintDebugMessage("[WRN] "+msgText+"\n");

QMessageBox::warning(nullptr, "Application warning message",

msgText,

QMessageBox::Ok);

break;


case QtCriticalMsg:

smartPrintDebugMessage("[CRERR] "+msgText+"\n");

QMessageBox::warning(nullptr, "Application critical message",

msgText,

QMessageBox::Ok);

break;

case QtFatalMsg:

smartPrintDebugMessage("[FTERR] "+msgText+"\n");

abort();


case QtInfoMsg:

smartPrintDebugMessage("[INF] "+msgText+"\n");

break;

}

}



void LogHelper::setDebugMessageHandler()

{

// Задается статическое значение имени файла лога

m_logFileName=qApp->applicationDirPath()+"/log.txt";

printf("\nSet log file to %s\n", qPrintable(m_logFileName));


// Лог-файл очищается

clearLogFile();


// Устанавливается Qt-обработчик консольного вывода

qInstallMessageHandler(myMessageOutput);

}



Использование:



#include "log_helper.h"


...


LogHelper::setDebugMessageHandler();



Вызов setDebugMessageHandler() имеет смысл делать как можно ближе к самому началу программы, чтобы все сообщения попадали в файл лога.


Так же в этом разделе:
 
MyTetra Share v.0.58
Яндекс индекс цитирования