Skip to content
Extraits de code Groupes Projets
Vérifiée Valider fd87ea33 rédigé par Kubat's avatar Kubat
Parcourir les fichiers

LOG: Fix the log dispatch creation

parent f6996503
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion!21Add clean logs support + dependent MR
......@@ -5,8 +5,8 @@ namespace Vivy
{
LogSinkDispatcher::~LogSinkDispatcher() noexcept {}
StderrLogSinkDispatcher::StderrLogSinkDispatcher(LogSink *const sink) noexcept
: LogSinkDispatcher(sink, std::string_view{ "stderr" })
StderrLogSinkDispatcher::StderrLogSinkDispatcher() noexcept
: LogSinkDispatcher(std::string_view{ "stderr" })
{
}
......@@ -14,14 +14,15 @@ void
StderrLogSinkDispatcher::handleLogMessage(const std::string_view category,
const LogMessage &msg) noexcept
{
std::cerr << '[' << category << ']' << msg.getTextBuffer() << '\n';
std::cerr << '[' << category << "] " << msg.getTextBuffer() << '\n';
}
}
// Vivy::LogSink implementation
namespace Vivy
{
LogSink::~LogSink() noexcept {}
// Flush all messages before exiting
LogSink::~LogSink() noexcept { flush(); }
// Get the log message from the logger and add it to the sink's queue.
void
......@@ -53,11 +54,11 @@ LogSink::newSink() noexcept
return std::make_shared<makeSharedEnabler>();
}
// void
// LogSink::registerLogDispatcher(std::shared_ptr<LogSinkDispatcher> dispatcher) noexcept
// {
// logDispatchers.push_back(dispatcher);
// }
void
LogSink::registerLogDispatcher(std::shared_ptr<LogSinkDispatcher> dispatcher) noexcept
{
logDispatchers.push_back(dispatcher);
}
}
// Vivy::Logger implementation
......@@ -78,8 +79,6 @@ Logger::logEvent(const char *fileName, const char *functionName, const int lineN
.severity = logSeverity,
.lineNumberInFile = lineNumber });
}
Logger::~Logger() noexcept {}
}
// Vivy::LogMessage implementation
......
......@@ -2,7 +2,6 @@
#include "Utils.hh"
#define VIVY_NEW_LOG_SINK() LogSink::newSink()
#define VIVY_GET_LOGGER(sink, cat) std::make_shared<Logger>(sink.get(), cat)
#define VIVY_LOG_WITH_LEVEL(log, level) log->logEvent(__FILE__, __func__, __LINE__, level)
#define VIVY_LOG_WARN(log) VIVY_LOG_WITH_LEVEL(log, LogLevel::Warning)
......@@ -11,7 +10,9 @@
#define VIVY_LOG_ERR(log) VIVY_LOG_WITH_LEVEL(log, LogLevel::Error)
#define VIVY_LOG_FATAL(log) VIVY_LOG_WITH_LEVEL(log, LogLevel::Critical)
#define VIVY_DCL_LOG_SINK(sink) std::shared_ptr<LogSink> sink{ VIVY_NEW_LOG_SINK() };
#define VIVY_DCL_LOG_SINK(sink) std::shared_ptr<LogSink> sink{ LogSink::newSink() };
#define VIVY_DCL_LOG_DISPATCH(sink, name, dispatch) \
std::shared_ptr<dispatch> name{ sink->newDispatcher<dispatch>() };
#define VIVY_LOGGABLE_OBJECT(sink, name, logger) \
std::shared_ptr<Logger> logger{ VIVY_GET_LOGGER(sink, name) }; \
......@@ -41,6 +42,35 @@ enum class LogLevel : int {
None = std::numeric_limits<int>::min() // In option setup to disable logs
};
// A LogSinkDispatcher will excavate LogMessages from the Sink and do something
// with them (save to a file, display in stderr/Vivy console, etc).
class LogSinkDispatcher {
VIVY_UNMOVABLE_OBJECT(LogSinkDispatcher)
const std::string dispatcherName;
protected:
explicit LogSinkDispatcher(const std::string_view name) noexcept
: dispatcherName(name)
{
}
public:
const std::string_view getDispatcherName() const noexcept { return dispatcherName; }
virtual ~LogSinkDispatcher() noexcept;
virtual void handleLogMessage(const std::string_view, const LogMessage &) noexcept = 0;
};
// The stderr dispatcher for logs
class StderrLogSinkDispatcher : public LogSinkDispatcher {
VIVY_UNMOVABLE_OBJECT(StderrLogSinkDispatcher)
public:
explicit StderrLogSinkDispatcher() noexcept;
void handleLogMessage(const std::string_view, const LogMessage &) noexcept override;
};
// LogSink is the parent logger. It will recieve messages and display them to a
// console or to std::cerr or to a file, etc. The save to over file, etc will
// be donne by the LogSinkDispatcher.
......@@ -53,9 +83,18 @@ public:
static std::shared_ptr<LogSink> newSink() noexcept;
~LogSink() noexcept;
void registerLogDispatcher(std::shared_ptr<LogSinkDispatcher>) noexcept;
void recieveLogMessage(const Logger *const, LogMessage &&) noexcept;
void flush() noexcept;
template <Derived<LogSinkDispatcher> DispatcherType>
std::shared_ptr<DispatcherType> newDispatcher() noexcept
{
std::shared_ptr<DispatcherType> dispatch = std::make_shared<DispatcherType>();
registerLogDispatcher(dispatch);
return dispatch;
}
private:
std::mutex messageQueueLock{};
std::vector<std::tuple<const std::string_view, LogMessage>> messageQueue;
......@@ -106,28 +145,6 @@ public:
LogMessage &operator<<(const long) noexcept;
};
// A LogSinkDispatcher will excavate LogMessages from the Sink and do something
// with them (save to a file, display in stderr/Vivy console, etc).
class LogSinkDispatcher : public std::enable_shared_from_this<LogSinkDispatcher> {
VIVY_UNMOVABLE_OBJECT(LogSinkDispatcher)
const std::string dispatcherName;
protected:
explicit LogSinkDispatcher(LogSink *const, const std::string_view name) noexcept
: dispatcherName(name)
{
std::shared_ptr<LogSinkDispatcher> self = shared_from_this();
// sink->registerLogDispatcher(self);
}
public:
const std::string_view getDispatcherName() const noexcept { return dispatcherName; }
virtual ~LogSinkDispatcher() noexcept;
virtual void handleLogMessage(const std::string_view, const LogMessage &) noexcept = 0;
};
// A logger class, a client to LogSink. Will generate and send instances of
// LogMessage.
class Logger final : public std::enable_shared_from_this<Logger> {
......@@ -136,44 +153,19 @@ class Logger final : public std::enable_shared_from_this<Logger> {
LogSink *const parentLogSink;
const std::string logCategory;
static std::string anyStringToStdString(StringType auto const &str) noexcept
{
std::string ret;
std::size_t i;
const std::size_t size = str.size();
ret.resize(size);
for (i = 0; i < size && str[i]; ++i)
ret[i] = str[i];
ret.resize(i);
return ret;
}
public:
// Templated constructor, construct from anything that can be considered as
// a string.
explicit Logger(LogSink *const sink, const StringType auto category) noexcept
: parentLogSink(sink)
, logCategory(anyStringToStdString(category))
, logCategory(Utils::anyStringToStdString(category))
{
}
~Logger() noexcept;
const std::string_view getCategoryView() const noexcept
{
return std::string_view{ logCategory };
}
const std::string_view getCategoryView() const noexcept { return logCategory; }
void sendLogMessage(LogMessage &&) const noexcept;
LogMessage logEvent(const char *fileName, const char *functionName, const int lineNumber,
const LogLevel) noexcept;
};
class StderrLogSinkDispatcher : public LogSinkDispatcher {
VIVY_UNMOVABLE_OBJECT(StderrLogSinkDispatcher)
public:
explicit StderrLogSinkDispatcher(LogSink *const sink) noexcept;
void handleLogMessage(const std::string_view, const LogMessage &) noexcept override;
};
}
......@@ -123,7 +123,7 @@ uniqAndSort(std::vector<T> &vec) noexcept
}
// WARN: The V1 and V2 vectors need to be sorted before calling this function.
template <typename T> inline std::vector<T>
template <typename T> static inline std::vector<T>
sortedSetDifference(const std::vector<T> &v1, const std::vector<T> &v2)
{
std::vector<T> res{};
......@@ -136,6 +136,19 @@ sortedSetDifference(const std::vector<T> &v1, const std::vector<T> &v2)
return res;
}
static inline std::string
anyStringToStdString(StringType auto const &str) noexcept
{
std::string ret;
std::size_t i;
const std::size_t size = str.size();
ret.resize(size);
for (i = 0; i < size && str[i]; ++i)
ret[i] = str[i];
ret.resize(i);
return ret;
}
enum class DocumentType : quint64 {
/* Basic types */
Vivy = (1 << 1),
......
......@@ -42,6 +42,7 @@ class MainWindow;
class VivyApplication : public QApplication {
Q_OBJECT
VIVY_DCL_LOG_SINK(logSink)
VIVY_DCL_LOG_DISPATCH(logSink, stderrLogDispathcer, StderrLogSinkDispatcher)
VIVY_LOGGABLE_OBJECT(logSink, std::string_view("APPLICATION"), logger)
public:
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter