From 1313cab93e2f45d919674b788ca0742022a1bfaec0be43af84b5b506762d7662 Mon Sep 17 00:00:00 2001 From: CupWater Date: Mon, 17 Aug 2026 18:27:39 +0800 Subject: [PATCH] finish log_manager.cpp --- include/featherlog/log_manager.hpp | 8 ++++-- include/featherlog/log_outputter.hpp | 6 ++++ include/featherlog/push_result.hpp | 31 +++++++++++++++----- src/log_manager.cpp | 42 ++++++++++++++++++++++++---- 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/include/featherlog/log_manager.hpp b/include/featherlog/log_manager.hpp index 7014c1c..b4d6c74 100644 --- a/include/featherlog/log_manager.hpp +++ b/include/featherlog/log_manager.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace flog { class FLOG_API LogManager : public std::enable_shared_from_this { @@ -25,13 +26,14 @@ namespace flog { _NODISCARD static std::shared_ptr FLOG_CALL create(); - ~LogManager() = default; + ~LogManager(); LogLevel FLOG_CALL get_min_log_level() const noexcept; void FLOG_CALL set_min_log_level(LogLevel level) noexcept; - PushResult FLOG_CALL add_outputter(const std::string& name, std::unique_ptr outputter); - std::optional FLOG_CALL get_outputter() noexcept; + PushResult> FLOG_CALL add_outputter(std::unique_ptr outputter); + bool FLOG_CALL contains_outputter(std::string_view name) const noexcept; + std::optional> try_delete_outputter(std::string_view name) noexcept; std::shared_ptr FLOG_CALL get_logger(const std::string &name); diff --git a/include/featherlog/log_outputter.hpp b/include/featherlog/log_outputter.hpp index 4fc27ad..b7e93a1 100644 --- a/include/featherlog/log_outputter.hpp +++ b/include/featherlog/log_outputter.hpp @@ -10,14 +10,20 @@ namespace flog { class FLOG_API LogOutputter { public: + explicit LogOutputter(std::string name) noexcept : name(std::move(name)) {} + virtual ~LogOutputter() = default; + std::string& getName() const noexcept; + std::unique_ptr FLOG_CALL set_formatter(const std::unique_ptr &formatter); [[nodiscard]] const std::unique_ptr & FLOG_CALL get_formatter() const; virtual void FLOG_CALL write(const LogMessage &message) = 0; protected: + std::string name; + std::unique_ptr m_logFormatter; }; } diff --git a/include/featherlog/push_result.hpp b/include/featherlog/push_result.hpp index e65971e..7ee4394 100644 --- a/include/featherlog/push_result.hpp +++ b/include/featherlog/push_result.hpp @@ -2,22 +2,39 @@ #define FEATHERLOG_PUSH_RESULT_HPP #include +#include namespace flog { template class PushResult { public: - static PushResult getVoid() { - return PushResult(3); + _NODISCARD static PushResult success() noexcept { return PushResult(); } + _NODISCARD static PushResult failWithValue(T value) noexcept { + return PushResult(std::move(std::optional(std::move(value)))); + } + + _NODISCARD bool isSuccessful() const noexcept { return !m_value.has_value(); } + _NODISCARD bool isFail() const noexcept { return m_value.has_value(); } + + void getValueIfFail(const std::function func) const { + if (isFail()) { + func(m_value.value()); + } + } + + _NODISCARD T getValue() const { + return m_value.value(); + } + + PushResult(const PushResult &other) noexcept { + m_value = other.m_value; } private: - explicit PushResult(std::optional value) : m_value(value) { - std::optional bad; - std::map> mp; - } + PushResult() noexcept = default; + explicit PushResult(std::optional value) noexcept : m_value(std::move(value)) {} - std::optional m_value; + std::optional m_value = std::nullopt; }; } diff --git a/src/log_manager.cpp b/src/log_manager.cpp index bfe252b..1722259 100644 --- a/src/log_manager.cpp +++ b/src/log_manager.cpp @@ -1,4 +1,6 @@ +#include #include +#include namespace flog { std::shared_ptr LogManager::create() { @@ -6,6 +8,17 @@ namespace flog { return std::shared_ptr(new LogManager()); } + LogManager::~LogManager() { + { + std::lock_guard lock(m_loggersMutex); + m_loggers.clear(); + } + { + std::lock_guard lock(m_logOutputtersMutex); + m_logOutputters.clear(); + } + } + LogLevel LogManager::get_min_log_level() const noexcept { return m_minLogLevel.load(std::memory_order_relaxed); } @@ -14,13 +27,30 @@ namespace flog { m_minLogLevel.store(level, std::memory_order_relaxed); } - bool LogManager::add_outputter(const std::string& name, std::unique_ptr outputter) { + PushResult> LogManager::add_outputter(std::unique_ptr outputter) + { std::lock_guard lock(m_logOutputtersMutex); - if (m_logOutputters.contains(name)) { - return false; + if (m_logOutputters.contains(outputter->getName())) { + return PushResult>::failWithValue(std::move(outputter)); } - m_logOutputters[name] = std::move(outputter); - return true; + m_logOutputters.emplace(outputter->getName(), std::move(outputter)); + return PushResult>::success(); + } + + bool LogManager::contains_outputter(const std::string_view name) const noexcept { + std::shared_lock lock(m_logOutputtersMutex); + return m_logOutputters.contains(name.data()); + } + + std::optional> LogManager::try_delete_outputter(const std::string_view name) noexcept { + if (contains_outputter(name)) { + std::lock_guard lock(m_logOutputtersMutex); + const auto it = m_logOutputters.find(name.data()); + std::optional outputter = std::move(it->second); + m_logOutputters.erase(it); + return std::move(outputter); + } + return std::nullopt; } std::shared_ptr LogManager::get_logger(const std::string &name) { @@ -50,7 +80,7 @@ namespace flog { void LogManager::print_log(const LogMessage &message) const { std::shared_lock lock(m_logOutputtersMutex); - for (auto &outputter: m_logOutputters) { + for (const std::unique_ptr &outputter: m_logOutputters | std::views::values) { outputter->write(message); } }