mirror of
https://github.com/gabime/spdlog.git
synced 2024-12-25 10:01:33 +08:00
Removed mdc support
This commit is contained in:
parent
c4922b1304
commit
e96ae7fd43
15
README.md
15
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
|
||||
|
@ -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
|
||||
}
|
@ -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 <map>
|
||||
#include <string>
|
||||
|
||||
#include <spdlog/common.h>
|
||||
|
||||
// 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<std::string, std::string>;
|
||||
|
||||
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
|
@ -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 <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 {
|
||||
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<null_scoped_padder> 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<details::mdc_formatter<Padder>>(padding));
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: // Unknown flag appears as is
|
||||
auto unknown_flag = details::make_unique<details::aggregate_formatter>();
|
||||
|
||||
|
@ -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<spdlog::pattern_formatter>();
|
||||
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<spdlog::pattern_formatter>();
|
||||
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<spdlog::pattern_formatter>();
|
||||
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<spdlog::pattern_formatter>();
|
||||
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<spdlog::pattern_formatter>();
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user