Issue #15 Classes for sharing the history of log messages

This commit is contained in:
Mat Sutcliffe
2020-04-15 18:18:43 +01:00
parent 151810d6fc
commit 7382564633
7 changed files with 144 additions and 1 deletions

View File

@@ -18,6 +18,7 @@
#include "blackcore/context/contextownaircraftimpl.h" #include "blackcore/context/contextownaircraftimpl.h"
#include "blackcore/context/contextsimulator.h" #include "blackcore/context/contextsimulator.h"
#include "blackmisc/sharedstate/datalinkdbus.h" #include "blackmisc/sharedstate/datalinkdbus.h"
#include "blackmisc/loghistory.h"
#include "blackcore/context/contextsimulatorimpl.h" #include "blackcore/context/contextsimulatorimpl.h"
#include "blackcore/data/launchersetup.h" #include "blackcore/data/launchersetup.h"
#include "blackcore/corefacadeconfig.h" #include "blackcore/corefacadeconfig.h"
@@ -123,6 +124,15 @@ namespace BlackCore
qFatal("Invalid application context mode"); qFatal("Invalid application context mode");
} }
// shared log history
m_logHistorySource = new CLogHistorySource(this);
m_logHistorySource->initialize(m_dataLinkDBus);
if (m_config.hasLocalCore())
{
m_logHistory = new CLogHistory(this);
m_logHistory->initialize(m_dataLinkDBus);
}
// contexts // contexts
if (m_contextApplication) { m_contextApplication->deleteLater(); } if (m_contextApplication) { m_contextApplication->deleteLater(); }
m_contextApplication = IContextApplication::create(this, m_config.getModeApplication(), m_dbusServer, m_dbusConnection); m_contextApplication = IContextApplication::create(this, m_config.getModeApplication(), m_dbusServer, m_dbusConnection);
@@ -331,6 +341,10 @@ namespace BlackCore
disconnect(this); disconnect(this);
// tear down shared state infrastructure // tear down shared state infrastructure
delete m_logHistory;
m_logHistory = nullptr;
delete m_logHistorySource;
m_logHistorySource = nullptr;
delete m_dataLinkDBus; delete m_dataLinkDBus;
m_dataLinkDBus = nullptr; m_dataLinkDBus = nullptr;

View File

@@ -26,6 +26,8 @@
namespace BlackMisc namespace BlackMisc
{ {
class CDBusServer; class CDBusServer;
class CLogHistory;
class CLogHistorySource;
namespace SharedState namespace SharedState
{ {
@@ -68,6 +70,9 @@ namespace BlackCore
//! Destructor //! Destructor
virtual ~CCoreFacade() override { this->gracefulShutdown(); } virtual ~CCoreFacade() override { this->gracefulShutdown(); }
//! Transport mechanism for sharing state between applications
BlackMisc::SharedState::CDataLinkDBus *getDataLinkDBus() { return this->m_dataLinkDBus; }
//! DBus server (if applicable) //! DBus server (if applicable)
const BlackMisc::CDBusServer *getDBusServer() const { return this->m_dbusServer; } const BlackMisc::CDBusServer *getDBusServer() const { return this->m_dbusServer; }
@@ -191,6 +196,8 @@ namespace BlackCore
// shared state infrastructure // shared state infrastructure
BlackMisc::SharedState::CDataLinkDBus *m_dataLinkDBus = nullptr; BlackMisc::SharedState::CDataLinkDBus *m_dataLinkDBus = nullptr;
BlackMisc::CLogHistory *m_logHistory = nullptr;
BlackMisc::CLogHistorySource *m_logHistorySource = nullptr;
// contexts: // contexts:
// There is a reason why we do not use smart pointers here. When the context is deleted // There is a reason why we do not use smart pointers here. When the context is deleted

View File

@@ -73,6 +73,9 @@ namespace BlackCore
//! Local settings? //! Local settings?
bool hasLocalSettings() const { return m_settings == Local || m_settings == LocalInDBusServer; } bool hasLocalSettings() const { return m_settings == Local || m_settings == LocalInDBusServer; }
//! Local core?
bool hasLocalCore() const { return m_application == Local || m_application == LocalInDBusServer; }
//! Requires server (at least one in server)? //! Requires server (at least one in server)?
bool requiresDBusSever() const; bool requiresDBusSever() const;

View File

@@ -0,0 +1,41 @@
/* Copyright (C) 2020
* swift Project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#include "blackmisc/loghistory.h"
#include "blackmisc/loghandler.h"
namespace BlackMisc
{
CLogHistory::CLogHistory(QObject *parent) : CListJournal(parent)
{
}
CLogHistorySource::CLogHistorySource(QObject *parent) : CListMutator(parent)
{
connect(CLogHandler::instance(), &CLogHandler::localMessageLogged, this, [this](auto&&... args)
{
this->addElement(args...);
});
}
CLogHistoryReplica::CLogHistoryReplica(QObject* parent) : CListObserver(parent)
{
}
void CLogHistoryReplica::onElementAdded(const CStatusMessage &msg)
{
emit elementAdded(msg);
}
void CLogHistoryReplica::onElementsReplaced(const CStatusMessageList &msgs)
{
emit elementsReplaced(msgs);
}
}

View File

@@ -0,0 +1,75 @@
/* Copyright (C) 2020
* swift Project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_LOGHISTORY_H
#define BLACKMISC_LOGHISTORY_H
#include "blackmisc/sharedstate/datalink.h"
#include "blackmisc/sharedstate/listjournal.h"
#include "blackmisc/sharedstate/listmutator.h"
#include "blackmisc/sharedstate/listobserver.h"
#include "blackmisc/statusmessagelist.h"
#include "blackmisc/logpattern.h"
#include <QObject>
namespace BlackMisc
{
/*!
* Records all log messages to a list that persists for the lifetime of the application.
*/
class BLACKMISC_EXPORT CLogHistory : public SharedState::CListJournal<CStatusMessageList>
{
Q_OBJECT
BLACK_SHARED_STATE_CHANNEL("swift.log.history")
public:
//! Constructor.
CLogHistory(QObject *parent = nullptr);
};
/*!
* Allows distributed insertion of log messages into a central CLogHistory.
*/
class BLACKMISC_EXPORT CLogHistorySource : public SharedState::CListMutator<CStatusMessageList>
{
Q_OBJECT
BLACK_SHARED_STATE_CHANNEL("swift.log.history")
public:
//! Constructor.
CLogHistorySource(QObject *parent = nullptr);
};
/*!
* Allows distributed access to the log messages of a central CLogHistory.
*/
class BLACKMISC_EXPORT CLogHistoryReplica : public SharedState::CListObserver<CStatusMessageList, CLogPattern>
{
Q_OBJECT
BLACK_SHARED_STATE_CHANNEL("swift.log.history")
public:
//! Constructor.
CLogHistoryReplica(QObject *parent = nullptr);
signals:
//! Signal emitted for each new log message.
void elementAdded(const BlackMisc::CStatusMessage &msg);
//! Signal emitted when the whole history is updated wholesale.
void elementsReplaced(const BlackMisc::CStatusMessageList &msgs);
private:
virtual void onElementAdded(const CStatusMessage &msg) override final;
virtual void onElementsReplaced(const CStatusMessageList &msgs) override final;
};
}
#endif

View File

@@ -328,7 +328,7 @@ namespace BlackMisc
QString categories = m_strings.values().join("|"); // clazy:exclude=container-anti-pattern QString categories = m_strings.values().join("|"); // clazy:exclude=container-anti-pattern
switch (m_strategy) switch (m_strategy)
{ {
case Everything: strategy = "none"; break; case Everything: strategy = "all"; break;
case ExactMatch: strategy = "exact match:" + categories; break; case ExactMatch: strategy = "exact match:" + categories; break;
case AnyOf: strategy = "any of:" + categories; break; case AnyOf: strategy = "any of:" + categories; break;
case AllOf: strategy = "all of:" + categories; break; case AllOf: strategy = "all of:" + categories; break;

View File

@@ -93,6 +93,9 @@ namespace BlackMisc
//! Returns true if the given message matches this pattern. //! Returns true if the given message matches this pattern.
bool match(const CStatusMessage &message) const; bool match(const CStatusMessage &message) const;
//! This class acts as a SharedState filter when stored in a CVariant.
bool matches(const CVariant &message) const { return match(message.to<CStatusMessage>()); }
//! Returns true if this pattern is a proper subset of the other pattern. //! Returns true if this pattern is a proper subset of the other pattern.
//! \see https://en.wikipedia.org/wiki/Proper_subset //! \see https://en.wikipedia.org/wiki/Proper_subset
//! \details Pattern A is a proper subset of pattern B iff pattern B would match every category which pattern A matches, //! \details Pattern A is a proper subset of pattern B iff pattern B would match every category which pattern A matches,