diff --git a/common/adc_spdlog.h b/common/adc_spdlog.h index a817849..e76ce9f 100644 --- a/common/adc_spdlog.h +++ b/common/adc_spdlog.h @@ -20,28 +20,103 @@ protected: std::shared_ptr _logger; void* _thisAddress; + std::string _currentPattern; public: - constexpr static char loggerDefaultFormat[] = "[%Y-%m-%d %T.%e] [%l]: [%v]"; + constexpr static std::string_view LOGGER_DEFAULT_FORMAT = "[%Y-%m-%d %T.%e] [%l]: [%v]"; - template - AdcSpdlogGenericDecorator(std::shared_ptr logger, BaseCtorArgTs&&... ctor_args) - : BaseT(std::forward(ctor_args)...), _logger(logger), _thisAddress((void*)std::addressof(*this)) + template + AdcSpdlogGenericDecorator(const R& pattern, std::shared_ptr logger, BaseCtorArgTs&&... ctor_args) + : BaseT(std::forward(ctor_args)...), + _logger(logger), + _thisAddress((void*)std::addressof(*this)), + _currentPattern(pattern.begin(), pattern.end()) { - _logger->set_pattern(loggerDefaultFormat); + _logger->set_pattern(_currentPattern); - logMethodCalling("AdcSpdlogGenericDecorator"); // in debug - logMethodCalling(); // in trace + if (_logger->level() == spdlog::level::trace) { + logMethodCalling(__PRETTY_FUNCTION__); // in trace + } else { + logMethodCalling("AdcSpdlogGenericDecorator", __FUNCTION__); // in debug + } _logger->debug("set logger with {}", loggerInfo()); } - virtual ~AdcSpdlogGenericDecorator() + + template + AdcSpdlogGenericDecorator(std::shared_ptr logger, BaseCtorArgTs&&... ctor_args) + : AdcSpdlogGenericDecorator(LOGGER_DEFAULT_FORMAT, logger, std::forward(ctor_args)...) { - // - logMethodCalling("AdcSpdlogGenericDecorator"); // in debug } + virtual ~AdcSpdlogGenericDecorator() + { + logMethodCalling("AdcSpdlogGenericDecorator", __FUNCTION__); // in debug + + _logger->flush(); + } + + + template + void setPattern(const R& pattern) + { + logMethodCalling("AdcSpdlogGenericDecorator", __FUNCTION__); // in debug + + _currentPattern = {pattern.begin(), pattern.end()}; + + _logger->debug("set current logging pattern to: {}", _currentPattern); + } + + + std::string pattern() const + { + logMethodCalling(); + + return _currentPattern; + } + + template + void logMsg(spdlog::level::level_enum level, std::string_view fmt, ArgTs&&... args) + { + _logger->log(level, fmt, std::forward(args)...); + } + + template + void logCritical(std::string_view fmt, ArgTs&&... args) + { + _logger->log(spdlog::level::critical, fmt, std::forward(args)...); + } + + template + void logError(std::string_view fmt, ArgTs&&... args) + { + _logger->log(spdlog::level::err, fmt, std::forward(args)...); + } + + template + void logWarn(std::string_view fmt, ArgTs&&... args) + { + _logger->log(spdlog::level::warn, fmt, std::forward(args)...); + } + + template + void logInfo(std::string_view fmt, ArgTs&&... args) + { + _logger->log(spdlog::level::info, fmt, std::forward(args)...); + } + + template + void logDebug(std::string_view fmt, ArgTs&&... args) + { + _logger->log(spdlog::level::debug, fmt, std::forward(args)...); + } + + template + void logTrace(std::string_view fmt, ArgTs&&... args) + { + _logger->log(spdlog::level::trace, fmt, std::forward(args)...); + } protected: // format string must contain two formating specifications: @@ -63,22 +138,48 @@ protected: return loggerInfo("name [{}] and log-level [{}]"); } - void logMethodCalling(spdlog::level::level_enum level = spdlog::level::trace) const + void logMethodCalling(std::string_view class_name, + std::string_view method_name, + spdlog::level::level_enum level = spdlog::level::debug) const { - _logger->log(level, "call {} (this: {}, thread ID: {})", __PRETTY_FUNCTION__, _thisAddress, + _logger->log(level, "call {}::{} (this: {}, thread ID: {})", class_name, method_name, _thisAddress, std::this_thread::get_id()); } - void logMethodCalling(std::string_view class_name, - spdlog::level::level_enum level = spdlog::level::debug, - std::string_view method_name = "") const - { - if (method_name.empty()) { - method_name = __FUNCTION__; - } - _logger->log(level, "call {}::{} (this: {}, thread ID: {})", class_name, method_name, _thisAddress, - std::this_thread::get_id()); + void logMethodCalling(std::string_view log_msg, spdlog::level::level_enum level = spdlog::level::debug) const + { + _logger->log(level, "call {} (this: {}, thread ID: {})", log_msg, _thisAddress, std::this_thread::get_id()); + } +}; + + +template +class AdcSpdlogGenericMarkDecorator : public AdcSpdlogGenericDecorator +{ +protected: + using base_t = AdcSpdlogGenericDecorator; + +public: + constexpr static std::array LOGGER_DEFAULT_FORMAT{"[%Y-%m-%d %T.%e] [%l]: ", "[%v]"}; + + template + static std::string constructPattern(const R& mark, size_t after_idx = 0, const IR& format = LOGGER_DEFAULT_FORMAT) + { + std::string pattern; + + std::ranges::copy(format | std::views::take(after_idx + 1) | std::views::join, std::back_inserter(pattern)); + std::ranges::copy(mark, std::back_inserter(pattern)); + std::ranges::copy(format | std::views::drop(after_idx + 1) | std::views::join, std::back_inserter(pattern)); + + return pattern; + } + + + template + AdcSpdlogGenericMarkDecorator(const R& mark, std::shared_ptr logger, BaseCtorArgTs&&... ctor_args) + : base_t(constructPattern(mark), logger, std::forward(ctor_args)...) + { } }; diff --git a/common/adc_traits.h b/common/adc_traits.h index 57ec882..d031eef 100644 --- a/common/adc_traits.h +++ b/common/adc_traits.h @@ -50,6 +50,10 @@ template concept adc_range_of_view_char_range = std::ranges::range && std::ranges::view> && std::same_as>, char>; +template +concept adc_range_of_input_char_range = + std::ranges::range && traits::adc_input_char_range>; + // deduce returned type of callable // template // using adc_retval_t = std::invoke_result_t>; diff --git a/net/adc_netserver_spdlog.h b/net/adc_netserver_spdlog.h index 9e5c6cb..941c9bc 100644 --- a/net/adc_netserver_spdlog.h +++ b/net/adc_netserver_spdlog.h @@ -11,9 +11,9 @@ ABSTRACT DEVICE COMPONENTS LIBRARY #ifdef USE_SPDLOG_LIBRARY -#include - +#include "../common/adc_spdlog.h" #include "../common/adc_traits.h" + #include "adc_netserver.h" namespace adc @@ -89,38 +89,38 @@ public: template -class AdcNetServerSpdlogDecorator : public ServerT +class AdcNetServerSpdlogDecorator : public AdcSpdlogGenericDecorator { protected: - std::shared_ptr _logger; + using base_t = AdcSpdlogGenericDecorator; - void* _thisAddress; std::string _serverID; public: + using base_t::logCritical; + using base_t::logDebug; + using base_t::logError; + using base_t::logInfo; + using base_t::logMsg; + using base_t::logWarn; + using typename ServerT::server_ident_t; template AdcNetServerSpdlogDecorator(std::shared_ptr logger, ImplCtorArgTs&&... ctor_args) - : ServerT(std::forward(ctor_args)...), _logger(logger), _thisAddress((void*)std::addressof(this)) + : base_t(logger, std::forward(ctor_args)...) { fmt::format_to(std::back_inserter(_serverID), "{}", ServerT::serverIdent()); - _logger->trace("Call AdcNetServerSpdlogDecorator::AdcNetServerSpdlogDecorator (this: {})", _thisAddress); - - _logger->debug("Creating network server session with ID = [{}] (ADDR = {})", _serverID, _thisAddress); - _logger->debug("use logger with name [{}] and level [{}]", _logger->name(), - spdlog::level::to_string_view(_logger->level())); + logDebug("Creating network server with ID = [{}] (ADDR = {})", _serverID, this->_thisAddress); } virtual ~AdcNetServerSpdlogDecorator() { - _logger->trace("Call AdcNetServerSpdlogDecorator::~AdcNetServerSpdlogDecorator (this: {})", _thisAddress); + this->logMethodCalling(); - _logger->debug("Deleting network server with ID = [{}] (ADDR = {})", _serverID, _thisAddress); - - _logger->flush(); + logDebug("Deleting network server with ID = [{}] (ADDR = {})", _serverID, this->_thisAddress); } @@ -132,16 +132,19 @@ public: virtual void start() { - _logger->trace("Call AdcNetServerSpdlogDecorator::start (this: {})", _thisAddress); + this->logMethodCalling(); - _logger->info("Starting network server with ID = [{}] (ADDR = {})", _serverID, _thisAddress); + logInfo("Starting network server"); ServerT::start(); }; virtual void stop() { - // + this->logMethodCalling(); + + logInfo("Stopping network server"); + ServerT::stop(); }; };