How to redirect qDebug, qWarning, qCritical etc output?
You've to install a message handler using qInstallMsgHandler
function, and then, you can use QTextStream
to write the debug message to a file. Here is a sample example:
#include <QtGlobal>
#include <stdio.h>
#include <stdlib.h>
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtInfoMsg:
fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtFatalMsg:
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
abort();
}
}
int main(int argc, char **argv)
{
qInstallMessageHandler(myMessageOutput); // Install the handler
QApplication app(argc, argv);
...
return app.exec();
}
Taken from the doc of qInstallMsgHandler
(I only added the comments):
- QtMsgHandler qInstallMessageHandler ( QtMsgHandler handler )
In the above example, the function myMessageOutput
uses stderr
which you might want to replace with some other file stream, or completely re-write the function!
Once you write and install this function, all your qDebug
(as well as qWarning
, qCritical
etc) messages would be redirected to the file you're writing to in the handler.
Qt output (qDebug qWarning etc) does not work if application is executed via cronjob
The issue is that qt behaves differently depending if it thinks that it is running in an (interactive?) terminal or not.
Quote:
One pitfall to be aware of: the destination of logging depends on an environment variable. If the variable QT_LOGGING_TO_CONSOLE is set to 1, the message functions will always log to the console. If set to 0, they will not log to the console, and will instead log to syslog, if enabled. When the environment variable is not set, the message functions log to a console if one is present (i.e. if the program is attached to a terminal). Thus, to ensure that the output of our example program goes to syslog, I set the environment variable to 0 within the program.
Therefore, the output of qDebug, QWarning etc. when executed from cron was not output via stderr, but directly handed over to journald.
TL;DR: quickfix: add QT_LOGGING_TO_CONSOLE=1
to /etc/crontab
.
.
PS: note if you need to debug an issue with QDebug:
- be aware of this: https://bugzilla.redhat.com/show_bug.cgi?id=1227295
- you can add
QT_LOGGING_DEBUG=1
as an environment variable to make
qt output changes in logging behavior during execution.
Related Topics
Resolution of Std::Chrono::High_Resolution_Clock Doesn't Correspond to Measurements
High Resolution Timer With C++ and Linux
Which C I/O Library Should Be Used in C++ Code
Dividing Two Integers to Produce a Float Result
Trailing Return Type Using Decltype With a Variadic Template Function
Default Value of Function Parameter
Sfinae to Check For Inherited Member Functions
How Does a C++ Reference Look, Memory-Wise
Conversion Constructor Vs. Conversion Operator: Precedence
Prevent Static Initialization Order "Fiasco", C++
Should the Exception Thrown by Boost::Asio::Io_Service::Run() Be Caught
Can Code That Is Valid in Both C and C++ Produce Different Behavior When Compiled in Each Language
How to Generate a Calling Graph For C++ Code
Initializing a Two Dimensional Std::Vector