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

LOG: Add logger to Vivy

This is a slightly more complicated logger than what is done for lektor.
The process to create a logger is the following:

{ // In scope
std::shared_ptr<LogSink> mySink   = VIVY_NEW_LOG_SINK();
std::shared_ptr<Logger> appLog    = VIVY_GET_LOGGER(mySink, "APPLICATION");
std::shared_ptr<Logger> scriptLog = VIVY_GET_LOGGER(mySink, "SCRIPT");
// ...
VIVY_LOG_WARN(appLog) << "This is" << ' ' << "very usefull!";
// ...
} // Will clear all loggers
parent 18ae278e
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion!21Add clean logs support + dependent MR
#include "Log.hh"
using namespace Vivy;
LogMessage::~LogMessage() noexcept { parentLogger->sendLogMessage(*this); }
Logger::~Logger() noexcept { parentLogSink->closeLoggerClient(this); }
void
LogSink::closeLoggerClient(Logger *const logger) noexcept
{
}
LogMessage
Logger::logEvent(const char *fileName, const char *functionName, const int lineNumber,
const LogLevel logSeverity) noexcept
{
return LogMessage(this, LogMessage::Header{ .fileName = fileName,
.functionName = functionName,
.severity = logSeverity,
.lineNumberInFile = lineNumber });
}
void
Logger::sendLogMessage(const LogMessage &msg) const noexcept
{
}
LogMessage::LogMessage(Logger *const logger, const LogMessage::Header hdr) noexcept
: messageHeader(hdr)
, parentLogger(logger)
{
}
LogMessage &
LogMessage::operator<<(const std::string &) noexcept
{
return *this;
}
LogMessage &
LogMessage::operator<<(const int) noexcept
{
return *this;
}
LogMessage &
LogMessage::operator<<(const long) noexcept
{
return *this;
}
#pragma once
#include "Utils.hh"
#include <sstream>
#define VIVY_NEW_LOG_SINK() LogSink::newSink()
#define VIVY_GET_LOGGER(sink, cat) sink->createClient(cat)
#define VIVY_LOG_WITH_LEVEL(log, level) log->logEvent(__FILE__, __function__, __LINE__, level)
#define VIVY_LOG_WARN(log) VIVY_LOG_WITH_LEVEL(log, LogLevel::Warning)
#define VIVY_LOG_DEBUG(log) VIVY_LOG_WITH_LEVEL(log, LogLevel::Debug)
#define VIVY_LOG_INFO(log) VIVY_LOG_WITH_LEVEL(log, LogLevel::Info)
#define VIVY_LOG_ERR(log) VIVY_LOG_WITH_LEVEL(log, LogLevel::Error)
#define VIVY_LOG_FATAL(log) VIVY_LOG_WITH_LEVEL(log, LogLevel::Critical)
namespace Vivy
{
class VivyApplication;
class VivyCli;
class LogSink;
class Logger;
class LogMessage;
// The severity of an event. Critical will cause the LogSink to flush all
// messages to its emeters and then abort.
enum class LogLevel : int {
Critical = std::numeric_limits<int>::max(), // Will trigger qFatal
Error = 4,
Warning = 3,
Info = 2,
Debug = 1
};
// Message to be logged, constructed by a logger then send
class LogMessage final {
friend class Logger;
struct Header final {
const char *fileName;
const char *functionName;
const LogLevel severity;
const int lineNumberInFile;
};
LogMessage(Logger *const, const Header) noexcept;
const Header messageHeader;
const chrono::milliseconds timeStamp{ duration_cast<chrono::milliseconds>(
chrono::system_clock::now().time_since_epoch()) };
static constexpr inline size_t messageBufferLength = 2048;
std::array<char, messageBufferLength> textBuffer{};
std::size_t indexInArray{ 0 };
Logger *const parentLogger;
public:
// The message will be send on destruction
~LogMessage() noexcept;
LogMessage &operator<<(const std::string &) noexcept;
LogMessage &operator<<(const int) noexcept;
LogMessage &operator<<(const long) noexcept;
};
// A logger class, a client to LogSink. Will generate and send instances of
// LogMessage.
class Logger final {
VIVY_UNMOVABLE_OBJECT(Logger)
friend class LogSink;
friend class std::shared_ptr<Logger>;
LogSink *const parentLogSink;
const std::string logCategory;
static std::string anyStringToStdString(StringType auto const &str) noexcept
{
std::string ret;
const std::size_t size = str.size();
ret.resize(size);
for (std::size_t i = 0; i < size; ++i)
ret[i] = str[i];
return ret;
}
// Templated constructor, construct from anything that can be considered as
// a string.
Logger(LogSink *const sink, StringType auto const &category) noexcept
: parentLogSink(sink)
, logCategory(anyStringToStdString(category))
{
}
public:
~Logger() noexcept;
void sendLogMessage(const LogMessage &) const noexcept;
LogMessage logEvent(const char *fileName, const char *functionName, const int lineNumber,
const LogLevel) noexcept;
};
// LogSink is the parent logger. It will recieve messages and display them to a
// console or to std::cerr or to a file, etc.
class LogSink final {
VIVY_UNMOVABLE_OBJECT(LogSink)
LogSink() noexcept;
public:
static std::shared_ptr<LogSink> newSink() noexcept;
~LogSink() noexcept;
void closeLoggerClient(Logger *const) noexcept;
std::shared_ptr<Logger> createClient(StringType auto const &category) noexcept
{
auto ret = std::make_shared<Logger>(this, category);
clientLoggers.push_back(ret);
return ret;
}
private:
std::vector<LogMessage> messageQueue;
std::vector<std::shared_ptr<Logger>> clientLoggers;
};
}
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