mountcontrol/cxx/mcc_spdlog.h
Timur A. Fatkhullin 8b1873b40b ...
2025-08-26 02:28:08 +03:00

186 lines
5.2 KiB
C++

#pragma once
#include <spdlog/logger.h>
#include <list>
#include "mcc_traits.h"
namespace mcc::utils
{
using namespace std::literals;
/* SPDLOG-library based advanced single/multithreaded logger */
class MccSpdlogLogger
{
public:
// [year-month-day time.millisecs][log-level]: log-message
constexpr static std::array LOGGER_DEFAULT_FORMAT = {"[%Y-%m-%d %T.%e]"sv, "[%l]"sv, ": "sv, "%v"sv};
typedef spdlog::level::level_enum loglevel_t;
template <traits::mcc_range_of_input_char_range R = decltype(LOGGER_DEFAULT_FORMAT)>
MccSpdlogLogger(std::shared_ptr<spdlog::logger> logger, const R& pattern_range = LOGGER_DEFAULT_FORMAT)
: _currentLogPatternRange(), _currentLogPattern(), _loggerSPtr(logger)
{
if (std::distance(pattern_range.begin(), pattern_range.end())) {
std::ranges::copy(
pattern_range | std::views::transform([](const auto& el) { return std::string(el.begin(), el.end()); }),
std::back_inserter(_currentLogPatternRange));
} else {
std::ranges::copy(LOGGER_DEFAULT_FORMAT | std::views::transform([](const auto& el) {
return std::string(el.begin(), el.end());
}),
std::back_inserter(_currentLogPatternRange));
}
std::ranges::copy(std::views::join(_currentLogPatternRange), std::back_inserter(_currentLogPattern));
_loggerSPtr->set_pattern(_currentLogPattern);
}
virtual ~MccSpdlogLogger() = default;
void setLogLevel(loglevel_t log_level)
{
_loggerSPtr->set_level(log_level);
}
loglevel_t getLogLevel() const
{
return _loggerSPtr->level();
}
void logMessage(loglevel_t level, const std::string& msg)
{
_loggerSPtr->log(level, msg);
}
// specialized for given level methods
void logCritical(const std::string& msg)
{
logMessage(spdlog::level::critical, msg);
}
void logError(const std::string& msg)
{
logMessage(spdlog::level::err, msg);
}
void logWarn(const std::string& msg)
{
logMessage(spdlog::level::warn, msg);
}
void logInfo(const std::string& msg)
{
logMessage(spdlog::level::info, msg);
}
void logDebug(const std::string& msg)
{
logMessage(spdlog::level::debug, msg);
}
void logTrace(const std::string& msg)
{
logMessage(spdlog::level::trace, msg);
}
template <traits::mcc_formattable... ArgTs>
void logMessage(spdlog::level::level_enum level, spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
{
_loggerSPtr->log(level, fmt, std::forward<ArgTs>(args)...);
}
template <traits::mcc_formattable... ArgTs>
void logCritical(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
{
_loggerSPtr->log(spdlog::level::critical, fmt, std::forward<ArgTs>(args)...);
}
template <typename... ArgTs>
void logError(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
{
_loggerSPtr->log(spdlog::level::err, fmt, std::forward<ArgTs>(args)...);
}
template <traits::mcc_formattable... ArgTs>
void logWarn(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
{
_loggerSPtr->log(spdlog::level::warn, fmt, std::forward<ArgTs>(args)...);
}
template <traits::mcc_formattable... ArgTs>
void logInfo(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
{
_loggerSPtr->log(spdlog::level::info, fmt, std::forward<ArgTs>(args)...);
}
template <traits::mcc_formattable... ArgTs>
void logDebug(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
{
_loggerSPtr->log(spdlog::level::debug, fmt, std::forward<ArgTs>(args)...);
}
template <traits::mcc_formattable... ArgTs>
void logTrace(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
{
_loggerSPtr->log(spdlog::level::trace, fmt, std::forward<ArgTs>(args)...);
}
protected:
std::list<std::string> _currentLogPatternRange;
std::string _currentLogPattern;
std::shared_ptr<spdlog::logger> _loggerSPtr;
// helper methods
auto getThreadId() const
{
std::ostringstream st;
st << std::this_thread::get_id();
return st.str();
}
// 'after_idx' is 0-based index!
void addMarkToPatternIdx(const traits::mcc_input_char_range auto& mark, size_t after_idx = 1)
requires(!std::is_pointer_v<std::decay_t<decltype(mark)>>)
{
if (!std::distance(mark.begin(), mark.end())) {
return;
}
auto it = _currentLogPatternRange.begin();
size_t idx = 0;
while (it != _currentLogPatternRange.end()) {
++it;
if (idx == after_idx)
break;
++idx;
}
_currentLogPatternRange.emplace(it, mark.begin(), mark.end());
_currentLogPattern.clear();
std::ranges::copy(std::views::join(_currentLogPatternRange), std::back_inserter(_currentLogPattern));
_loggerSPtr->set_pattern(_currentLogPattern);
}
void addMarkToPatternIdx(const char* mark, size_t after_idx = 1)
{
addMarkToPatternIdx(std::string_view{mark}, after_idx);
}
};
} // namespace mcc::utils