added logging module and a sandbox project
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
#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, 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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user