mirror of
https://github.com/gabime/spdlog.git
synced 2025-09-28 17:19:34 +08:00
Added Mapped Diagnostic Context (MDC) support (#2907)
* Added Mapped Diagnostic Context (MDC) support * Update include statement * Optimize string creation * Fix includes * Fix padding rules in mdc empty case * Add comment to describe the use of mdc formatter
This commit is contained in:

committed by
GitHub

parent
23587b0d9a
commit
d03eb40c17
31
include/spdlog/mdc.h
Normal file
31
include/spdlog/mdc.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#include <spdlog/common.h>
|
||||
#include <map>
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
class SPDLOG_API mdc {
|
||||
public:
|
||||
static void put(const std::string &key, const std::string &value) {
|
||||
get_context()[key] = value;
|
||||
}
|
||||
|
||||
static std::string get(const std::string &key) {
|
||||
auto &context = get_context();
|
||||
auto it = context.find(key);
|
||||
if (it != context.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static void remove(const std::string &key) { get_context().erase(key); }
|
||||
|
||||
static void clear() { get_context().clear(); }
|
||||
|
||||
static std::map<std::string, std::string> &get_context() {
|
||||
static thread_local std::map<std::string, std::string> context;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace spdlog
|
@@ -10,6 +10,7 @@
|
||||
#include <spdlog/details/fmt_helper.h>
|
||||
#include <spdlog/details/log_msg.h>
|
||||
#include <spdlog/details/os.h>
|
||||
#include <spdlog/mdc.h>
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
#include <spdlog/formatter.h>
|
||||
|
||||
@@ -867,6 +868,43 @@ private:
|
||||
memory_buf_t cached_datetime_;
|
||||
};
|
||||
|
||||
// Class for formatting Mapped Diagnostic Context (MDC) in log messages.
|
||||
// Example: [logger-name] [info] [mdc_key_1:mdc_value_1 mdc_key_2:mdc_value_2] some message
|
||||
template <typename ScopedPadder>
|
||||
class mdc_formatter : public flag_formatter {
|
||||
public:
|
||||
explicit mdc_formatter(padding_info padinfo)
|
||||
: flag_formatter(padinfo) {}
|
||||
|
||||
void format(const details::log_msg &, const std::tm &, memory_buf_t &dest) override {
|
||||
auto mdc_map = mdc::get_context();
|
||||
if (mdc_map.empty()) {
|
||||
ScopedPadder p(0, padinfo_, dest);
|
||||
return;
|
||||
} else {
|
||||
auto last_element = --mdc_map.end();
|
||||
for (auto it = mdc_map.begin(); it != mdc_map.end(); ++it) {
|
||||
auto &pair = *it;
|
||||
const auto &key = pair.first;
|
||||
const auto &value = pair.second;
|
||||
size_t content_size = key.size() + value.size() + 1; // 1 for ':'
|
||||
|
||||
if (it != last_element) {
|
||||
content_size++; // 1 for ' '
|
||||
}
|
||||
|
||||
ScopedPadder p(content_size, padinfo_, dest);
|
||||
fmt_helper::append_string_view(key, dest);
|
||||
fmt_helper::append_string_view(":", dest);
|
||||
fmt_helper::append_string_view(value, dest);
|
||||
if (it != last_element) {
|
||||
fmt_helper::append_string_view(" ", dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
SPDLOG_INLINE pattern_formatter::pattern_formatter(std::string pattern,
|
||||
@@ -1159,6 +1197,10 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i
|
||||
padding));
|
||||
break;
|
||||
|
||||
case ('&'):
|
||||
formatters_.push_back(details::make_unique<details::mdc_formatter<Padder>>(padding));
|
||||
break;
|
||||
|
||||
default: // Unknown flag appears as is
|
||||
auto unknown_flag = details::make_unique<details::aggregate_formatter>();
|
||||
|
||||
|
Reference in New Issue
Block a user