Skip to content

Instantly share code, notes, and snippets.

@carlosolmos
Last active November 15, 2023 03:52
Show Gist options
  • Save carlosolmos/639a21d23b0d4b6de85ff14578c37e7c to your computer and use it in GitHub Desktop.
Save carlosolmos/639a21d23b0d4b6de85ff14578c37e7c to your computer and use it in GitHub Desktop.
Redirect QDebug output to a file.
/*
This code redirects the output of qDebug() to a log file.
It also rotates the file base on size.
Uses QMutex for thread safety.
*/
//some constants to parameterize.
const qint64 LOG_FILE_LIMIT = 3000000;
const QString LOG_PATH = "/application/logs/";
const QString LOG_FILENAME = "mylogfile.log";
//thread safety
QMutex mutex;
void redirectDebugMessages(QtMsgType type, const QMessageLogContext & context, const QString & str)
{
//thread safety
mutex.lock();
QString txt;
//prepend timestamp to every message
QString datetime = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
//prepend a log level label to every message
switch (type) {
case QtDebugMsg:
txt = QString("[Debug*] ");
break;
case QtWarningMsg:
txt = QString("[Warning] ");
break;
case QtInfoMsg:
txt = QString("[Info] ");
break;
case QtCriticalMsg:
txt = QString("[Critical] ");
break;
case QtFatalMsg:
txt = QString("[Fatal] ");
}
QString filePath = LOG_PATH + LOG_FILENAME;
QFile outFile(filePath);
//if file reached the limit, rotate to filename.1
if(outFile.size() > LOG_FILE_LIMIT){
//roll the log file.
QFile::remove(filePath + ".1");
QFile::rename(filePath, filePath + ".1");
QFile::resize(filePath, 0);
}
//write message
outFile.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream ts(&outFile);
ts << datetime << txt << str << endl;
//close fd
outFile.close();
mutex.unlock();
}
//in the main function add this code
int main(int argc, char *argv[]){
qInstallMessageHandler(redirectDebugMessages);
}
@naavis
Copy link

naavis commented Feb 20, 2021

Thanks for this! I don't think it is thread-safe, though. You are instantiating mutex inside the message handler function, which means every thread will have it's own copy of the mutex and calling mutex.lock() will never block. The mutex should be a global variable for this to be thread-safe.

@carlosolmos
Copy link
Author

Nice catch! Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment