From e96ae7fd43b38545d627921bd04c3d3ededc98d2 Mon Sep 17 00:00:00 2001 From: gabime Date: Sat, 9 Nov 2024 15:51:53 +0200 Subject: [PATCH] Removed mdc support --- README.md | 15 --- example/example.cpp | 24 +---- include/spdlog/mdc.h | 50 ---------- include/spdlog/pattern_formatter-inl.h | 64 ------------ tests/test_pattern_formatter.cpp | 130 ------------------------- 5 files changed, 1 insertion(+), 282 deletions(-) delete mode 100644 include/spdlog/mdc.h diff --git a/README.md b/README.md index c45d7a0a..3982ad95 100644 --- a/README.md +++ b/README.md @@ -446,21 +446,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) ``` --- -#### Mapped Diagnostic Context -```c++ -// Mapped Diagnostic Context (MDC) is a map that stores key-value pairs (string values) in thread local storage. -// Each thread maintains its own MDC, which loggers use to append diagnostic information to log outputs. -// Note: it is not supported in asynchronous mode due to its reliance on thread-local storage. -#include "spdlog/mdc.h" -void mdc_example() -{ - spdlog::mdc::put("key1", "value1"); - spdlog::mdc::put("key2", "value2"); - // if not using the default format, use the %& formatter to print mdc data - // spdlog::set_pattern("[%H:%M:%S %z] [%^%L%$] [%&] %v"); -} -``` ---- ## Benchmarks Below are some [benchmarks](https://github.com/gabime/spdlog/blob/v1.x/bench/bench.cpp) done in Ubuntu 64 bit, Intel i7-4770 CPU @ 3.40GHz diff --git a/example/example.cpp b/example/example.cpp index a2daf372..3a557ca2 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -26,7 +26,6 @@ void udp_example(); void custom_flags_example(); void file_events_example(); void replace_default_logger_example(); -void mdc_example(); #include "spdlog/spdlog.h" #include "spdlog/cfg/env.h" // support for loading levels from the environment variable @@ -85,7 +84,6 @@ int main(int, char *[]) { custom_flags_example(); file_events_example(); replace_default_logger_example(); - mdc_example(); // Flush all *registered* loggers using a worker thread every 3 seconds. // note: registered loggers *must* be thread safe for this to work correctly! @@ -377,24 +375,4 @@ void replace_default_logger_example() { spdlog::debug("This message should be displayed.."); spdlog::set_default_logger(old_logger); -} - -// Mapped Diagnostic Context (MDC) is a map that stores key-value pairs (string values) in thread local storage. -// Each thread maintains its own MDC, which loggers use to append diagnostic information to log outputs. -// Note: it is not supported in asynchronous mode due to its reliance on thread-local storage. - -#ifndef SPDLOG_NO_TLS - #include "spdlog/mdc.h" -void mdc_example() -{ - spdlog::mdc::put("key1", "value1"); - spdlog::mdc::put("key2", "value2"); - // if not using the default format, you can use the %& formatter to print mdc data as well - spdlog::set_pattern("[%H:%M:%S %z] [%^%L%$] [%&] %v"); - spdlog::info("Some log message with context"); -} -#else -void mdc_example() { - // if TLS feature is disabled -} -#endif +} \ No newline at end of file diff --git a/include/spdlog/mdc.h b/include/spdlog/mdc.h deleted file mode 100644 index 80b6f25c..00000000 --- a/include/spdlog/mdc.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) - -#pragma once - -#if defined(SPDLOG_NO_TLS) - #error "This header requires thread local storage support, but SPDLOG_NO_TLS is defined." -#endif - -#include -#include - -#include - -// MDC is a simple map of key->string values stored in thread local storage whose content will be printed by the loggers. -// Note: Not supported in async mode (thread local storage - so the async thread pool have different copy). -// -// Usage example: -// spdlog::mdc::put("mdc_key_1", "mdc_value_1"); -// spdlog::info("Hello, {}", "World!"); // => [2024-04-26 02:08:05.040] [info] [mdc_key_1:mdc_value_1] Hello, World! - -namespace spdlog { -class SPDLOG_API mdc { -public: - using mdc_map_t = std::map; - - 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 mdc_map_t &get_context() { - static thread_local mdc_map_t context; - return context; - } -}; - -} // namespace spdlog diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index b53d8051..97714a73 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -788,49 +788,6 @@ private: 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 -#ifndef SPDLOG_NO_TLS -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); - } - } - } -}; -#endif - // Full info formatter // pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] [%s:%#] %v class full_formatter final : public flag_formatter { @@ -907,16 +864,6 @@ public: dest.push_back(' '); } -#ifndef SPDLOG_NO_TLS - // 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(' '); - } -#endif // fmt_helper::append_string_view(msg.msg(), dest); fmt_helper::append_string_view(msg.payload, dest); } @@ -924,11 +871,6 @@ public: private: std::chrono::seconds cache_timestamp_{0}; memory_buf_t cached_datetime_; - -#ifndef SPDLOG_NO_TLS - mdc_formatter mdc_formatter_{padding_info{}}; -#endif - }; } // namespace details @@ -1223,12 +1165,6 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i padding)); break; -#ifndef SPDLOG_NO_TLS // mdc formatter requires TLS support - case ('&'): - formatters_.push_back(details::make_unique>(padding)); - break; -#endif - default: // Unknown flag appears as is auto unknown_flag = details::make_unique(); diff --git a/tests/test_pattern_formatter.cpp b/tests/test_pattern_formatter.cpp index d248e996..350b973b 100644 --- a/tests/test_pattern_formatter.cpp +++ b/tests/test_pattern_formatter.cpp @@ -500,133 +500,3 @@ TEST_CASE("override need_localtime", "[pattern_formatter]") { REQUIRE(to_string_view(formatted) == oss.str()); } } - -#ifndef SPDLOG_NO_TLS -TEST_CASE("mdc formatter test-1", "[pattern_formatter]") { - spdlog::mdc::put("mdc_key_1", "mdc_value_1"); - spdlog::mdc::put("mdc_key_2", "mdc_value_2"); - - auto formatter = std::make_shared(); - formatter->set_pattern("[%n] [%l] [%&] %v"); - - memory_buf_t formatted; - spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, - "some message"); - formatter->format(msg, formatted); - - auto expected = spdlog::fmt_lib::format( - "[logger-name] [info] [mdc_key_1:mdc_value_1 mdc_key_2:mdc_value_2] some message{}", - spdlog::details::os::default_eol); - REQUIRE(to_string_view(formatted) == expected); - - SECTION("Tear down") { spdlog::mdc::clear(); } -} - -TEST_CASE("mdc formatter value update", "[pattern_formatter]") { - spdlog::mdc::put("mdc_key_1", "mdc_value_1"); - spdlog::mdc::put("mdc_key_2", "mdc_value_2"); - - auto formatter = std::make_shared(); - formatter->set_pattern("[%n] [%l] [%&] %v"); - - memory_buf_t formatted_1; - spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, - "some message"); - formatter->format(msg, formatted_1); - - auto expected = spdlog::fmt_lib::format( - "[logger-name] [info] [mdc_key_1:mdc_value_1 mdc_key_2:mdc_value_2] some message{}", - spdlog::details::os::default_eol); - - REQUIRE(to_string_view(formatted_1) == expected); - - spdlog::mdc::put("mdc_key_1", "new_mdc_value_1"); - memory_buf_t formatted_2; - formatter->format(msg, formatted_2); - expected = spdlog::fmt_lib::format( - "[logger-name] [info] [mdc_key_1:new_mdc_value_1 mdc_key_2:mdc_value_2] some message{}", - spdlog::details::os::default_eol); - - REQUIRE(to_string_view(formatted_2) == expected); - - SECTION("Tear down") { spdlog::mdc::clear(); } -} - -TEST_CASE("mdc different threads", "[pattern_formatter]") { - auto formatter = std::make_shared(); - formatter->set_pattern("[%n] [%l] [%&] %v"); - spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, - "some message"); - - memory_buf_t formatted_2; - - auto lambda_1 = [formatter, msg]() { - spdlog::mdc::put("mdc_key", "thread_1_id"); - memory_buf_t formatted; - formatter->format(msg, formatted); - - auto expected = - spdlog::fmt_lib::format("[logger-name] [info] [mdc_key:thread_1_id] some message{}", - spdlog::details::os::default_eol); - - REQUIRE(to_string_view(formatted) == expected); - }; - - auto lambda_2 = [formatter, msg]() { - spdlog::mdc::put("mdc_key", "thread_2_id"); - memory_buf_t formatted; - formatter->format(msg, formatted); - - auto expected = - spdlog::fmt_lib::format("[logger-name] [info] [mdc_key:thread_2_id] some message{}", - spdlog::details::os::default_eol); - - REQUIRE(to_string_view(formatted) == expected); - }; - - std::thread thread_1(lambda_1); - std::thread thread_2(lambda_2); - - thread_1.join(); - thread_2.join(); - - SECTION("Tear down") { spdlog::mdc::clear(); } -} - -TEST_CASE("mdc remove key", "[pattern_formatter]") { - spdlog::mdc::put("mdc_key_1", "mdc_value_1"); - spdlog::mdc::put("mdc_key_2", "mdc_value_2"); - spdlog::mdc::remove("mdc_key_1"); - - auto formatter = std::make_shared(); - formatter->set_pattern("[%n] [%l] [%&] %v"); - - memory_buf_t formatted; - spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, - "some message"); - formatter->format(msg, formatted); - - auto expected = - spdlog::fmt_lib::format("[logger-name] [info] [mdc_key_2:mdc_value_2] some message{}", - spdlog::details::os::default_eol); - REQUIRE(to_string_view(formatted) == expected); - - SECTION("Tear down") { spdlog::mdc::clear(); } -} - -TEST_CASE("mdc empty", "[pattern_formatter]") { - auto formatter = std::make_shared(); - formatter->set_pattern("[%n] [%l] [%&] %v"); - - memory_buf_t formatted; - spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, - "some message"); - formatter->format(msg, formatted); - - auto expected = spdlog::fmt_lib::format("[logger-name] [info] [] some message{}", - spdlog::details::os::default_eol); - REQUIRE(to_string_view(formatted) == expected); - - SECTION("Tear down") { spdlog::mdc::clear(); } -} -#endif