LogEngine: provide possibility to disable the log engine

This commit is contained in:
Simon Stürz 2023-08-09 11:29:33 +02:00
parent 4b3ec64e58
commit 84dca158b3
9 changed files with 120 additions and 19 deletions

View File

@ -1,10 +1,39 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2023, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "logengineinfluxdb.h" #include "logengineinfluxdb.h"
#include <QNetworkReply> #include <QNetworkReply>
#include <QUrlQuery> #include <QUrlQuery>
#include <QJsonDocument> #include <QJsonDocument>
#include <QCoreApplication> #include <QCoreApplication>
#include <QTimer>
LogEngineInfluxDB::LogEngineInfluxDB(const QString &host, const QString &dbName, const QString &username, const QString &password, QObject *parent) LogEngineInfluxDB::LogEngineInfluxDB(const QString &host, const QString &dbName, const QString &username, const QString &password, QObject *parent)
: LogEngine{parent}, : LogEngine{parent},
@ -14,7 +43,10 @@ LogEngineInfluxDB::LogEngineInfluxDB(const QString &host, const QString &dbName,
m_password(password) m_password(password)
{ {
m_nam = new QNetworkAccessManager(this); m_nam = new QNetworkAccessManager(this);
initDB();
m_reinitTimer.setInterval(5000);
m_reinitTimer.setSingleShot(true);
connect(&m_reinitTimer, &QTimer::timeout, this, &LogEngineInfluxDB::initDB);
} }
LogEngineInfluxDB::~LogEngineInfluxDB() LogEngineInfluxDB::~LogEngineInfluxDB()
@ -39,7 +71,6 @@ Logger *LogEngineInfluxDB::registerLogSource(const QString &name, const QStringL
return nullptr; return nullptr;
} }
// qCDebug(dcLogEngine()) << "Registering log source" << name << "with tags" << tagNames; // qCDebug(dcLogEngine()) << "Registering log source" << name << "with tags" << tagNames;
Logger *logger = createLogger(name, tagNames, loggingType); Logger *logger = createLogger(name, tagNames, loggingType);
@ -196,7 +227,7 @@ void LogEngineInfluxDB::logEvent(Logger *logger, const QStringList &tags, const
void LogEngineInfluxDB::processQueues() void LogEngineInfluxDB::processQueues()
{ {
if (m_initStatus == InitStatusFailure) { if (m_initStatus == InitStatusFailure || m_initStatus == InitStatusDisabled) {
m_writeQueue.clear(); m_writeQueue.clear();
qDeleteAll(m_queryQueue); qDeleteAll(m_queryQueue);
m_queryQueue.clear(); m_queryQueue.clear();
@ -499,6 +530,22 @@ void LogEngineInfluxDB::clear(const QString &source)
}); });
} }
void LogEngineInfluxDB::enable()
{
qCInfo(dcLogEngine()) << "Enabling influx DB log engine";
initDB();
}
void LogEngineInfluxDB::disable()
{
qCInfo(dcLogEngine()) << "Disabling influx DB log engine";
m_initStatus = InitStatusDisabled;
m_reinitTimer.stop();
// Cleanup queues
processQueues();
}
void LogEngineInfluxDB::initDB() void LogEngineInfluxDB::initDB()
{ {
m_initStatus = InitStatusStarting; m_initStatus = InitStatusStarting;
@ -513,10 +560,10 @@ void LogEngineInfluxDB::createDB()
if (status != QNetworkReply::NoError) { if (status != QNetworkReply::NoError) {
if (status == QNetworkReply::ConnectionRefusedError) { if (status == QNetworkReply::ConnectionRefusedError) {
// Influx not up yet? trying again in 5 secs... // Influx not up yet? trying again in 5 secs...
qCInfo(dcLogEngine) << "Failed to connect to influx... retrying in 5 seconds..."; if (m_initStatus != InitStatusDisabled) {
QTimer::singleShot(5000, this, [=](){ qCInfo(dcLogEngine) << "Failed to connect to influx... retrying in 5 seconds...";
initDB(); m_reinitTimer.start();
}); }
return; return;
} }
qCCritical(dcLogEngine()) << "Unable to connect to InfluxDB"; qCCritical(dcLogEngine()) << "Unable to connect to InfluxDB";

View File

@ -1,8 +1,39 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2023, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef LOGENGINEINFLUXDB_H #ifndef LOGENGINEINFLUXDB_H
#define LOGENGINEINFLUXDB_H #define LOGENGINEINFLUXDB_H
#include "logging/logengine.h" #include "logging/logengine.h"
#include <QObject> #include <QObject>
#include <QTimer>
#include <QQueue> #include <QQueue>
#include <QHostAddress> #include <QHostAddress>
#include <QNetworkRequest> #include <QNetworkRequest>
@ -33,7 +64,8 @@ public:
InitStatusNone, InitStatusNone,
InitStatusStarting, InitStatusStarting,
InitStatusOK, InitStatusOK,
InitStatusFailure InitStatusFailure,
InitStatusDisabled
}; };
Q_ENUM(InitStatus) Q_ENUM(InitStatus)
@ -51,6 +83,9 @@ public:
bool jobsRunning() const override; bool jobsRunning() const override;
void clear(const QString &source) override; void clear(const QString &source) override;
void enable() override;
void disable() override;
private: private:
void initDB(); void initDB();
void createRetentionPolicies(); void createRetentionPolicies();
@ -72,6 +107,7 @@ private:
}; };
InitStatus m_initStatus = InitStatusNone; InitStatus m_initStatus = InitStatusNone;
QTimer m_reinitTimer;
QNetworkAccessManager *m_nam = nullptr; QNetworkAccessManager *m_nam = nullptr;

View File

@ -83,7 +83,7 @@ NymeaCore::NymeaCore(QObject *parent) :
{ {
} }
void NymeaCore::init(const QStringList &additionalInterfaces) { void NymeaCore::init(const QStringList &additionalInterfaces, bool disableLogEngine) {
qCDebug(dcCore()) << "Initializing NymeaCore"; qCDebug(dcCore()) << "Initializing NymeaCore";
qCDebug(dcPlatform()) << "Loading platform abstraction"; qCDebug(dcPlatform()) << "Loading platform abstraction";
@ -124,8 +124,13 @@ void NymeaCore::init(const QStringList &additionalInterfaces) {
m_hardwareManager = new HardwareManagerImplementation(m_platform, m_serverManager->mqttBroker(), m_zigbeeManager, m_zwaveManager, m_modbusRtuManager, this); m_hardwareManager = new HardwareManagerImplementation(m_platform, m_serverManager->mqttBroker(), m_zigbeeManager, m_zwaveManager, m_modbusRtuManager, this);
qCDebug(dcCore) << "Creating Log Engine"; qCDebug(dcCore) << "Creating Log Engine";
// m_logger = new Logger(m_configuration->logDBDriver(), m_configuration->logDBName(), m_configuration->logDBHost(), m_configuration->logDBUser(), m_configuration->logDBPassword(), this);
m_logEngine = new LogEngineInfluxDB(m_configuration->logDBHost(), m_configuration->logDBName(), m_configuration->logDBUser(), m_configuration->logDBPassword(), this); m_logEngine = new LogEngineInfluxDB(m_configuration->logDBHost(), m_configuration->logDBName(), m_configuration->logDBUser(), m_configuration->logDBPassword(), this);
if (disableLogEngine) {
m_logEngine->disable();
} else {
m_logEngine->enable();
}
m_logger = m_logEngine->registerLogSource("core", {"event"}); m_logger = m_logEngine->registerLogSource("core", {"event"});
qCDebug(dcCore) << "Creating Thing Manager (locale:" << m_configuration->locale() << ")"; qCDebug(dcCore) << "Creating Thing Manager (locale:" << m_configuration->locale() << ")";
@ -340,7 +345,7 @@ ExperienceManager *NymeaCore::experienceManager() const
return m_experienceManager; return m_experienceManager;
} }
LogEngine* NymeaCore::logEngine() const LogEngine *NymeaCore::logEngine() const
{ {
return m_logEngine; return m_logEngine;
} }

View File

@ -92,7 +92,7 @@ public:
static NymeaCore* instance(); static NymeaCore* instance();
~NymeaCore(); ~NymeaCore();
void init(const QStringList &additionalInterfaces = QStringList()); void init(const QStringList &additionalInterfaces = QStringList(), bool disableLogEngine = false);
void destroy(nymeaserver::NymeaCore::ShutdownReason reason); void destroy(nymeaserver::NymeaCore::ShutdownReason reason);
RuleEngine::RuleError removeRule(const RuleId &id); RuleEngine::RuleError removeRule(const RuleId &id);

View File

@ -54,6 +54,9 @@ public:
virtual bool jobsRunning() const = 0; virtual bool jobsRunning() const = 0;
virtual void clear(const QString &source) = 0; virtual void clear(const QString &source) = 0;
virtual void enable() = 0;
virtual void disable() = 0;
signals: signals:
void logEntryAdded(const LogEntry &entry); void logEntryAdded(const LogEntry &entry);

View File

@ -52,6 +52,7 @@
#include "nymeadbusservice.h" #include "nymeadbusservice.h"
#include "nymeaapplication.h" #include "nymeaapplication.h"
#include "loggingcategories.h" #include "loggingcategories.h"
#include "logging/logengine.h"
#include "version.h" #include "version.h"
NYMEA_LOGGING_CATEGORY(dcApplication, "Application") NYMEA_LOGGING_CATEGORY(dcApplication, "Application")
@ -121,6 +122,9 @@ int main(int argc, char *argv[])
QCommandLineOption interfacesOption({"i", "interface"}, QCoreApplication::translate("nymea", "Additional interfaces to listen on. In nymea URI format (e.g. nymeas://127.0.0.2:7777). Note that such interfaces will not require any authentication as they are intended to be used for automated testing only."), "interfaceString"); QCommandLineOption interfacesOption({"i", "interface"}, QCoreApplication::translate("nymea", "Additional interfaces to listen on. In nymea URI format (e.g. nymeas://127.0.0.2:7777). Note that such interfaces will not require any authentication as they are intended to be used for automated testing only."), "interfaceString");
parser.addOption(interfacesOption); parser.addOption(interfacesOption);
QCommandLineOption noLogDbOption({"m", "no-logengine"}, QCoreApplication::translate("nymea", "Disable the influx DB log engine."));
parser.addOption(noLogDbOption);
parser.process(application); parser.process(application);
// Open the logfile, if any specified // Open the logfile, if any specified
@ -230,12 +234,13 @@ int main(int argc, char *argv[])
} }
// create core instance // create core instance
NymeaCore::instance()->init(parser.values(interfacesOption)); NymeaCore::instance()->init(parser.values(interfacesOption), parser.isSet(noLogDbOption));
int ret = application.exec(); int ret = application.exec();
closeLogFile(); closeLogFile();
return ret; return ret;
} }
// FIXME: the background service should get the arguments too
NymeaService service(argc, argv); NymeaService service(argc, argv);
int ret = service.exec(); int ret = service.exec();
closeLogFile(); closeLogFile();

View File

@ -82,8 +82,8 @@ void NymeaService::start()
fprintf(stdout, "Could not create nymea settings directory %s", qPrintable(NymeaSettings::settingsPath())); fprintf(stdout, "Could not create nymea settings directory %s", qPrintable(NymeaSettings::settingsPath()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
qCDebug(dcApplication) << "=====================================";
qCDebug(dcApplication) << "=====================================";
qCDebug(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started as daemon."; qCDebug(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started as daemon.";
qCDebug(dcApplication) << "====================================="; qCDebug(dcApplication) << "=====================================";
NymeaCore::instance(); NymeaCore::instance();

View File

@ -54,10 +54,13 @@ NymeaTestBase::NymeaTestBase(QObject *parent) :
QCoreApplication::instance()->setOrganizationName("nymea-test"); QCoreApplication::instance()->setOrganizationName("nymea-test");
} }
void NymeaTestBase::initTestCase(const QString &loggingRules) void NymeaTestBase::initTestCase(const QString &loggingRules, bool disableLogEngine)
{ {
qCDebug(dcTests) << "NymeaTestBase starting."; qCDebug(dcTests) << "NymeaTestBase starting.";
// Keep this over restart of core instance
m_disableLogEngine = disableLogEngine;
// If testcase asserts cleanup won't do. Lets clear any previous test run settings leftovers // If testcase asserts cleanup won't do. Lets clear any previous test run settings leftovers
NymeaSettings rulesSettings(NymeaSettings::SettingsRoleRules); NymeaSettings rulesSettings(NymeaSettings::SettingsRoleRules);
rulesSettings.clear(); rulesSettings.clear();
@ -84,7 +87,7 @@ void NymeaTestBase::initTestCase(const QString &loggingRules)
// Start the server // Start the server
qCDebug(dcTests()) << "Setting up nymea core instance"; qCDebug(dcTests()) << "Setting up nymea core instance";
NymeaCore::instance()->init(); NymeaCore::instance()->init(QStringList(), m_disableLogEngine);
// Wait unitl the server is initialized // Wait unitl the server is initialized
QSignalSpy coreInitializedSpy(NymeaCore::instance(), SIGNAL(initialized())); QSignalSpy coreInitializedSpy(NymeaCore::instance(), SIGNAL(initialized()));
@ -432,7 +435,7 @@ void NymeaTestBase::restartServer()
qCDebug(dcTests()) << "Tearing down server instance"; qCDebug(dcTests()) << "Tearing down server instance";
NymeaCore::instance()->destroy(NymeaCore::ShutdownReasonRestart); NymeaCore::instance()->destroy(NymeaCore::ShutdownReasonRestart);
qCDebug(dcTests()) << "Restarting server instance"; qCDebug(dcTests()) << "Restarting server instance";
NymeaCore::instance()->init(); NymeaCore::instance()->init(QStringList(), m_disableLogEngine);
QSignalSpy coreSpy(NymeaCore::instance(), SIGNAL(initialized())); QSignalSpy coreSpy(NymeaCore::instance(), SIGNAL(initialized()));
coreSpy.wait(); coreSpy.wait();
m_mockTcpServer = MockTcpServer::servers().first(); m_mockTcpServer = MockTcpServer::servers().first();

View File

@ -51,7 +51,7 @@ public:
explicit NymeaTestBase(QObject *parent = nullptr); explicit NymeaTestBase(QObject *parent = nullptr);
protected slots: protected slots:
void initTestCase(const QString &loggingRules = QString()); void initTestCase(const QString &loggingRules = QString(), bool disableLogEngine = false);
void cleanupTestCase(); void cleanupTestCase();
void cleanup(); void cleanup();
@ -130,6 +130,8 @@ private:
void createMock(); void createMock();
protected: protected:
bool m_disableLogEngine = false;
PluginId mockPluginId = PluginId("727a4a9a-c187-446f-aadf-f1b2220607d1"); PluginId mockPluginId = PluginId("727a4a9a-c187-446f-aadf-f1b2220607d1");
VendorId nymeaVendorId = VendorId("2062d64d-3232-433c-88bc-0d33c0ba2ba6"); VendorId nymeaVendorId = VendorId("2062d64d-3232-433c-88bc-0d33c0ba2ba6");