From ce996563d1fc53407014039fac921c8818dc903d Mon Sep 17 00:00:00 2001 From: Bailey Chittle Date: Thu, 22 Dec 2022 12:05:23 -0500 Subject: [PATCH] attributes can simulate structured logging, show example. Now works with pattern_formatter --- example/example.cpp | 18 +++++++++++++++++- include/spdlog/pattern_formatter-inl.h | 11 +++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/example/example.cpp b/example/example.cpp index 9cedfd53..a6f87678 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -27,6 +27,8 @@ void custom_flags_example(); void file_events_example(); void replace_default_logger_example(); +void attribute_example(); + #include "spdlog/spdlog.h" #include "spdlog/cfg/env.h" // support for loading levels from the environment variable #include "spdlog/fmt/ostr.h" // support for user defined types @@ -86,6 +88,7 @@ int main(int, char *[]) custom_flags_example(); file_events_example(); replace_default_logger_example(); + attribute_example(); // Flush all *registered* loggers using a worker thread every 3 seconds. // note: registered loggers *must* be thread safe for this to work correctly! @@ -94,7 +97,6 @@ int main(int, char *[]) // Apply some function on all registered loggers spdlog::apply_all([&](std::shared_ptr l) { l->info("End of example."); }); - spdlog::default_logger_raw()->log(spdlog::level::warn, "EXPERIMENTAL: log with attributes", {"attribute_key", "attribute value"}); // Release all spdlog resources, and drop all loggers in the registry. // This is optional (only mandatory if using windows + async log). spdlog::shutdown(); @@ -390,3 +392,17 @@ void replace_default_logger_example() spdlog::set_default_logger(old_logger); } + +void attribute_example() { + // spdlog::default_logger_raw()->log(spdlog::level::warn, "EXPERIMENTAL: log with attributes", {"attribute_key", "attribute value"}); + + // logfmt structured logging using attributes + + // auto logfmt_logger = spdlog::basic_logger_mt("logfmt_logger", "logs/mylog.txt"); + auto logfmt_logger = spdlog::default_logger_raw(); + + std::string logfmt_pattern = "time=%Y-%m-%dT%H:%M:%S.%f%z, name=%n, level=%^%l%$, process=%P, thread=%t, message=\"%v\""; + logfmt_logger->set_pattern(logfmt_pattern); + + logfmt_logger->log(spdlog::level::info, "logfmt structured logging", {"key", "value"}); +} \ No newline at end of file diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index 6b8ac54d..0fbd6d86 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -1086,6 +1086,17 @@ SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory { f->format(msg, cached_tm_, dest); } + // TODO: make separate function, and add a custom format to attributes (for now just using logfmt) + if (msg.attributes.size() > 0) { + details::fmt_helper::append_string_view(", ", dest); + for (const details::attr& a : msg.attributes) { + details::fmt_helper::append_string_view(a.key, dest); + details::fmt_helper::append_string_view("=\"", dest); + details::fmt_helper::append_string_view(a.value, dest); + details::fmt_helper::append_string_view("\", ", dest); + } + } + // write eol details::fmt_helper::append_string_view(eol_, dest); }