From 78830148db6a3829a29c676cf02016115828ab27 Mon Sep 17 00:00:00 2001 From: Bailey Chittle Date: Wed, 11 Jan 2023 11:44:29 -0500 Subject: [PATCH 1/6] experimenting with attribute formatting --- include/spdlog/pattern_formatter-inl.h | 68 ++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index ba866c68..0bc02754 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -929,6 +929,58 @@ private: log_clock::time_point last_message_time_; }; +// attribute formatting: stub +class attr_formatter_start final : public flag_formatter +{ +public: + explicit attr_formatter_start(padding_info padinfo) + : flag_formatter(padinfo) + {} + void format(const details::log_msg &, const std::tm &, memory_buf_t &dest) override + { + fmt_helper::append_string_view("", dest); + } +}; +class attr_formatter_stop final : public flag_formatter +{ +public: + explicit attr_formatter_stop(padding_info padinfo) + : flag_formatter(padinfo) + {} + void format(const details::log_msg &, const std::tm &, memory_buf_t &dest) override + { + fmt_helper::append_string_view("", dest); + } +}; + +class attr_formatter_key final : public flag_formatter +{ +public: + explicit attr_formatter_key(padding_info padinfo) + : flag_formatter(padinfo) + {} + void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override + { + for (const details::attr& a : msg.attributes) { + fmt_helper::append_string_view(a.key, dest); + } + } +}; + +class attr_formatter_value final : public flag_formatter +{ +public: + explicit attr_formatter_value(padding_info padinfo) + : flag_formatter(padinfo) + {} + void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override + { + for (const details::attr& a : msg.attributes) { + fmt_helper::append_string_view(a.value, dest); + } + } +}; + // Full info formatter // pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] [%s:%#] %v class full_formatter final : public flag_formatter @@ -1320,6 +1372,22 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i formatters_.push_back(details::make_unique>(padding)); break; + case ('['): // start attribute formatting + formatters_.push_back(details::make_unique(padding)); + break; + + case ('K'): // attribute key + formatters_.push_back(details::make_unique(padding)); + break; + + case ('V'): // attribute value + formatters_.push_back(details::make_unique(padding)); + break; + + case (']'): // stop attribute formatting + formatters_.push_back(details::make_unique(padding)); + break; + default: // Unknown flag appears as is auto unknown_flag = details::make_unique(); From 785c3a5b0f26442f693fee51302bdaad6e2b1698 Mon Sep 17 00:00:00 2001 From: Bailey Chittle Date: Wed, 11 Jan 2023 13:29:40 -0500 Subject: [PATCH 2/6] custom pattern formatting is now functional --- include/spdlog/pattern_formatter-inl.h | 55 ++++++++++++++++---------- include/spdlog/pattern_formatter.h | 14 +++++++ 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index 0bc02754..d04e28f4 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -934,7 +934,7 @@ class attr_formatter_start final : public flag_formatter { public: explicit attr_formatter_start(padding_info padinfo) - : flag_formatter(padinfo) + : flag_formatter(padinfo, details::attr_flags::start) {} void format(const details::log_msg &, const std::tm &, memory_buf_t &dest) override { @@ -945,7 +945,7 @@ class attr_formatter_stop final : public flag_formatter { public: explicit attr_formatter_stop(padding_info padinfo) - : flag_formatter(padinfo) + : flag_formatter(padinfo, details::attr_flags::stop) {} void format(const details::log_msg &, const std::tm &, memory_buf_t &dest) override { @@ -957,13 +957,11 @@ class attr_formatter_key final : public flag_formatter { public: explicit attr_formatter_key(padding_info padinfo) - : flag_formatter(padinfo) + : flag_formatter(padinfo, details::attr_flags::key) {} - void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override + void format(const details::log_msg &, const std::tm &, memory_buf_t &dest) override { - for (const details::attr& a : msg.attributes) { - fmt_helper::append_string_view(a.key, dest); - } + fmt_helper::append_string_view("", dest); } }; @@ -971,13 +969,11 @@ class attr_formatter_value final : public flag_formatter { public: explicit attr_formatter_value(padding_info padinfo) - : flag_formatter(padinfo) + : flag_formatter(padinfo, details::attr_flags::value) {} - void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override + void format(const details::log_msg &, const std::tm &, memory_buf_t &dest) override { - for (const details::attr& a : msg.attributes) { - fmt_helper::append_string_view(a.value, dest); - } + fmt_helper::append_string_view("", dest); } }; @@ -1128,16 +1124,33 @@ SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory } } - for (auto &f : formatters_) + auto it_end = formatters_.begin(); + for (auto it = formatters_.begin(); it != formatters_.end(); ++it) { - f->format(msg, cached_tm_, dest); - } - // TODO: make separate function, and add a custom format to attributes (for now just using logfmt) - 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); + if ((*it)->flag_ == details::attr_flags::start) { + if (msg.attributes.size() == 0) { + while((*it)->flag_ != details::attr_flags::stop && it != formatters_.end()) ++it; + it_end = it; + } + for (const details::attr& a : msg.attributes) { + for (auto it2 = it; it2 != formatters_.end(); ++it2) { + if ((*it2)->flag_ == details::attr_flags::stop) { + it_end = it2; + break; + } else if ((*it2)->flag_ == details::attr_flags::key) { + // custom formatting function overload makes this even more messy with reinterpret casts, + // will just do manual key addition + details::fmt_helper::append_string_view(a.key, dest); + } else if ((*it2)->flag_ == details::attr_flags::value) { + details::fmt_helper::append_string_view(a.value, dest); + } else { + (*it2)->format(msg, cached_tm_, dest); + } + } + } + it = it_end; + } + (*it)->format(msg, cached_tm_, dest); } // write eol diff --git a/include/spdlog/pattern_formatter.h b/include/spdlog/pattern_formatter.h index acf1c536..abe238e7 100644 --- a/include/spdlog/pattern_formatter.h +++ b/include/spdlog/pattern_formatter.h @@ -47,16 +47,30 @@ struct padding_info bool enabled_ = false; }; +enum class attr_flags { + none, + start, + stop, + key, + value +}; + class SPDLOG_API flag_formatter { public: explicit flag_formatter(padding_info padinfo) : padinfo_(padinfo) {} + explicit flag_formatter(padding_info padinfo, attr_flags flag) + : padinfo_(padinfo) + , flag_{flag} + {} flag_formatter() = default; virtual ~flag_formatter() = default; virtual void format(const details::log_msg &msg, const std::tm &tm_time, memory_buf_t &dest) = 0; + attr_flags flag_ = attr_flags::none; + protected: padding_info padinfo_; }; From 3aba11dfa0a5674d470fc9bc4cf90e18f414d62f Mon Sep 17 00:00:00 2001 From: Bailey Chittle Date: Wed, 11 Jan 2023 14:54:28 -0500 Subject: [PATCH 3/6] fixed reordering error --- include/spdlog/pattern_formatter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spdlog/pattern_formatter.h b/include/spdlog/pattern_formatter.h index abe238e7..ad7dc8f5 100644 --- a/include/spdlog/pattern_formatter.h +++ b/include/spdlog/pattern_formatter.h @@ -62,8 +62,8 @@ public: : padinfo_(padinfo) {} explicit flag_formatter(padding_info padinfo, attr_flags flag) - : padinfo_(padinfo) - , flag_{flag} + : flag_(flag) + , padinfo_(padinfo) {} flag_formatter() = default; virtual ~flag_formatter() = default; From 82e4553e033bd9351877942494602a1d73873b3f Mon Sep 17 00:00:00 2001 From: Bailey Chittle Date: Wed, 11 Jan 2023 15:29:00 -0500 Subject: [PATCH 4/6] changed switch statement due to an interesting bug I found --- include/spdlog/pattern_formatter-inl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index d04e28f4..30648276 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -1385,7 +1385,7 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i formatters_.push_back(details::make_unique>(padding)); break; - case ('['): // start attribute formatting + case ('('): // start attribute formatting formatters_.push_back(details::make_unique(padding)); break; @@ -1397,7 +1397,7 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i formatters_.push_back(details::make_unique(padding)); break; - case (']'): // stop attribute formatting + case (')'): // stop attribute formatting formatters_.push_back(details::make_unique(padding)); break; From 3383207ef5c9a021de4f90e9684b0f7ab88daf0b Mon Sep 17 00:00:00 2001 From: Bailey Chittle Date: Wed, 11 Jan 2023 15:49:34 -0500 Subject: [PATCH 5/6] default kv pairs --- include/spdlog/pattern_formatter-inl.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index 30648276..cceef76d 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -1060,7 +1060,14 @@ public: fmt_helper::append_string_view(msg.payload, dest); if (msg.attributes.size() > 0) { + // by default uses logfmt-esque kv pairs fmt_helper::append_string_view(" | ", dest); // separate message from attributes + 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); + } } } From 0b48d79fff32a3103f26d474809d668bf0b0ab2c Mon Sep 17 00:00:00 2001 From: Bailey Chittle Date: Wed, 11 Jan 2023 15:52:57 -0500 Subject: [PATCH 6/6] fixed example to include new pattern formatting --- example/example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/example.cpp b/example/example.cpp index a920c6de..ed95db94 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -390,7 +390,7 @@ void attribute_example() { // auto logfmt_logger = spdlog::basic_logger_mt("logfmt_logger", "logs/mylog.txt"); auto logfmt_logger = spdlog::stdout_color_mt("logfmt_logger"); - std::string logfmt_pattern = "time=%Y-%m-%dT%H:%M:%S.%f%z name=%n level=%^%l%$ process=%P thread=%t message=\"%v\" "; + std::string logfmt_pattern = "time=%Y-%m-%dT%H:%M:%S.%f%z name=%n level=%^%l%$ process=%P thread=%t message=\"%v\"%( %K=\"%V\"%)"; logfmt_logger->set_pattern(logfmt_pattern); logfmt_logger->info("logfmt structured logging", spdlog::attribute_list{{"key\n1", "value\n1"}, {"key\r\n2", "value\r\n2"}});