mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-31 12:55:33 +08:00
refs #338 CLogHandler filtering messages using CLogPattern instead of the old prefix-based approach.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include "loghandler.h"
|
||||
#include "algorithm.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QMetaMethod>
|
||||
|
||||
@@ -43,27 +44,34 @@ namespace BlackMisc
|
||||
qInstallMessageHandler(m_oldHandler);
|
||||
}
|
||||
|
||||
CLogCategoryHandler *CLogHandler::handlerForCategoryPrefix(const QString &category)
|
||||
CLogPatternHandler *CLogHandler::handlerForPattern(const CLogPattern &pattern)
|
||||
{
|
||||
Q_ASSERT(thread() == QThread::currentThread());
|
||||
|
||||
if (! m_categoryPrefixHandlers.contains(category))
|
||||
auto finder = [ & ](const PatternPair &pair) { return pair.first == pattern; };
|
||||
auto comparator = [](const PatternPair &a, const PatternPair &b) { return a.first.isProperSubsetOf(b.first); };
|
||||
|
||||
auto it = std::find_if(m_patternHandlers.begin(), m_patternHandlers.end(), finder);
|
||||
if (it == m_patternHandlers.end())
|
||||
{
|
||||
m_categoryPrefixHandlers[category] = new CLogCategoryHandler(this, m_enableFallThrough);
|
||||
|
||||
auto *handler = new CLogPatternHandler(this, m_enableFallThrough);
|
||||
topologicallySortedInsert(m_patternHandlers, PatternPair(pattern, handler), comparator);
|
||||
return handler;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
return m_categoryPrefixHandlers[category];
|
||||
}
|
||||
|
||||
QList<CLogCategoryHandler *> CLogHandler::handlersForCategories(const CLogCategoryList &categories) const
|
||||
QList<CLogPatternHandler *> CLogHandler::handlersForMessage(const CStatusMessage &message) const
|
||||
{
|
||||
QList<CLogCategoryHandler *> m_handlers;
|
||||
for (auto i = m_categoryPrefixHandlers.begin(); i != m_categoryPrefixHandlers.end(); ++i)
|
||||
QList<CLogPatternHandler *> m_handlers;
|
||||
for (const auto &pair : m_patternHandlers)
|
||||
{
|
||||
if (categories.anyStartWith(i.key()))
|
||||
if (pair.first.match(message))
|
||||
{
|
||||
m_handlers.push_back(i.value());
|
||||
m_handlers.push_back(pair.second);
|
||||
}
|
||||
}
|
||||
return m_handlers;
|
||||
@@ -74,13 +82,13 @@ namespace BlackMisc
|
||||
Q_ASSERT(thread() == QThread::currentThread());
|
||||
|
||||
m_enableFallThrough = enable;
|
||||
for (auto *handler : m_categoryPrefixHandlers.values())
|
||||
for (const auto &pair : m_patternHandlers)
|
||||
{
|
||||
handler->enableConsoleOutput(enable);
|
||||
pair.second->enableConsoleOutput(enable);
|
||||
}
|
||||
}
|
||||
|
||||
bool CLogHandler::isFallThroughEnabled(const QList<CLogCategoryHandler *> &handlers) const
|
||||
bool CLogHandler::isFallThroughEnabled(const QList<CLogPatternHandler *> &handlers) const
|
||||
{
|
||||
for (const auto *handler : handlers)
|
||||
{
|
||||
@@ -108,7 +116,7 @@ namespace BlackMisc
|
||||
{
|
||||
collectGarbage();
|
||||
|
||||
auto handlers = handlersForCategories(statusMessage.getCategories());
|
||||
auto handlers = handlersForMessage(statusMessage);
|
||||
|
||||
if (isFallThroughEnabled(handlers))
|
||||
{
|
||||
|
||||
@@ -12,13 +12,14 @@
|
||||
|
||||
//! \file
|
||||
|
||||
#include "logpattern.h"
|
||||
#include "statusmessage.h"
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
class CLogCategoryHandler;
|
||||
class CLogPatternHandler;
|
||||
|
||||
/*!
|
||||
* Class for subscribing to log messages.
|
||||
@@ -41,9 +42,9 @@ namespace BlackMisc
|
||||
//! Tell the CLogHandler to install itself with qInstallMessageHandler.
|
||||
void install();
|
||||
|
||||
//! Return a category handler for subscribing to all messages with a category starting with the given prefix.
|
||||
//! Return a pattern handler for subscribing to all messages which match the given pattern.
|
||||
//! \warning This must only be called from the main thread.
|
||||
CLogCategoryHandler *handlerForCategoryPrefix(const QString &prefix);
|
||||
CLogPatternHandler *handlerForPattern(const CLogPattern &pattern);
|
||||
|
||||
signals:
|
||||
//! Emitted when a message is logged in this process.
|
||||
@@ -67,34 +68,38 @@ namespace BlackMisc
|
||||
void collectGarbage();
|
||||
QtMessageHandler m_oldHandler = nullptr;
|
||||
bool m_enableFallThrough = true;
|
||||
bool isFallThroughEnabled(const QList<CLogCategoryHandler *> &handlers) const;
|
||||
QMap<QString, CLogCategoryHandler *> m_categoryPrefixHandlers;
|
||||
QList<CLogCategoryHandler *> handlersForCategories(const CLogCategoryList &categories) const;
|
||||
bool isFallThroughEnabled(const QList<CLogPatternHandler *> &handlers) const;
|
||||
using PatternPair = std::pair<CLogPattern, CLogPatternHandler *>;
|
||||
QList<PatternPair> m_patternHandlers;
|
||||
QList<CLogPatternHandler *> handlersForMessage(const CStatusMessage &message) const;
|
||||
};
|
||||
|
||||
/*!
|
||||
* A class for subscribing to log messages in particular categories.
|
||||
* \sa CLogHandler::handlerForCategory
|
||||
* A class for subscribing to log messages which match particular patterns.
|
||||
* \see CLogHandler::handlerForPattern
|
||||
*/
|
||||
class CLogCategoryHandler : public QObject
|
||||
class CLogPatternHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
/*!
|
||||
* Enable or disable the default Qt handler for messages in relevant categories.
|
||||
* This can override the setting of the parent CLogHandler.
|
||||
* Enable or disable the default Qt handler for messages which match the relevant pattern.
|
||||
*
|
||||
* The setting of this property in one CLogPatternHandler can override the setting in another
|
||||
* CLogPatternHandler or the base CLogHandler, if this handler's pattern is a subset of the
|
||||
* other handler's pattern. Which is to say, more specific patterns can override less specific patterns.
|
||||
*/
|
||||
void enableConsoleOutput(bool enable) { Q_ASSERT(thread() == QThread::currentThread()); m_enableFallThrough = enable; }
|
||||
|
||||
signals:
|
||||
/*!
|
||||
* Emitted when a message is logged in a relevant category.
|
||||
* Emitted when a message is logged which matches the relevant pattern.
|
||||
*
|
||||
* When all slots are disconnected from this signal, the CLogCategoryHandler could be deleted.
|
||||
* When all slots are disconnected from this signal, the CLogPatternHandler could be deleted.
|
||||
*
|
||||
* Note that if a message matches more that one category handler, then this signal will be emitted for all of them,
|
||||
* so if a slot is connected to all of them then it will be called multiple times. Use the methods
|
||||
* Note that if a message matches more that one handler's pattern, then this signal will be emitted for all of
|
||||
* those handlers, so if a slot is connected to all of them then it will be called multiple times. Use the methods
|
||||
* CStatusMessage::markAsHandledBy() and CStatusMessage::wasHandledBy() to detect this case in the slot and avoid
|
||||
* multiple handlings of the same message. Caveat: for this to work, the slot must take its argument by non-const
|
||||
* reference, and be connected by Qt::DirectConnection (i.e. the receiver is in the same thread as the CLogHandler).
|
||||
@@ -103,7 +108,7 @@ namespace BlackMisc
|
||||
|
||||
private:
|
||||
friend class CLogHandler;
|
||||
CLogCategoryHandler(QObject *parent, bool enableFallThrough) : QObject(parent), m_enableFallThrough(enableFallThrough) {}
|
||||
CLogPatternHandler(QObject *parent, bool enableFallThrough) : QObject(parent), m_enableFallThrough(enableFallThrough) {}
|
||||
bool m_enableFallThrough;
|
||||
|
||||
bool canBeDeleted()
|
||||
|
||||
Reference in New Issue
Block a user