#pragma once #ifdef USE_SPDLOG_LIBRARY #include #include #include "adc_traits.h" namespace adc { template class AdcSpdlogGenericDecorator : public BaseT { protected: std::shared_ptr _logger; void* _thisAddress; public: constexpr static char loggerDefaultFormat[] = "[%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)) { _logger->set_pattern(loggerDefaultFormat); logMethodCalling("AdcSpdlogGenericDecorator"); // in debug logMethodCalling(); // in trace _logger->debug("set logger with {}", loggerInfo()); } virtual ~AdcSpdlogGenericDecorator() { // logMethodCalling("AdcSpdlogGenericDecorator"); // in debug } protected: // format string must contain two formating specifications: // 1 - logger name (string) // 2 - logging level (string) template R loggerInfo(std::string_view fmt) const { R info; std::format_to(std::back_inserter(info), fmt, _logger->name(), spdlog::level::to_string_view(_logger->level())); return info; } std::string loggerInfo() const { // return loggerInfo("name [{}] and log-level [{}]"); } void logMethodCalling(spdlog::level::level_enum level = spdlog::level::trace) const { _logger->log(level, "call {} (this: {}, thread ID: {})", __PRETTY_FUNCTION__, _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()); } }; } // namespace adc #endif