Redirect stderr to log file

To log side libraries output
This commit is contained in:
Gres 2020-04-25 19:46:49 +03:00
parent 5556d7aae2
commit b73cbde790

View File

@ -6,12 +6,19 @@
#include <QMutex> #include <QMutex>
#include <QThread> #include <QThread>
#ifdef Q_OS_WIN
#include <io.h>
#else
#include <unistd.h>
#endif
namespace namespace
{ {
QtMessageHandler original = nullptr;
QMutex mutex; QMutex mutex;
QFile file; QString fileName;
QTextStream stream; int realStdout{};
int realStderr{};
FILE *logFile{};
void handler(QtMsgType type, const QMessageLogContext &context, void handler(QtMsgType type, const QMessageLogContext &context,
const QString &msg) const QString &msg)
@ -29,11 +36,30 @@ void handler(QtMsgType type, const QMessageLogContext &context,
QFileInfo(context.file).fileName().toUtf8() + ':' + QFileInfo(context.file).fileName().toUtf8() + ':' +
QByteArray::number(context.line) + typeName + msg.toUtf8() + '\n'; QByteArray::number(context.line) + typeName + msg.toUtf8() + '\n';
SOFT_ASSERT(original, return ); if (logFile)
original(type, context, msg); write(fileno(logFile), message.data(), message.size());
if (realStderr > 0)
write(realStderr, message.data(), message.size());
}
QMutexLocker locker(&mutex); void toDefaults()
file.write(message); {
qInstallMessageHandler(nullptr);
if (realStdout > 0) {
dup2(realStdout, fileno(stdout));
realStdout = -1;
}
if (realStderr > 0) {
dup2(realStderr, fileno(stderr));
realStderr = -1;
}
if (logFile) {
fclose(logFile);
logFile = nullptr;
}
} }
} // namespace } // namespace
@ -44,28 +70,32 @@ std::atomic_bool isTrace = false;
QString traceFileName() QString traceFileName()
{ {
QMutexLocker locker(&mutex); QMutexLocker locker(&mutex);
return file.fileName(); return fileName;
} }
bool setTraceFileName(const QString &fileName) bool setTraceFileName(const QString &fileName)
{ {
QMutexLocker locker(&mutex); QMutexLocker locker(&mutex);
original = nullptr; toDefaults();
qInstallMessageHandler(nullptr);
if (file.isOpen())
file.close();
if (fileName.isEmpty()) if (fileName.isEmpty())
return true; return true;
file.setFileName(fileName); logFile = fopen(qPrintable(fileName), "w");
if (!logFile)
if (!file.open(QFile::WriteOnly | QFile::Unbuffered))
return false; return false;
original = qInstallMessageHandler(handler); realStdout = dup(fileno(stdout));
realStderr = dup(fileno(stderr));
const auto fd = fileno(logFile);
dup2(fd, fileno(stdout));
dup2(fd, fileno(stderr));
::fileName = fileName;
qInstallMessageHandler(handler);
return true; return true;
} }