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 "qtsingleapplication.h"
|
||||||
#include "utils/xmlconfig.h"
|
#include "utils/xmlconfig.h"
|
||||||
#include "utils/pathutils.h"
|
#include "utils/pathutils.h"
|
||||||
|
#include "utils/filelogger.h"
|
||||||
#include "gcssplashscreen.h"
|
#include "gcssplashscreen.h"
|
||||||
|
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
@ -108,7 +109,6 @@
|
|||||||
#include <QSplashScreen>
|
#include <QSplashScreen>
|
||||||
#include <QSurfaceFormat>
|
#include <QSurfaceFormat>
|
||||||
|
|
||||||
namespace {
|
|
||||||
typedef QList<ExtensionSystem::PluginSpec *> PluginSpecSet;
|
typedef QList<ExtensionSystem::PluginSpec *> PluginSpecSet;
|
||||||
typedef QMap<QString, bool> AppOptions;
|
typedef QMap<QString, bool> AppOptions;
|
||||||
typedef QMap<QString, QString> AppOptionValues;
|
typedef QMap<QString, QString> AppOptionValues;
|
||||||
@ -286,48 +286,21 @@ void systemInit()
|
|||||||
QSurfaceFormat::setDefaultFormat(format);
|
QSurfaceFormat::setDefaultFormat(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QTextStream *logStream;
|
static FileLogger *logger;
|
||||||
|
|
||||||
void mainMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
void mainMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
logger->log(type, context, 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QtMsgType)
|
||||||
|
|
||||||
void logInit(QString fileName)
|
void logInit(QString fileName)
|
||||||
{
|
{
|
||||||
QFile *file = new QFile(fileName);
|
qRegisterMetaType<QtMsgType>();
|
||||||
|
qInstallMessageHandler(mainMessageOutput);
|
||||||
if (file->open(QIODevice::WriteOnly | QIODevice::Text)) {
|
logger = new FileLogger();
|
||||||
logStream = new QTextStream(file);
|
if (!logger->start(fileName)) {
|
||||||
qInstallMessageHandler(mainMessageOutput);
|
|
||||||
} else {
|
|
||||||
displayError(msgLogfileOpenFailed(fileName));
|
displayError(msgLogfileOpenFailed(fileName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,7 +429,6 @@ void loadTranslators(QString language, QTranslator &translator, QTranslator &qtT
|
|||||||
translator.load(QString());
|
translator.load(QString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace anonymous
|
|
||||||
|
|
||||||
int main(int argc, char * *argv)
|
int main(int argc, char * *argv)
|
||||||
{
|
{
|
||||||
@ -494,6 +466,8 @@ int main(int argc, char * *argv)
|
|||||||
if (appOptionValues.contains(LOG_FILE_OPTION)) {
|
if (appOptionValues.contains(LOG_FILE_OPTION)) {
|
||||||
QString logFileName = appOptionValues.value(LOG_FILE_OPTION);
|
QString logFileName = appOptionValues.value(LOG_FILE_OPTION);
|
||||||
logInit(logFileName);
|
logInit(logFileName);
|
||||||
|
// relog command line arguments for the benefit of the file logger...
|
||||||
|
qDebug() << "Command line" << app.arguments();
|
||||||
}
|
}
|
||||||
|
|
||||||
// load user settings
|
// load user settings
|
||||||
@ -644,5 +618,9 @@ int main(int argc, char * *argv)
|
|||||||
|
|
||||||
qDebug() << "main - GCS ran for" << timer.elapsed() << "ms";
|
qDebug() << "main - GCS ran for" << timer.elapsed() << "ms";
|
||||||
|
|
||||||
|
if (logger) {
|
||||||
|
delete logger;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
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 \
|
logfile.h \
|
||||||
crc.h \
|
crc.h \
|
||||||
mustache.h \
|
mustache.h \
|
||||||
textbubbleslider.h
|
textbubbleslider.h \
|
||||||
|
filelogger.h
|
||||||
|
|
||||||
HEADERS += xmlconfig.h
|
HEADERS += xmlconfig.h
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user