add AdcOstreamLogger class (std::basic_stream based multithread-safe
simple logger)
This commit is contained in:
parent
9769c24005
commit
7251f95459
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <mutex>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -674,5 +676,85 @@ static constexpr size_t AdcFNV1aHash(const R& r)
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* std::basic_ostream based multithread-safe simple logger */
|
||||||
|
|
||||||
|
template <typename CharT = char, typename CharTraitsT = std::char_traits<CharT>>
|
||||||
|
class AdcOstreamLogger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef CharT char_t;
|
||||||
|
typedef CharTraitsT char_traits_t;
|
||||||
|
|
||||||
|
enum loglevel_t { NULL_LEVEL, ERROR_LEVEL, INFO_LEVEL, DEBUG_LEVEL };
|
||||||
|
static constexpr std::array logLevelMark{"null", "error", "info", "debug"};
|
||||||
|
|
||||||
|
AdcOstreamLogger(std::basic_ostream<CharT, CharTraitsT>& stream = std::cout, loglevel_t log_level = INFO_LEVEL)
|
||||||
|
: _logStream(stream), _currentLogLevel(log_level)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AdcOstreamLogger(loglevel_t log_level) : _logStream(std::cout), _currentLogLevel(log_level) {}
|
||||||
|
|
||||||
|
virtual ~AdcOstreamLogger() = default;
|
||||||
|
|
||||||
|
void setLogLevel(loglevel_t log_level)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_logMutex);
|
||||||
|
|
||||||
|
_currentLogLevel = log_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
loglevel_t getLogLevel() const
|
||||||
|
{
|
||||||
|
return _currentLogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::formattable... Ts>
|
||||||
|
void logMessage(loglevel_t level, std::string_view fmt, Ts&&... args)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_logMutex);
|
||||||
|
|
||||||
|
if (_currentLogLevel < level)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string s;
|
||||||
|
std::format_to(std::back_inserter(s), fmt, std::forward<Ts>(args)...);
|
||||||
|
|
||||||
|
const std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||||
|
|
||||||
|
// format log-message in form:
|
||||||
|
// [YYYY-MM-DD HH:MM:SS][level] log-message
|
||||||
|
//
|
||||||
|
_logStream << std::put_time(std::localtime(&now), "[%F %T]") << "[" << logLevelMark[_currentLogLevel] << "] "
|
||||||
|
<< s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <traits::formattable... Ts>
|
||||||
|
void logError(std::string_view fmt, Ts&&... args)
|
||||||
|
{
|
||||||
|
logMessage(ERROR_LEVEL, fmt, std::forward<Ts>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::formattable... Ts>
|
||||||
|
void logInfo(std::string_view fmt, Ts&&... args)
|
||||||
|
{
|
||||||
|
logMessage(INFO_LEVEL, fmt, std::forward<Ts>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::formattable... Ts>
|
||||||
|
void logDebug(std::string_view fmt, Ts&&... args)
|
||||||
|
{
|
||||||
|
logMessage(DEBUG_LEVEL, fmt, std::forward<Ts>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::basic_ostream<CharT, CharTraitsT>& _logStream;
|
||||||
|
loglevel_t _currentLogLevel;
|
||||||
|
|
||||||
|
std::mutex _logMutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace adc::utils
|
} // namespace adc::utils
|
||||||
|
|||||||
@ -227,12 +227,25 @@ concept adc_netsession_proto_c =
|
|||||||
/* LOGGER */
|
/* LOGGER */
|
||||||
|
|
||||||
template <typename LOGGERT>
|
template <typename LOGGERT>
|
||||||
concept adc_logger_c = requires(LOGGERT log) {
|
concept adc_logger_c = requires(LOGGERT log, const LOGGERT log_const) {
|
||||||
// logging method must accept at least the single argument - formating string
|
typename LOGGERT::loglevel_t;
|
||||||
|
|
||||||
|
log.setLogLevel(std::declval<typename LOGGERT::loglevel_t>());
|
||||||
|
{ log_const.getLogLevel() } -> std::same_as<typename LOGGERT::loglevel_t>;
|
||||||
|
|
||||||
|
// logging method signature:
|
||||||
|
// void method(std::string_view fmt, traits::formattable auto&& args...)
|
||||||
|
|
||||||
|
|
||||||
|
// logging method must accept at least the single argument - formatting string
|
||||||
log.logInfo(std::declval<std::string_view>());
|
log.logInfo(std::declval<std::string_view>());
|
||||||
|
// method must be defined at least for std::string as its argument
|
||||||
log.logInfo(std::declval<std::string_view>(), std::declval<std::string>());
|
log.logInfo(std::declval<std::string_view>(), std::declval<std::string>());
|
||||||
|
|
||||||
|
log.logWarn(std::declval<std::string_view>());
|
||||||
log.logWarn(std::declval<std::string_view>(), std::declval<std::string>());
|
log.logWarn(std::declval<std::string_view>(), std::declval<std::string>());
|
||||||
|
|
||||||
|
log.logError(std::declval<std::string_view>());
|
||||||
log.logError(std::declval<std::string_view>(), std::declval<std::string>());
|
log.logError(std::declval<std::string_view>(), std::declval<std::string>());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user