diff --git a/include/spdlog/mdc.h b/include/spdlog/mdc.h index 20ae64f43..ae4dfbb93 100644 --- a/include/spdlog/mdc.h +++ b/include/spdlog/mdc.h @@ -1,35 +1,34 @@ -// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) - #pragma once #include +#include namespace spdlog { + class mdc { + public: + using mdc_map_t = std::map; + + static void put(const std::string &key, const std::string &value) { + get_context()[key] = value; + } -class 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; + 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 ""; } - return ""; - } - static void remove(const std::string &key) { get_context().erase(key); } + static void remove(const std::string &key) { get_context().erase(key); } - static void clear() { get_context().clear(); } + static void clear() { get_context().clear(); } - static std::map &get_context() { - static thread_local std::map context; - return context; - } -}; + static mdc_map_t &get_context() { + static thread_local mdc_map_t context; + return context; + } + }; -} // namespace spdlog +} // namespace spdlog \ No newline at end of file diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index ce7e21052..65e22d450 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -784,6 +784,49 @@ class elapsed_formatter final : public flag_formatter { log_clock::time_point last_message_time_; }; +// 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 +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 { + format_mdc(mdc_map, dest); + } + } + + void format_mdc(const mdc::mdc_map_t &mdc_map, memory_buf_t &dest){ + 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); + } + } + } +}; + + + // Full info formatter // pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] [%s:%#] %v class full_formatter final : public flag_formatter { @@ -859,6 +902,15 @@ class full_formatter final : public flag_formatter { dest.push_back(']'); dest.push_back(' '); } + + // add mdc if present + auto &mdc_map = mdc::get_context(); + if (!mdc_map.empty()) { + dest.push_back('['); + mdc_formatter_.format_mdc(mdc_map, dest); + dest.push_back(']'); + dest.push_back(' '); + } // fmt_helper::append_string_view(msg.msg(), dest); fmt_helper::append_string_view(msg.payload, dest); } @@ -866,44 +918,10 @@ class full_formatter final : public flag_formatter { private: std::chrono::seconds cache_timestamp_{0}; memory_buf_t cached_datetime_; + mdc_formatter mdc_formatter_{padding_info{}}; }; -// 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 -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