mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
LP-362 make file logging thread safe (and asynchronous)
This commit is contained in:
parent
783bb83642
commit
54b33e0a07
@ -84,6 +84,7 @@
|
||||
#include "qtsingleapplication.h"
|
||||
#include "utils/xmlconfig.h"
|
||||
#include "utils/pathutils.h"
|
||||
#include "utils/filelogger.h"
|
||||
#include "gcssplashscreen.h"
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
@ -108,7 +109,6 @@
|
||||
#include <QSplashScreen>
|
||||
#include <QSurfaceFormat>
|
||||
|
||||
namespace {
|
||||
typedef QList<ExtensionSystem::PluginSpec *> PluginSpecSet;
|
||||
typedef QMap<QString, bool> AppOptions;
|
||||
typedef QMap<QString, QString> AppOptionValues;
|
||||
@ -286,48 +286,21 @@ void systemInit()
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
}
|
||||
|
||||
static QTextStream *logStream;
|
||||
static FileLogger *logger;
|
||||
|
||||
void mainMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
|
||||
QTextStream &out = *logStream;
|
||||
|
||||
// logStream << QTime::currentTime().toString("hh:mm:ss.zzz ");
|
||||
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
out << "DBG: ";
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
case QtInfoMsg:
|
||||
out << "INF: ";
|
||||
break;
|
||||
#endif
|
||||
case QtWarningMsg:
|
||||
out << "WRN: ";
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
out << "CRT: ";
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
out << "FTL: ";
|
||||
break;
|
||||
}
|
||||
|
||||
out << msg << '\n';
|
||||
out.flush();
|
||||
logger->log(type, context, msg);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QtMsgType)
|
||||
|
||||
void logInit(QString fileName)
|
||||
{
|
||||
QFile *file = new QFile(fileName);
|
||||
|
||||
if (file->open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
logStream = new QTextStream(file);
|
||||
qInstallMessageHandler(mainMessageOutput);
|
||||
} else {
|
||||
qRegisterMetaType<QtMsgType>();
|
||||
qInstallMessageHandler(mainMessageOutput);
|
||||
logger = new FileLogger();
|
||||
if (!logger->start(fileName)) {
|
||||
displayError(msgLogfileOpenFailed(fileName));
|
||||
}
|
||||
}
|
||||
@ -456,7 +429,6 @@ void loadTranslators(QString language, QTranslator &translator, QTranslator &qtT
|
||||
translator.load(QString());
|
||||
}
|
||||
}
|
||||
} // namespace anonymous
|
||||
|
||||
int main(int argc, char * *argv)
|
||||
{
|
||||
@ -494,6 +466,8 @@ int main(int argc, char * *argv)
|
||||
if (appOptionValues.contains(LOG_FILE_OPTION)) {
|
||||
QString logFileName = appOptionValues.value(LOG_FILE_OPTION);
|
||||
logInit(logFileName);
|
||||
// relog command line arguments for the benefit of the file logger...
|
||||
qDebug() << "Command line" << app.arguments();
|
||||
}
|
||||
|
||||
// load user settings
|
||||
@ -644,5 +618,9 @@ int main(int argc, char * *argv)
|
||||
|
||||
qDebug() << "main - GCS ran for" << timer.elapsed() << "ms";
|
||||
|
||||
if (logger) {
|
||||
delete logger;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
141
ground/gcs/src/libs/utils/filelogger.h
Normal file
141
ground/gcs/src/libs/utils/filelogger.h
Normal file
@ -0,0 +1,141 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file filelogger.h
|
||||
* @author The LibrePilot Project, http://www.openpilot.org Copyright (C) 2016.
|
||||
* Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
|
||||
* @brief
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils_global.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT FileLogger : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QTextStream * logStream;
|
||||
QThread *loggerThread;
|
||||
bool started;
|
||||
|
||||
public:
|
||||
FileLogger() : QObject(), logStream(NULL), loggerThread(NULL), started(false)
|
||||
{}
|
||||
|
||||
virtual ~FileLogger()
|
||||
{
|
||||
stop();
|
||||
if (logStream) {
|
||||
delete logStream;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
bool start(const QString &fileName)
|
||||
{
|
||||
if (started) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QFile *file = new QFile(fileName);
|
||||
if (!file->open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
logStream = new QTextStream(file);
|
||||
|
||||
loggerThread = new QThread(this);
|
||||
moveToThread(loggerThread);
|
||||
loggerThread->start();
|
||||
|
||||
started = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool stop()
|
||||
{
|
||||
if (!started) {
|
||||
return false;
|
||||
}
|
||||
// stop accepting messages
|
||||
started = false;
|
||||
|
||||
// make sure all messages are flushed by sending a blocking message
|
||||
QtMsgType type = QtDebugMsg;
|
||||
const QString msg = "stopping file logger";
|
||||
QMetaObject::invokeMethod(this, "doLog", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QtMsgType, type), Q_ARG(const QString &, msg));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void log(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(this, "doLog", Qt::QueuedConnection,
|
||||
Q_ARG(QtMsgType, type), Q_ARG(const QString &, msg));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void doLog(QtMsgType type, const QString &msg)
|
||||
{
|
||||
QTextStream &out = *logStream;
|
||||
|
||||
// logStream << QTime::currentTime().toString("hh:mm:ss.zzz ");
|
||||
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
out << "DBG: ";
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
case QtInfoMsg:
|
||||
out << "INF: ";
|
||||
break;
|
||||
#endif
|
||||
case QtWarningMsg:
|
||||
out << "WRN: ";
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
out << "CRT: ";
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
out << "FTL: ";
|
||||
break;
|
||||
}
|
||||
|
||||
out << msg << '\n';
|
||||
out.flush();
|
||||
}
|
||||
};
|
@ -121,7 +121,8 @@ HEADERS += \
|
||||
logfile.h \
|
||||
crc.h \
|
||||
mustache.h \
|
||||
textbubbleslider.h
|
||||
textbubbleslider.h \
|
||||
filelogger.h
|
||||
|
||||
HEADERS += xmlconfig.h
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user