From 1bda85413996d835496f37b109c6c57919e3d244 Mon Sep 17 00:00:00 2001 From: blue Date: Mon, 17 Mar 2025 17:13:52 +0200 Subject: [PATCH] Logging is easier now, assigned in runtime group is now stored in config --- CMakeLists.txt | 2 +- component/CMakeLists.txt | 2 -- component/config.cpp | 28 ++++++++++++++++++++-------- component/config.h | 11 ++++++++--- component/core.cpp | 9 ++++++--- component/core.h | 4 ++-- component/router.cpp | 18 +++++++++++------- component/router.h | 8 ++++---- connection/connection.cpp | 19 ++++++++++--------- connection/connection.h | 2 ++ jay.cpp | 2 +- module/actor.cpp | 4 ++-- module/module.cpp | 7 ++++++- module/module.h | 8 ++++++-- shared/CMakeLists.txt | 4 ++++ shared/loggable.cpp | 29 +++++++++++++++++++++++++++++ shared/loggable.h | 29 +++++++++++++++++++++++++++++ {component => shared}/logger.cpp | 16 ++++++++-------- {component => shared}/logger.h | 4 ++++ 19 files changed, 153 insertions(+), 53 deletions(-) create mode 100644 shared/loggable.cpp create mode 100644 shared/loggable.h rename {component => shared}/logger.cpp (87%) rename {component => shared}/logger.h (97%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44e59d3..939e3bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(jay LANGUAGES CXX ) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) cmake_policy(SET CMP0076 NEW) diff --git a/component/CMakeLists.txt b/component/CMakeLists.txt index 7e77ed0..ba46907 100644 --- a/component/CMakeLists.txt +++ b/component/CMakeLists.txt @@ -1,6 +1,5 @@ set(SOURCES config.cpp - logger.cpp actor.cpp router.cpp core.cpp @@ -8,7 +7,6 @@ set(SOURCES set(HEADERS config.h - logger.h actor.h router.h core.h diff --git a/component/config.cpp b/component/config.cpp index d3838e5..418544d 100644 --- a/component/config.cpp +++ b/component/config.cpp @@ -3,7 +3,8 @@ #include "config.h" -Config::Config(const std::string& path): +Config::Config(const std::filesystem::path& path): + path(path), root(YAML::LoadFile(path)) {} @@ -23,21 +24,21 @@ std::string Config::getFullJID() const { return getBareJID() + "/" + getResource(); } -Logger::Level Config::getLogLevel() const { +Shared::Logger::Level Config::getLogLevel() const { std::string level = root["logLevel"].as("info"); if (level == "trace") - return Logger::trace; + return Shared::Logger::trace; else if (level == "debug") - return Logger::debug; + return Shared::Logger::debug; else if (level == "info") - return Logger::info; + return Shared::Logger::info; else if (level == "warn" || level == "warning") - return Logger::warning; + return Shared::Logger::warning; else if (level == "error") - return Logger::error; + return Shared::Logger::error; else - return Logger::info; + return Shared::Logger::info; } gloox::TLSPolicy Config::getTLSPolicy() const { @@ -115,3 +116,14 @@ Shared::Responses Config::getResponses() const { return responses; } + +void Config::setActors(const std::map& actors) { + YAML::Node cfg = root["actors"] = YAML::Node(YAML::NodeType::Map); + + for (const std::pair& pair : actors) + cfg[pair.first] = pair.second; + + std::ofstream out(path); + out << YAML::Dump(root); + out.close(); +} diff --git a/component/config.h b/component/config.h index 9169159..86138c9 100644 --- a/component/config.h +++ b/component/config.h @@ -5,6 +5,8 @@ #include #include +#include +#include #include "gloox/gloox.h" @@ -12,7 +14,7 @@ #include "shared/definitions.h" #include "shared/result.h" -#include "logger.h" +#include "shared/logger.h" class Config { public: @@ -23,7 +25,7 @@ public: }; public: - Config(const std::string& path); + Config(const std::filesystem::path& path); bool isValid() const; @@ -32,11 +34,14 @@ public: std::string getPassword() const; std::string getResource() const; std::map getActors() const; - Logger::Level getLogLevel() const; + Shared::Logger::Level getLogLevel() const; gloox::TLSPolicy getTLSPolicy() const; Module getModuleConfig(const std::string& name) const; Shared::Responses getResponses() const; + void setActors(const std::map& actors); + private: + std::filesystem::path path; YAML::Node root; }; diff --git a/component/core.cpp b/component/core.cpp index ad89f2d..ae2b3bd 100644 --- a/component/core.cpp +++ b/component/core.cpp @@ -15,7 +15,7 @@ Core::Core(const std::string& configPath): void Core::send(const std::string& jid, const std::string& body) { std::shared_ptr cn = connection.lock(); if (!cn) { - logger.log(Logger::warning, "Couldn't send a message to " + jid + ", connection is not available", {"Core"}); + logger.log(Shared::Logger::warning, "Couldn't send a message to " + jid + ", connection is not available", {"Core"}); return; } @@ -37,12 +37,15 @@ void Core::initialize(const std::shared_ptr& cn) { void Core::setGroup(const std::string& jid, const std::string& group) { router.registerActor(jid, group); - // todo save config + + std::map actors = router.getActors(); + actors["default"] = router.getDefaultGroup(); + config.setActors(actors); } void Core::initializeActors() { for (const std::pair& pair : config.getActors()) { - logger.log(Logger::info, "registering actor " + pair.first + " as " + pair.second, {"Core"}); + logger.log(Shared::Logger::info, "registering actor " + pair.first + " as " + pair.second, {"Core"}); router.registerActor(pair.first, pair.second); } } diff --git a/component/core.h b/component/core.h index 6a63a66..3272694 100644 --- a/component/core.h +++ b/component/core.h @@ -6,9 +6,9 @@ #include #include +#include "shared/logger.h" #include "config.h" #include "router.h" -#include "logger.h" class Connection; @@ -22,7 +22,7 @@ public: public: Config config; - Logger logger; + Shared::Logger logger; Router router; private: diff --git a/component/router.cpp b/component/router.cpp index b6314a9..2da0a58 100644 --- a/component/router.cpp +++ b/component/router.cpp @@ -6,8 +6,8 @@ #include "module/module.h" #include "connection/connection.h" -Router::Router(const Logger& logger): - logger(logger), +Router::Router(const Shared::Logger& logger): + Shared::Loggable(logger, {"Router"}), modules(), actors(), defaultGroup("Stranger"), @@ -44,13 +44,13 @@ void Router::routeMessage(const std::string& sender, const std::string& body) { std::vector args = Module::Module::split(body); Modules::iterator mItr = modules.find(args[0]); if (mItr == modules.end()) { - logger.log(Logger::debug, "could not find module \"" + args[0] + "\" to handle message from " + sender, {"Router"}); + debug("could not find module \"" + args[0] + "\" to handle message from " + sender); return onMessageResult(Shared::unhandled, sender); } std::shared_ptr module = mItr->second.lock(); if (!module) { - logger.log(Logger::error, "could not lock module \"" + mItr->first + "\" to handle message from " + sender, {"Router"}); + error("could not lock module \"" + mItr->first + "\" to handle message from " + sender); return onMessageResult(Shared::error, sender); } @@ -59,9 +59,9 @@ void Router::routeMessage(const std::string& sender, const std::string& body) { try { result = module->message(aItr->second, args); if (result == Shared::success) - logger.log(Logger::debug, "module \"" + mItr->first + "\" successfully handled message from " + sender, {"Router"}); + debug("module \"" + mItr->first + "\" successfully handled message from " + sender); } catch (...) { - logger.log(Logger::error, "module \"" + mItr->first + "\" thew an unhandled exception handling message from " + sender, {"Router"}); + error("module \"" + mItr->first + "\" thew an unhandled exception handling message from " + sender); result = Shared::error; } @@ -77,6 +77,10 @@ std::map Router::getActors() const { return result; } +std::string Router::getDefaultGroup() const { + return defaultGroup; +} + void Router::setConnection(const std::shared_ptr& cn) { connection = cn; } @@ -100,7 +104,7 @@ void Router::onMessageResult(Shared::Result result, const std::string& sender) { std::shared_ptr cn = connection.lock(); if (!cn) { - logger.log(Logger::warning, "Couldn't send a message to " + sender + ", connection is not available", {"Router"}); + warn("Couldn't send a message to " + sender + ", connection is not available"); return; } diff --git a/component/router.h b/component/router.h index 4d9caeb..bacb578 100644 --- a/component/router.h +++ b/component/router.h @@ -10,8 +10,8 @@ #include #include "shared/result.h" +#include "shared/loggable.h" #include "actor.h" -#include "logger.h" namespace Module { class Module; @@ -19,15 +19,16 @@ namespace Module { class Connection; -class Router { +class Router : private Shared::Loggable { public: - Router(const Logger& logger); + Router(const Shared::Logger& logger); void registerModule(const std::string& key, const std::shared_ptr& module); void registerActor(const std::string& key, const std::string& group); void routeMessage(const std::string& sender, const std::string& body); std::map getActors() const; + std::string getDefaultGroup() const; void setConnection(const std::shared_ptr& connection); void setResponses(Shared::Result result, const Shared::Strings& options); @@ -43,7 +44,6 @@ private: typedef std::map Responses; std::weak_ptr connection; - const Logger& logger; Modules modules; Actors actors; std::string defaultGroup; diff --git a/connection/connection.cpp b/connection/connection.cpp index ce78083..e3b2519 100644 --- a/connection/connection.cpp +++ b/connection/connection.cpp @@ -4,6 +4,7 @@ #include "connection.h" Connection::Connection(const std::shared_ptr& core): + Shared::Loggable(core->logger, {"Connection"}), state(initial), core(core), gloox() @@ -21,7 +22,7 @@ void Connection::initialize() { gloox->registerConnectionListener(this); gloox->registerMessageHandler(this); - ::gloox::LogLevel level = Logger::convert(core->config.getLogLevel()); + ::gloox::LogLevel level = Shared::Logger::convert(core->config.getLogLevel()); gloox->logInstance().registerLogHandler(level, gloox::LogAreaAll, &core->logger); gloox::Disco* disco = gloox->disco(); @@ -39,7 +40,7 @@ void Connection::deinitialize() { if (state == initial) return; - core->logger.log(Logger::debug, "deinitializing", {"Connection"}); + debug("deinitializing"); gloox->logInstance().removeLogHandler(&core->logger); gloox->removeMessageHandler(this); @@ -53,14 +54,14 @@ void Connection::connect() { if (state != disconnected) return; - core->logger.log(Logger::debug, "connecting", {"Connection"}); + debug("connecting"); state = connected; gloox->connect(true); state = disconnected; } void Connection::send(const std::string& jid, const std::string& body) { - core->logger.log(Logger::debug, "sending message \"" + body + "\" to " + jid, {"Connection"}); + debug("sending message \"" + body + "\" to " + jid); gloox->send(gloox::Message(gloox::Message::Chat, jid, body)); } @@ -73,12 +74,12 @@ void Connection::handleMessage(const gloox::Message& message, gloox::MessageSess return; std::string jid = message.from().bare(); - core->logger.log(Logger::debug, "received message \"" + body + "\" from " + jid, {"Connection"}); + debug("received message \"" + body + "\" from " + jid); core->router.routeMessage(jid, body); } void Connection::onConnect() { - core->logger.log(Logger::info, "connection established", {"Connection"}); + info("connection established"); } void Connection::onDisconnect(gloox::ConnectionError e) { std::string error; @@ -143,12 +144,12 @@ void Connection::onDisconnect(gloox::ConnectionError e) { } if (error.empty()) - core->logger.log(Logger::info, "disconnected" , {"Connection"}); + info("disconnected"); else - core->logger.log(Logger::error, "disconnected: " + error , {"Connection"}); + Loggable::error("disconnected: " + error); } bool Connection::onTLSConnect(const gloox::CertInfo&) { - core->logger.log(Logger::info, "TLS established", {"Connection"}); + info("TLS established"); return true; } diff --git a/connection/connection.h b/connection/connection.h index 910635c..c079ddb 100644 --- a/connection/connection.h +++ b/connection/connection.h @@ -11,9 +11,11 @@ #include #include +#include "shared/loggable.h" #include "component/core.h" class Connection: + private Shared::Loggable, public gloox::ConnectionListener, public gloox::MessageHandler { diff --git a/jay.cpp b/jay.cpp index ade530d..7c47a7a 100644 --- a/jay.cpp +++ b/jay.cpp @@ -51,7 +51,7 @@ void Jay::createModules() { if (!conf.enabled) continue; - core->logger.log(Logger::info, "enabling module " + pair.first, {"Jay"}); + core->logger.log(Shared::Logger::info, "enabling module " + pair.first, {"Jay"}); modules.emplace_back(pair.second(core, conf.permissions)); core->router.registerModule(pair.first, modules.back()); } diff --git a/module/actor.cpp b/module/actor.cpp index ee68076..22d3427 100644 --- a/module/actor.cpp +++ b/module/actor.cpp @@ -4,7 +4,7 @@ #include "actor.h" Module::Actor::Actor(const std::shared_ptr& core, const Shared::Permissions& permissions): - Module(core, permissions) + Module(core, permissions, "Actor") {} Module::Actor::~Actor() noexcept {} @@ -51,7 +51,7 @@ std::string Module::Actor::list() { } std::string Module::Actor::set(const std::string& jid, const std::string& group) { - core->setGroup(jid, group); + core->setGroup(lower(jid), group); return jid + " is now " + core->router.getGroup(jid); } diff --git a/module/module.cpp b/module/module.cpp index 3865188..7c4f47f 100644 --- a/module/module.cpp +++ b/module/module.cpp @@ -7,7 +7,8 @@ #include "gloox/message.h" -Module::Module::Module(const std::shared_ptr& core, const Shared::Permissions& permissions): +Module::Module::Module(const std::shared_ptr& core, const Shared::Permissions& permissions, const std::string& name): + Shared::Loggable(core->logger, {"Module", name}), core(core), permissions(permissions) {} @@ -36,3 +37,7 @@ std::vector Module::Module::split(const std::string& string, const return result; } + +std::string Module::Module::lower(const std::string& text) { + return std::ranges::to(text | std::views::transform(::tolower)); +} diff --git a/module/module.h b/module/module.h index b8f2513..2881a5e 100644 --- a/module/module.h +++ b/module/module.h @@ -6,17 +6,20 @@ #include #include #include +#include +#include #include "shared/definitions.h" #include "shared/result.h" +#include "shared/loggable.h" #include "component/core.h" #include "component/actor.h" namespace Module { -class Module { +class Module : protected Shared::Loggable { protected: - Module(const std::shared_ptr& core, const Shared::Permissions& permissions); + Module(const std::shared_ptr& core, const Shared::Permissions& permissions, const std::string& name); bool hasPermission(const std::string& permission, const std::shared_ptr<::Actor>& actor) const; @@ -24,6 +27,7 @@ public: virtual ~Module() noexcept; static Shared::Strings split(const std::string& string, const std::string& delimiter = " "); + static std::string lower(const std::string& text); virtual Shared::Result message(const std::shared_ptr<::Actor>& actor, const Shared::Strings& args) = 0; diff --git a/shared/CMakeLists.txt b/shared/CMakeLists.txt index d157eb4..d08bcb0 100644 --- a/shared/CMakeLists.txt +++ b/shared/CMakeLists.txt @@ -1,7 +1,11 @@ set(SOURCES + logger.cpp + loggable.cpp ) set(HEADERS + logger.h + loggable.h definitions.h result.h ) diff --git a/shared/loggable.cpp b/shared/loggable.cpp new file mode 100644 index 0000000..52dbcf0 --- /dev/null +++ b/shared/loggable.cpp @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2024 Yury Gubich +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "loggable.h" + +Shared::Loggable::Loggable(const Logger& logger, const std::vector& domain) : + logger(logger), + domain(domain) +{} + +void Shared::Loggable::trace(const std::string& message) const { + logger.log(Logger::trace, message, domain); +} + +void Shared::Loggable::debug(const std::string& message) const { + logger.log(Logger::debug, message, domain); +} + +void Shared::Loggable::info(const std::string& message) const { + logger.log(Logger::info, message, domain); +} + +void Shared::Loggable::warn(const std::string& message) const { + logger.log(Logger::warning, message, domain); +} + +void Shared::Loggable::error(const std::string& message) const { + logger.log(Logger::error, message, domain); +} diff --git a/shared/loggable.h b/shared/loggable.h new file mode 100644 index 0000000..48d9eb7 --- /dev/null +++ b/shared/loggable.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2024 Yury Gubich +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include + +#include "logger.h" + +namespace Shared { + +class Loggable { +public: + Loggable(const Logger& logger, const std::vector& domain = {"Unknown"}); + +private: + const Logger& logger; + std::vector domain; + +protected: + void trace(const std::string& message) const; + void debug(const std::string& message) const; + void info(const std::string& message) const; + void warn(const std::string& message) const; + void error(const std::string& message) const; +}; + +} \ No newline at end of file diff --git a/component/logger.cpp b/shared/logger.cpp similarity index 87% rename from component/logger.cpp rename to shared/logger.cpp index 0e7f10b..fb8ddab 100644 --- a/component/logger.cpp +++ b/shared/logger.cpp @@ -39,11 +39,11 @@ void writeTimestamp() { } constexpr std::string_view getLogLevel(gloox::LogLevel level) { - return (level >= 0 && level < 3) ? logLevelMap[Logger::convert(level)] : "UNKNOWN"; + return (level >= 0 && level < 3) ? logLevelMap[Shared::Logger::convert(level)] : "UNKNOWN"; } constexpr std::string_view getColor(gloox::LogLevel level) { - return (level >= 0 && level < 3) ? colorMap[Logger::convert(level)] : ""; + return (level >= 0 && level < 3) ? colorMap[Shared::Logger::convert(level)] : ""; } void writeTags(gloox::LogArea area) { @@ -84,7 +84,7 @@ void writeTags(gloox::LogArea area) { std::cout << '\t'; } -Logger::Level Logger::convert(gloox::LogLevel level) { +Shared::Logger::Level Shared::Logger::convert(gloox::LogLevel level) { switch (level) { case gloox::LogLevelDebug: return trace; @@ -97,7 +97,7 @@ Logger::Level Logger::convert(gloox::LogLevel level) { return warning; } -gloox::LogLevel Logger::convert(Level level) { +gloox::LogLevel Shared::Logger::convert(Level level) { switch (level) { case trace: return gloox::LogLevelDebug; @@ -116,20 +116,20 @@ gloox::LogLevel Logger::convert(Level level) { return gloox::LogLevelWarning; } -Logger::Logger(Level level): +Shared::Logger::Logger(Level level): level(level) {} -Logger::~Logger() {} +Shared::Logger::~Logger() {} -void Logger::handleLog(gloox::LogLevel level, gloox::LogArea area, const std::string& message) { +void Shared::Logger::handleLog(gloox::LogLevel level, gloox::LogArea area, const std::string& message) { writeTimestamp(); std::cout << getColor(level) << bold << '[' << getLogLevel(level) << ']' << clear << bold; writeTags(area); std::cout << clear << '\t' << message << clear << std::endl; } -void Logger::log(Level lvl, const std::string& message, const std::vector& domain) const { +void Shared::Logger::log(Level lvl, const std::string& message, const std::vector& domain) const { if (lvl < level) return; diff --git a/component/logger.h b/shared/logger.h similarity index 97% rename from component/logger.h rename to shared/logger.h index 6059745..f1f08e5 100644 --- a/component/logger.h +++ b/shared/logger.h @@ -8,6 +8,8 @@ #include #include +namespace Shared { + class Logger: public gloox::LogHandler { public: enum Level { @@ -33,3 +35,5 @@ public: private: Level level; }; + +} \ No newline at end of file