From 84dca158b3f83ee87522bf36bc90594b4a13aaeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 9 Aug 2023 11:29:33 +0200 Subject: [PATCH] LogEngine: provide possibility to disable the log engine --- libnymea-core/logging/logengineinfluxdb.cpp | 63 ++++++++++++++++++--- libnymea-core/logging/logengineinfluxdb.h | 38 ++++++++++++- libnymea-core/nymeacore.cpp | 11 +++- libnymea-core/nymeacore.h | 2 +- libnymea/logging/logengine.h | 3 + server/main.cpp | 7 ++- server/nymeaservice.cpp | 2 +- tests/testlib/nymeatestbase.cpp | 9 ++- tests/testlib/nymeatestbase.h | 4 +- 9 files changed, 120 insertions(+), 19 deletions(-) diff --git a/libnymea-core/logging/logengineinfluxdb.cpp b/libnymea-core/logging/logengineinfluxdb.cpp index ab41904c..4f065af1 100644 --- a/libnymea-core/logging/logengineinfluxdb.cpp +++ b/libnymea-core/logging/logengineinfluxdb.cpp @@ -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 . +* +* 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 #include #include #include -#include LogEngineInfluxDB::LogEngineInfluxDB(const QString &host, const QString &dbName, const QString &username, const QString &password, QObject *parent) : LogEngine{parent}, @@ -14,7 +43,10 @@ LogEngineInfluxDB::LogEngineInfluxDB(const QString &host, const QString &dbName, m_password(password) { m_nam = new QNetworkAccessManager(this); - initDB(); + + m_reinitTimer.setInterval(5000); + m_reinitTimer.setSingleShot(true); + connect(&m_reinitTimer, &QTimer::timeout, this, &LogEngineInfluxDB::initDB); } LogEngineInfluxDB::~LogEngineInfluxDB() @@ -39,7 +71,6 @@ Logger *LogEngineInfluxDB::registerLogSource(const QString &name, const QStringL return nullptr; } - // qCDebug(dcLogEngine()) << "Registering log source" << name << "with tags" << tagNames; Logger *logger = createLogger(name, tagNames, loggingType); @@ -196,7 +227,7 @@ void LogEngineInfluxDB::logEvent(Logger *logger, const QStringList &tags, const void LogEngineInfluxDB::processQueues() { - if (m_initStatus == InitStatusFailure) { + if (m_initStatus == InitStatusFailure || m_initStatus == InitStatusDisabled) { m_writeQueue.clear(); qDeleteAll(m_queryQueue); 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() { m_initStatus = InitStatusStarting; @@ -513,10 +560,10 @@ void LogEngineInfluxDB::createDB() if (status != QNetworkReply::NoError) { if (status == QNetworkReply::ConnectionRefusedError) { // Influx not up yet? trying again in 5 secs... - qCInfo(dcLogEngine) << "Failed to connect to influx... retrying in 5 seconds..."; - QTimer::singleShot(5000, this, [=](){ - initDB(); - }); + if (m_initStatus != InitStatusDisabled) { + qCInfo(dcLogEngine) << "Failed to connect to influx... retrying in 5 seconds..."; + m_reinitTimer.start(); + } return; } qCCritical(dcLogEngine()) << "Unable to connect to InfluxDB"; diff --git a/libnymea-core/logging/logengineinfluxdb.h b/libnymea-core/logging/logengineinfluxdb.h index d03a9933..b421db89 100644 --- a/libnymea-core/logging/logengineinfluxdb.h +++ b/libnymea-core/logging/logengineinfluxdb.h @@ -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 . +* +* 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 #define LOGENGINEINFLUXDB_H #include "logging/logengine.h" #include +#include #include #include #include @@ -33,7 +64,8 @@ public: InitStatusNone, InitStatusStarting, InitStatusOK, - InitStatusFailure + InitStatusFailure, + InitStatusDisabled }; Q_ENUM(InitStatus) @@ -51,6 +83,9 @@ public: bool jobsRunning() const override; void clear(const QString &source) override; + void enable() override; + void disable() override; + private: void initDB(); void createRetentionPolicies(); @@ -72,6 +107,7 @@ private: }; InitStatus m_initStatus = InitStatusNone; + QTimer m_reinitTimer; QNetworkAccessManager *m_nam = nullptr; diff --git a/libnymea-core/nymeacore.cpp b/libnymea-core/nymeacore.cpp index 9c9d91a0..d68962e7 100644 --- a/libnymea-core/nymeacore.cpp +++ b/libnymea-core/nymeacore.cpp @@ -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(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); 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); + if (disableLogEngine) { + m_logEngine->disable(); + } else { + m_logEngine->enable(); + } + m_logger = m_logEngine->registerLogSource("core", {"event"}); qCDebug(dcCore) << "Creating Thing Manager (locale:" << m_configuration->locale() << ")"; @@ -340,7 +345,7 @@ ExperienceManager *NymeaCore::experienceManager() const return m_experienceManager; } -LogEngine* NymeaCore::logEngine() const +LogEngine *NymeaCore::logEngine() const { return m_logEngine; } diff --git a/libnymea-core/nymeacore.h b/libnymea-core/nymeacore.h index 1f6935ac..84041e81 100644 --- a/libnymea-core/nymeacore.h +++ b/libnymea-core/nymeacore.h @@ -92,7 +92,7 @@ public: static NymeaCore* instance(); ~NymeaCore(); - void init(const QStringList &additionalInterfaces = QStringList()); + void init(const QStringList &additionalInterfaces = QStringList(), bool disableLogEngine = false); void destroy(nymeaserver::NymeaCore::ShutdownReason reason); RuleEngine::RuleError removeRule(const RuleId &id); diff --git a/libnymea/logging/logengine.h b/libnymea/logging/logengine.h index c0452d34..62e6c2af 100644 --- a/libnymea/logging/logengine.h +++ b/libnymea/logging/logengine.h @@ -54,6 +54,9 @@ public: virtual bool jobsRunning() const = 0; virtual void clear(const QString &source) = 0; + virtual void enable() = 0; + virtual void disable() = 0; + signals: void logEntryAdded(const LogEntry &entry); diff --git a/server/main.cpp b/server/main.cpp index b6f5be3b..2c78b4ca 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -52,6 +52,7 @@ #include "nymeadbusservice.h" #include "nymeaapplication.h" #include "loggingcategories.h" +#include "logging/logengine.h" #include "version.h" 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"); parser.addOption(interfacesOption); + QCommandLineOption noLogDbOption({"m", "no-logengine"}, QCoreApplication::translate("nymea", "Disable the influx DB log engine.")); + parser.addOption(noLogDbOption); + parser.process(application); // Open the logfile, if any specified @@ -230,12 +234,13 @@ int main(int argc, char *argv[]) } // create core instance - NymeaCore::instance()->init(parser.values(interfacesOption)); + NymeaCore::instance()->init(parser.values(interfacesOption), parser.isSet(noLogDbOption)); int ret = application.exec(); closeLogFile(); return ret; } + // FIXME: the background service should get the arguments too NymeaService service(argc, argv); int ret = service.exec(); closeLogFile(); diff --git a/server/nymeaservice.cpp b/server/nymeaservice.cpp index f1b40eb7..4dc70707 100644 --- a/server/nymeaservice.cpp +++ b/server/nymeaservice.cpp @@ -82,8 +82,8 @@ void NymeaService::start() fprintf(stdout, "Could not create nymea settings directory %s", qPrintable(NymeaSettings::settingsPath())); exit(EXIT_FAILURE); } - qCDebug(dcApplication) << "====================================="; + qCDebug(dcApplication) << "====================================="; qCDebug(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started as daemon."; qCDebug(dcApplication) << "====================================="; NymeaCore::instance(); diff --git a/tests/testlib/nymeatestbase.cpp b/tests/testlib/nymeatestbase.cpp index 39dc2d3a..8391f2ff 100644 --- a/tests/testlib/nymeatestbase.cpp +++ b/tests/testlib/nymeatestbase.cpp @@ -54,10 +54,13 @@ NymeaTestBase::NymeaTestBase(QObject *parent) : QCoreApplication::instance()->setOrganizationName("nymea-test"); } -void NymeaTestBase::initTestCase(const QString &loggingRules) +void NymeaTestBase::initTestCase(const QString &loggingRules, bool disableLogEngine) { 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 NymeaSettings rulesSettings(NymeaSettings::SettingsRoleRules); rulesSettings.clear(); @@ -84,7 +87,7 @@ void NymeaTestBase::initTestCase(const QString &loggingRules) // Start the server qCDebug(dcTests()) << "Setting up nymea core instance"; - NymeaCore::instance()->init(); + NymeaCore::instance()->init(QStringList(), m_disableLogEngine); // Wait unitl the server is initialized QSignalSpy coreInitializedSpy(NymeaCore::instance(), SIGNAL(initialized())); @@ -432,7 +435,7 @@ void NymeaTestBase::restartServer() qCDebug(dcTests()) << "Tearing down server instance"; NymeaCore::instance()->destroy(NymeaCore::ShutdownReasonRestart); qCDebug(dcTests()) << "Restarting server instance"; - NymeaCore::instance()->init(); + NymeaCore::instance()->init(QStringList(), m_disableLogEngine); QSignalSpy coreSpy(NymeaCore::instance(), SIGNAL(initialized())); coreSpy.wait(); m_mockTcpServer = MockTcpServer::servers().first(); diff --git a/tests/testlib/nymeatestbase.h b/tests/testlib/nymeatestbase.h index edea3ccb..8c528e7d 100644 --- a/tests/testlib/nymeatestbase.h +++ b/tests/testlib/nymeatestbase.h @@ -51,7 +51,7 @@ public: explicit NymeaTestBase(QObject *parent = nullptr); protected slots: - void initTestCase(const QString &loggingRules = QString()); + void initTestCase(const QString &loggingRules = QString(), bool disableLogEngine = false); void cleanupTestCase(); void cleanup(); @@ -130,6 +130,8 @@ private: void createMock(); protected: + bool m_disableLogEngine = false; + PluginId mockPluginId = PluginId("727a4a9a-c187-446f-aadf-f1b2220607d1"); VendorId nymeaVendorId = VendorId("2062d64d-3232-433c-88bc-0d33c0ba2ba6");