124 lines
2.8 KiB
C++
124 lines
2.8 KiB
C++
#include "matador/logger/log_domain.hpp"
|
|
|
|
#include <chrono>
|
|
#include <thread>
|
|
|
|
namespace matador::logger {
|
|
|
|
namespace details {
|
|
|
|
std::size_t acquire_thread_index(const std::thread::id id) {
|
|
static std::size_t next_index = 0;
|
|
static std::mutex thread_mutex;
|
|
static std::map<std::thread::id, std::size_t> ids;
|
|
std::lock_guard lock(thread_mutex);
|
|
if(ids.find(id) == ids.end()) {
|
|
ids[id] = next_index++;
|
|
}
|
|
return ids[id];
|
|
}
|
|
|
|
char* gettimestamp(char* const buffer, const size_t size) {
|
|
using namespace std::chrono;
|
|
|
|
const auto now = system_clock::now();
|
|
const auto now_ms = time_point_cast<milliseconds>(now);
|
|
|
|
std::time_t t = system_clock::to_time_t(now);
|
|
const auto ms = duration_cast<milliseconds>(now_ms.time_since_epoch()) % 1000;
|
|
|
|
std::tm tm{};
|
|
#ifdef _WIN32
|
|
localtime_s(&tm, &t);
|
|
#else
|
|
localtime_r(&t, &tm);
|
|
#endif
|
|
char buf[32];
|
|
std::strftime(buf, 32, "%Y-%m-%d %H:%M:%S", &tm);
|
|
|
|
std::snprintf(buffer, size, "%s.%03ld", buf, static_cast<long>(ms.count()));
|
|
|
|
return buffer;
|
|
}
|
|
|
|
}
|
|
|
|
std::map<log_level, std::string> log_domain::level_strings = { /* NOLINT */
|
|
{ log_level::LVL_DEBUG, "DEBUG" },
|
|
{ log_level::LVL_INFO, "INFO" },
|
|
{ log_level::LVL_WARN, "WARN" },
|
|
{ log_level::LVL_ERROR, "ERROR" },
|
|
{ log_level::LVL_TRACE, "TRACE" }
|
|
};
|
|
|
|
log_domain::log_domain(std::string name, const log_level_range log_range)
|
|
: name_(std::move(name))
|
|
, log_level_range_(log_range)
|
|
{}
|
|
|
|
std::string log_domain::name() const
|
|
{
|
|
return name_;
|
|
}
|
|
|
|
void log_domain::max_log_level(log_level max_level)
|
|
{
|
|
log_level_range_.max_level = max_level;
|
|
}
|
|
|
|
log_level log_domain::max_log_level() const
|
|
{
|
|
return log_level_range_.max_level;
|
|
}
|
|
|
|
void log_domain::min_log_level(log_level min_level)
|
|
{
|
|
log_level_range_.min_level = min_level;
|
|
}
|
|
|
|
log_level log_domain::min_log_level() const
|
|
{
|
|
return log_level_range_.min_level;
|
|
}
|
|
|
|
void log_domain::add_sink(sink_ptr sink)
|
|
{
|
|
sinks.push_back(std::move(sink));
|
|
}
|
|
|
|
void log_domain::log(log_level lvl, const std::string &source, const char *message)
|
|
{
|
|
if (lvl < log_level_range_.max_level || lvl > log_level_range_.min_level) {
|
|
return;
|
|
}
|
|
|
|
char timestamp[80];
|
|
get_time_stamp(timestamp);
|
|
|
|
char buffer[1024];
|
|
|
|
#ifdef _MSC_VER
|
|
int ret = sprintf_s(buffer, 1024, "%s [Thread %zu] [%-7s] [%s]: %s\n", timestamp, details::acquire_thread_index(std::this_thread::get_id()), level_strings[lvl].c_str(), source.c_str(), message);
|
|
#else
|
|
int ret = sprintf(buffer, "%s [Thread %lu] [%-7s] [%s]: %s\n", timestamp, details::acquire_thread_index(std::this_thread::get_id()), level_strings[lvl].c_str(), source.c_str(), message);
|
|
#endif
|
|
|
|
std::lock_guard<std::mutex> l(mutex_);
|
|
for (auto &sink : sinks) {
|
|
sink->write(buffer, ret);
|
|
}
|
|
}
|
|
|
|
void log_domain::clear()
|
|
{
|
|
sinks.clear();
|
|
}
|
|
|
|
void log_domain::get_time_stamp(char* const timestamp_buffer)
|
|
{
|
|
std::lock_guard l(mutex_);
|
|
details::gettimestamp(timestamp_buffer, 80);
|
|
}
|
|
|
|
}
|