Added MDC logging feature, working only for synchronous loggers

pull/534/head
Michał Mąka 8 years ago
parent 9688689938
commit 75cfffc234

@ -19,6 +19,8 @@
#include <utility>
#include <vector>
#include <array>
#include <regex>
#include <map>
namespace spdlog
{
@ -425,6 +427,36 @@ private:
std::string _str;
};
#define ENABLE_MDC_FORMATTER 1
// Disabling this feature for MinGW
// See https://github.com/Alexpux/MINGW-packages/issues/2519
#ifdef __MINGW32__
#undef ENABLE_MDC_FORMATTER
#define ENABLE_MDC_FORMATTER 0
#endif
// Enabled formatting pattern %X{key} to be mapped to appropiate value
class MDC_formatter SPDLOG_FINAL :public flag_formatter
{
public:
#if ENABLE_MDC_FORMATTER
thread_local static std::map<std::string, std::string> mdc_map;
#endif
MDC_formatter(std::string key): _key(std::move(key))
{}
void format(details::log_msg& msg, const std::tm&) override
{
#if ENABLE_MDC_FORMATTER
msg.formatted << mdc_map[_key];
#else
msg.formatted << "%X{" << _key << "}";
#endif
}
private:
std::string _key;
};
// Full info formatter
// pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v
class full_formatter SPDLOG_FINAL:public flag_formatter
@ -496,8 +528,11 @@ inline void spdlog::pattern_formatter::compile_pattern(const std::string& patter
if (user_chars) //append user chars found so far
_formatters.push_back(std::move(user_chars));
if (++it != end)
handle_flag(*it);
if (++it != end) {
auto flag = *it;
if (flag != 'X' || !try_handle_mdc_flag(flag, it, end))
handle_flag(flag);
}
else
break;
}
@ -654,6 +689,22 @@ inline void spdlog::pattern_formatter::handle_flag(char flag)
}
}
inline bool spdlog::pattern_formatter::try_handle_mdc_flag(char flag, std::string::const_iterator& it, const std::string::const_iterator& end)
{
if (++it != end) {
if (*it != '{')
return false;
std::smatch mdc_key_match;
auto brace_end = std::find(it, end, '}');
if (brace_end != end && std::regex_match(it, brace_end + 1, mdc_key_match, std::regex("[{]([\\w]+)[}]"))) {
_formatters.push_back(std::unique_ptr<details::MDC_formatter>(new details::MDC_formatter(mdc_key_match[1])));
it += std::distance(mdc_key_match[0].first, mdc_key_match[0].second) - 1;
return true;
}
}
return false;
}
inline std::tm spdlog::pattern_formatter::get_time(details::log_msg& msg)
{
if (_pattern_time == pattern_time_type::local)

@ -39,6 +39,7 @@ private:
std::vector<std::unique_ptr<details::flag_formatter>> _formatters;
std::tm get_time(details::log_msg& msg);
void handle_flag(char flag);
bool try_handle_mdc_flag(char flag, std::string::const_iterator& it, const std::string::const_iterator& end);
void compile_pattern(const std::string& pattern);
};
}

@ -0,0 +1,34 @@
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include "spdlog/details/pattern_formatter_impl.h"
#include <string>
namespace spdlog
{
namespace mdc
{
inline void set_context(std::string key, std::string value)
{
#if ENABLE_MDC_FORMATTER
spdlog::details::MDC_formatter::mdc_map[std::move(key)] = std::move(value);
#endif
}
inline void remove_context(const std::string& key)
{
#if ENABLE_MDC_FORMATTER
auto &mdc_map = spdlog::details::MDC_formatter::mdc_map;
auto value_it = mdc_map.find(key);
if (value_it != mdc_map.end())
mdc_map.erase(value_it);
#endif
}
}
}
Loading…
Cancel
Save