From 0c19bdd7725028fe07751bbef02bdf1326829591 Mon Sep 17 00:00:00 2001 From: gabime Date: Sun, 24 Jun 2018 01:32:39 +0300 Subject: [PATCH] pattern per sink and pattern caching --- include/spdlog/common.h | 2 +- include/spdlog/details/async_logger_impl.h | 1 - include/spdlog/details/file_helper.h | 6 +- include/spdlog/details/fmt_helper.h | 8 +- include/spdlog/details/log_msg.h | 5 +- include/spdlog/details/logger_impl.h | 13 +- .../spdlog/details/pattern_formatter_impl.h | 305 ++++++++++-------- include/spdlog/details/registry.h | 23 +- include/spdlog/formatter.h | 18 +- include/spdlog/logger.h | 19 +- include/spdlog/sinks/android_sink.h | 12 +- include/spdlog/sinks/ansicolor_sink.h | 15 +- include/spdlog/sinks/base_sink.h | 21 +- include/spdlog/sinks/daily_file_sink.h | 4 +- include/spdlog/sinks/null_sink.h | 4 +- include/spdlog/sinks/ostream_sink.h | 4 +- include/spdlog/sinks/rotating_file_sink.h | 8 +- include/spdlog/sinks/simple_file_sink.h | 4 +- include/spdlog/sinks/sink.h | 61 ++-- include/spdlog/sinks/wincolor_sink.h | 16 +- include/spdlog/spdlog.h | 5 - tests/file_helper.cpp | 6 +- tests/test_pattern_formatter.cpp | 57 ++-- tests/test_sink.h | 2 +- 24 files changed, 349 insertions(+), 270 deletions(-) diff --git a/include/spdlog/common.h b/include/spdlog/common.h index 394bc032..a6c505df 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -49,7 +49,7 @@ #define SPDLOG_DEPRECATED #endif -#include "fmt/fmt.h" +#include "spdlog/fmt/fmt.h" namespace spdlog { diff --git a/include/spdlog/details/async_logger_impl.h b/include/spdlog/details/async_logger_impl.h index 06023cf7..9b3b86d3 100644 --- a/include/spdlog/details/async_logger_impl.h +++ b/include/spdlog/details/async_logger_impl.h @@ -71,7 +71,6 @@ inline void spdlog::async_logger::backend_log_(details::log_msg &incoming_log_ms { try { - formatter_->format(incoming_log_msg); for (auto &s : sinks_) { if (s->should_log(incoming_log_msg.level)) diff --git a/include/spdlog/details/file_helper.h b/include/spdlog/details/file_helper.h index 997e1c95..f7a7b2a8 100644 --- a/include/spdlog/details/file_helper.h +++ b/include/spdlog/details/file_helper.h @@ -80,10 +80,10 @@ public: } } - void write(const log_msg &msg) + void write(const fmt::memory_buffer &buf) { - size_t msg_size = msg.formatted.size(); - auto data = msg.formatted.data(); + size_t msg_size = buf.size(); + auto data = buf.data(); if (std::fwrite(data, 1, msg_size, fd_) != msg_size) { throw spdlog_ex("Failed writing to file " + os::filename_to_str(_filename), errno); diff --git a/include/spdlog/details/fmt_helper.h b/include/spdlog/details/fmt_helper.h index c4c605cb..ffeca007 100644 --- a/include/spdlog/details/fmt_helper.h +++ b/include/spdlog/details/fmt_helper.h @@ -14,6 +14,12 @@ inline void append_str(const std::string &str, fmt::memory_buffer &dest) dest.append(str_ptr, str_ptr + str.size()); } +inline void append_c_str(const char *c_str, fmt::memory_buffer &dest) +{ + auto str_size = strlen(c_str); + dest.append(c_str, c_str + str_size); +} + inline void append_buf(const fmt::memory_buffer &buf, fmt::memory_buffer &dest) { const char *buf_ptr = buf.data(); @@ -74,7 +80,7 @@ inline void append_and_pad3(int n, fmt::memory_buffer &dest) append_int(n, dest); } -void append_and_pad6(int n, fmt::memory_buffer &dest) +inline void append_and_pad6(int n, fmt::memory_buffer &dest) { if (n > 99999) { diff --git a/include/spdlog/details/log_msg.h b/include/spdlog/details/log_msg.h index 998c5ee0..ce988e4f 100644 --- a/include/spdlog/details/log_msg.h +++ b/include/spdlog/details/log_msg.h @@ -38,11 +38,10 @@ struct log_msg log_clock::time_point time; size_t thread_id; fmt::memory_buffer raw; - fmt::memory_buffer formatted; size_t msg_id{0}; // info about wrapping the formatted text with color - size_t color_range_start{0}; - size_t color_range_end{0}; + mutable size_t color_range_start{0}; + mutable size_t color_range_end{0}; }; } // namespace details } // namespace spdlog diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index 612001f1..5a61a709 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -14,7 +14,6 @@ template inline spdlog::logger::logger(std::string logger_name, const It &begin, const It &end) : name_(std::move(logger_name)) , sinks_(begin, end) - , formatter_(std::make_shared("%+")) , level_(level::info) , flush_level_(level::off) , last_err_time_(0) @@ -37,14 +36,19 @@ inline spdlog::logger::logger(const std::string &logger_name, spdlog::sink_ptr s inline spdlog::logger::~logger() = default; -inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter) +template +inline void spdlog::logger::set_formatter(const Args &... args) { - formatter_ = std::move(msg_formatter); + for (auto &sink : sinks_) + { + std::unique_ptr formatter(new FormatterT(args...)); + sink->set_formatter(std::move(formatter)); + } } inline void spdlog::logger::set_pattern(const std::string &pattern, pattern_time_type pattern_time) { - formatter_ = std::make_shared(pattern, pattern_time); + set_formatter(pattern, pattern_time); } template @@ -288,7 +292,6 @@ inline void spdlog::logger::sink_it_(details::log_msg &msg) #if defined(SPDLOG_ENABLE_MESSAGE_COUNTER) incr_msg_counter_(msg); #endif - formatter_->format(msg); for (auto &sink : sinks_) { if (sink->should_log(msg.level)) diff --git a/include/spdlog/details/pattern_formatter_impl.h b/include/spdlog/details/pattern_formatter_impl.h index aa21c228..61edaa97 100644 --- a/include/spdlog/details/pattern_formatter_impl.h +++ b/include/spdlog/details/pattern_formatter_impl.h @@ -28,7 +28,7 @@ class flag_formatter { public: virtual ~flag_formatter() = default; - virtual void format(details::log_msg &msg, const std::tm &tm_time) = 0; + virtual void format(const details::log_msg &msg, const std::tm &tm_time, fmt::memory_buffer &dest) = 0; }; /////////////////////////////////////////////////////////////////////// @@ -36,27 +36,27 @@ public: /////////////////////////////////////////////////////////////////////// class name_formatter : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { - fmt_helper::append_str(*msg.logger_name, msg.formatted); + fmt_helper::append_str(*msg.logger_name, dest); } }; // log level appender class level_formatter : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { - fmt_helper::append_str(level::to_str(msg.level), msg.formatted); + fmt_helper::append_c_str(level::to_str(msg.level), dest); } }; // short log level appender class short_level_formatter : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { - fmt_helper::append_str(level::to_short_str(msg.level), msg.formatted); + fmt_helper::append_c_str(level::to_short_str(msg.level), dest); } }; @@ -78,9 +78,9 @@ static int to12h(const tm &t) static const std::string days[]{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; class a_formatter : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_str(days[tm_time.tm_wday], msg.formatted); + fmt_helper::append_str(days[tm_time.tm_wday], dest); } }; @@ -88,9 +88,9 @@ class a_formatter : public flag_formatter static const std::string full_days[]{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; class A_formatter : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_str(full_days[tm_time.tm_wday], msg.formatted); + fmt_helper::append_str(full_days[tm_time.tm_wday], dest); } }; @@ -98,9 +98,9 @@ class A_formatter : public flag_formatter static const std::string months[]{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"}; class b_formatter : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_str(months[tm_time.tm_mon], msg.formatted); + fmt_helper::append_str(months[tm_time.tm_mon], dest); } }; @@ -109,205 +109,203 @@ static const std::string full_months[]{ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; class B_formatter : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_str(full_months[tm_time.tm_mon], msg.formatted); + fmt_helper::append_str(full_months[tm_time.tm_mon], dest); } }; // Date and time representation (Thu Aug 23 15:35:46 2014) class c_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt::format_to(msg.formatted, "{} {} {} ", days[tm_time.tm_wday], months[tm_time.tm_mon], tm_time.tm_mday); // - fmt_helper::append_and_pad2(tm_time.tm_hour, msg.formatted); - msg.formatted.push_back(':'); - fmt_helper::append_and_pad2(tm_time.tm_min, msg.formatted); - msg.formatted.push_back(':'); - fmt_helper::append_and_pad2(tm_time.tm_sec, msg.formatted); - msg.formatted.push_back(' '); - fmt_helper::append_int(tm_time.tm_year + 1900, msg.formatted); + fmt::format_to(dest, "{} {} {} ", days[tm_time.tm_wday], months[tm_time.tm_mon], tm_time.tm_mday); // + fmt_helper::append_and_pad2(tm_time.tm_hour, dest); + dest.push_back(':'); + fmt_helper::append_and_pad2(tm_time.tm_min, dest); + dest.push_back(':'); + fmt_helper::append_and_pad2(tm_time.tm_sec, dest); + dest.push_back(' '); + fmt_helper::append_int(tm_time.tm_year + 1900, dest); } }; // year - 2 digit class C_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_and_pad2(tm_time.tm_year % 100, msg.formatted); + fmt_helper::append_and_pad2(tm_time.tm_year % 100, dest); } }; // Short MM/DD/YY date, equivalent to %m/%d/%y 08/23/01 class D_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_and_pad2(tm_time.tm_mon + 1, msg.formatted); - msg.formatted.push_back('/'); - fmt_helper::append_and_pad2(tm_time.tm_mday, msg.formatted); - msg.formatted.push_back('/'); - fmt_helper::append_and_pad2(tm_time.tm_year % 100, msg.formatted); + fmt_helper::append_and_pad2(tm_time.tm_mon + 1, dest); + dest.push_back('/'); + fmt_helper::append_and_pad2(tm_time.tm_mday, dest); + dest.push_back('/'); + fmt_helper::append_and_pad2(tm_time.tm_year % 100, dest); } }; // year - 4 digit class Y_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_int(tm_time.tm_year + 1900, msg.formatted); + fmt_helper::append_int(tm_time.tm_year + 1900, dest); } }; // month 1-12 class m_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_and_pad2(tm_time.tm_mon + 1, msg.formatted); + fmt_helper::append_and_pad2(tm_time.tm_mon + 1, dest); } }; // day of month 1-31 class d_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - // fmt::format_to(msg.formatted, "{:02}", tm_time.tm_mday); - fmt_helper::append_and_pad2(tm_time.tm_mday, msg.formatted); + // fmt::format_to(dest, "{:02}", tm_time.tm_mday); + fmt_helper::append_and_pad2(tm_time.tm_mday, dest); } }; // hours in 24 format 0-23 class H_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_and_pad2(tm_time.tm_hour, msg.formatted); + fmt_helper::append_and_pad2(tm_time.tm_hour, dest); } }; // hours in 12 format 1-12 class I_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_and_pad2(to12h(tm_time), msg.formatted); + fmt_helper::append_and_pad2(to12h(tm_time), dest); } }; // minutes 0-59 class M_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_and_pad2(tm_time.tm_min, msg.formatted); + fmt_helper::append_and_pad2(tm_time.tm_min, dest); } }; // seconds 0-59 class S_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt_helper::append_and_pad2(tm_time.tm_sec, msg.formatted); + fmt_helper::append_and_pad2(tm_time.tm_sec, dest); } }; // milliseconds class e_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { auto duration = msg.time.time_since_epoch(); auto millis = std::chrono::duration_cast(duration).count() % 1000; - fmt_helper::append_and_pad3(static_cast(millis), msg.formatted); + fmt_helper::append_and_pad3(static_cast(millis), dest); } }; // microseconds class f_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { auto duration = msg.time.time_since_epoch(); auto micros = std::chrono::duration_cast(duration).count() % 1000000; - fmt_helper::append_and_pad6(static_cast(micros), msg.formatted); + fmt_helper::append_and_pad6(static_cast(micros), dest); } }; // nanoseconds class F_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { auto duration = msg.time.time_since_epoch(); auto ns = std::chrono::duration_cast(duration).count() % 1000000000; - fmt::format_to(msg.formatted, "{:09}", static_cast(ns)); + fmt::format_to(dest, "{:09}", static_cast(ns)); } }; class E_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { auto duration = msg.time.time_since_epoch(); auto seconds = std::chrono::duration_cast(duration).count(); - // fmt::format_to(msg.formatted, "{}", seconds); - fmt_helper::append_int(seconds, msg.formatted); + fmt_helper::append_int(seconds, dest); } }; // AM/PM class p_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - fmt::format_to(msg.formatted, "{}", ampm(tm_time)); + fmt::format_to(dest, "{}", ampm(tm_time)); } }; // 12 hour clock 02:55:02 pm class r_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - // fmt::format_to(msg.formatted, "{:02}:{:02}:{:02} {}", to12h(tm_time), tm_time.tm_min, tm_time.tm_sec, ampm(tm_time)); - fmt_helper::append_and_pad2(to12h(tm_time), msg.formatted); - msg.formatted.push_back(':'); - fmt_helper::append_and_pad2(tm_time.tm_min, msg.formatted); - msg.formatted.push_back(':'); - fmt_helper::append_and_pad2(tm_time.tm_sec, msg.formatted); - fmt::format_to(msg.formatted, " {}", ampm(tm_time)); + // fmt::format_to(dest, "{:02}:{:02}:{:02} {}", to12h(tm_time), tm_time.tm_min, tm_time.tm_sec, ampm(tm_time)); + fmt_helper::append_and_pad2(to12h(tm_time), dest); + dest.push_back(':'); + fmt_helper::append_and_pad2(tm_time.tm_min, dest); + dest.push_back(':'); + fmt_helper::append_and_pad2(tm_time.tm_sec, dest); + fmt::format_to(dest, " {}", ampm(tm_time)); } }; // 24-hour HH:MM time, equivalent to %H:%M class R_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - // fmt::format_to(msg.formatted, "{:02}:{:02}", tm_time.tm_hour, tm_time.tm_min); - fmt_helper::append_and_pad2(tm_time.tm_hour, msg.formatted); - msg.formatted.push_back(':'); - fmt_helper::append_and_pad2(tm_time.tm_min, msg.formatted); + fmt_helper::append_and_pad2(tm_time.tm_hour, dest); + dest.push_back(':'); + fmt_helper::append_and_pad2(tm_time.tm_min, dest); } }; // ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S class T_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override { - // fmt::format_to(msg.formatted, "{:02}:{:02}:{:02}", tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec); - fmt_helper::append_and_pad2(tm_time.tm_hour, msg.formatted); - msg.formatted.push_back(':'); - fmt_helper::append_and_pad2(tm_time.tm_min, msg.formatted); - msg.formatted.push_back(':'); - fmt_helper::append_and_pad2(tm_time.tm_sec, msg.formatted); + // fmt::format_to(dest, "{:02}:{:02}:{:02}", tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec); + fmt_helper::append_and_pad2(tm_time.tm_hour, dest); + dest.push_back(':'); + fmt_helper::append_and_pad2(tm_time.tm_min, dest); + dest.push_back(':'); + fmt_helper::append_and_pad2(tm_time.tm_sec, dest); } }; @@ -321,13 +319,14 @@ public: z_formatter(const z_formatter &) = delete; z_formatter &operator=(const z_formatter &) = delete; - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &msg, const std::tm &tm_time, fmt::memory_buffer &dest) override { #ifdef _WIN32 int total_minutes = get_cached_offset(msg, tm_time); #else // No need to chache under gcc, // it is very fast (already stored in tm.tm_gmtoff) + (void)(msg); int total_minutes = os::utc_minutes_offset(tm_time); #endif bool is_negative = total_minutes < 0; @@ -344,21 +343,19 @@ public: int h = total_minutes / 60; int m = total_minutes % 60; - // fmt::format_to(msg.formatted, "{}{:02}:{:02}", sign, h, m); - msg.formatted.push_back(sign); - fmt_helper::append_and_pad2(h, msg.formatted); - msg.formatted.push_back(':'); - fmt_helper::append_and_pad2(m, msg.formatted); + dest.push_back(sign); + fmt_helper::append_and_pad2(h, dest); + dest.push_back(':'); + fmt_helper::append_and_pad2(m, dest); } private: log_clock::time_point last_update_{std::chrono::seconds(0)}; +#ifdef _WIN32 int offset_minutes_{0}; - std::mutex mutex_; int get_cached_offset(const log_msg &msg, const std::tm &tm_time) { - std::lock_guard l(mutex_); if (msg.time - last_update_ >= cache_refresh) { offset_minutes_ = os::utc_minutes_offset(tm_time); @@ -366,42 +363,42 @@ private: } return offset_minutes_; } +#endif }; // Thread id class t_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { - // fmt::format_to(msg.formatted, "{}", msg.thread_id); - fmt_helper::append_size_t(msg.thread_id, msg.formatted); + // fmt::format_to(dest, "{}", msg.thread_id); + fmt_helper::append_size_t(msg.thread_id, dest); } }; // Current pid class pid_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &, const std::tm &, fmt::memory_buffer &dest) override { - // fmt::format_to(msg.formatted, "{}", details::os::pid()); - fmt_helper::append_int(details::os::pid(), msg.formatted); + fmt_helper::append_int(details::os::pid(), dest); } }; // message counter formatter class i_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { - fmt::format_to(msg.formatted, "{:06}", msg.msg_id); + fmt::format_to(dest, "{:06}", msg.msg_id); } }; class v_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { - fmt_helper::append_buf(msg.raw, msg.formatted); + fmt_helper::append_buf(msg.raw, dest); } }; @@ -412,9 +409,9 @@ public: : ch_(ch) { } - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &, const std::tm &, fmt::memory_buffer &dest) override { - msg.formatted.push_back(ch_); + dest.push_back(ch_); } private: @@ -431,9 +428,9 @@ public: { str_ += ch; } - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &, const std::tm &, fmt::memory_buffer &dest) override { - fmt_helper::append_str(str_, msg.formatted); + fmt_helper::append_str(str_, dest); } private: @@ -443,16 +440,16 @@ private: // mark the color range. expect it to be in the form of "%^colored text%$" class color_start_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { - msg.color_range_start = msg.formatted.size(); + msg.color_range_start = dest.size(); } }; class color_stop_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &) override + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override { - msg.color_range_end = msg.formatted.size(); + msg.color_range_end = dest.size(); } }; @@ -460,54 +457,80 @@ class color_stop_formatter SPDLOG_FINAL : public flag_formatter // pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v class full_formatter SPDLOG_FINAL : public flag_formatter { - void format(details::log_msg &msg, const std::tm &tm_time) override + void format(const details::log_msg &msg, const std::tm &tm_time, fmt::memory_buffer &dest) override { #ifndef SPDLOG_NO_DATETIME auto duration = msg.time.time_since_epoch(); + + // each second cache the header + auto seconds = std::chrono::duration_cast(duration).count(); + if (cached_header_.size() == 0 || cached_seconds_ts_ != seconds) + { + + cached_header_ = std::move(fmt::memory_buffer()); + cached_header_.push_back('['); + fmt_helper::append_int(tm_time.tm_year + 1900, cached_header_); + cached_header_.push_back('-'); + + fmt_helper::append_and_pad2(tm_time.tm_mon + 1, cached_header_); + cached_header_.push_back('-'); + + fmt_helper::append_and_pad2(tm_time.tm_mday, cached_header_); + cached_header_.push_back(' '); + + fmt_helper::append_and_pad2(tm_time.tm_hour, cached_header_); + cached_header_.push_back(':'); + + fmt_helper::append_and_pad2(tm_time.tm_min, cached_header_); + cached_header_.push_back(':'); + + fmt_helper::append_and_pad2(tm_time.tm_sec, cached_header_); + cached_header_.push_back('.'); + + cached_seconds_ts_ = seconds; + } + fmt_helper::append_buf(cached_header_, dest); + + // auto millis = std::chrono::duration_cast(duration).count() % 1000; - msg.formatted.push_back('['); - fmt_helper::append_int(tm_time.tm_year + 1900, msg.formatted); - msg.formatted.push_back('-'); + if (cached_millis_.size() == 0 || millis != cached_millis_ts_) + { + cached_millis_ = std::move(fmt::memory_buffer()); + fmt_helper::append_and_pad3(static_cast(millis), cached_millis_); + cached_millis_.push_back(']'); + cached_millis_.push_back(' '); + cached_millis_ts_ = millis; + } + fmt_helper::append_buf(cached_millis_, dest); - fmt_helper::append_and_pad2(tm_time.tm_mon + 1, msg.formatted); - msg.formatted.push_back('-'); - - fmt_helper::append_and_pad2(tm_time.tm_mday, msg.formatted); - msg.formatted.push_back(' '); - - fmt_helper::append_and_pad2(tm_time.tm_hour, msg.formatted); - msg.formatted.push_back(':'); - - fmt_helper::append_and_pad2(tm_time.tm_min, msg.formatted); - msg.formatted.push_back(':'); - - fmt_helper::append_and_pad2(tm_time.tm_sec, msg.formatted); - msg.formatted.push_back('.'); - - fmt_helper::append_and_pad3(static_cast(millis), msg.formatted); - msg.formatted.push_back(']'); - msg.formatted.push_back(' '); - - // no datetime needed -#else +#else // no datetime needed (void)tm_time; #endif #ifndef SPDLOG_NO_NAME - fmt_helper::append_str(*msg.logger_name, msg.formatted); + dest.push_back('['); + fmt_helper::append_str(*msg.logger_name, dest); + dest.push_back(']'); + dest.push_back(' '); #endif - msg.formatted.push_back('['); + dest.push_back('['); // wrap the level name with color - msg.color_range_start = msg.formatted.size(); - fmt_helper::append_str(level::to_str(msg.level), msg.formatted); - msg.color_range_end = msg.formatted.size(); - msg.formatted.push_back(']'); - msg.formatted.push_back(' '); - fmt_helper::append_buf(msg.raw, msg.formatted); + msg.color_range_start = dest.size(); + fmt_helper::append_c_str(level::to_str(msg.level), dest); + msg.color_range_end = dest.size(); + dest.push_back(']'); + dest.push_back(' '); + fmt_helper::append_buf(msg.raw, dest); } + +private: + long cached_seconds_ts_{0}; + long cached_millis_ts_{0}; + fmt::memory_buffer cached_header_; + fmt::memory_buffer cached_millis_; }; } // namespace details @@ -704,7 +727,7 @@ inline void spdlog::pattern_formatter::handle_flag(char flag) } } -inline std::tm spdlog::pattern_formatter::get_time(details::log_msg &msg) +inline std::tm spdlog::pattern_formatter::get_time(const details::log_msg &msg) { if (pattern_time_ == pattern_time_type::local) { @@ -713,7 +736,7 @@ inline std::tm spdlog::pattern_formatter::get_time(details::log_msg &msg) return details::os::gmtime(log_clock::to_time_t(msg.time)); } -inline void spdlog::pattern_formatter::format(details::log_msg &msg) +inline void spdlog::pattern_formatter::format(const details::log_msg &msg, fmt::memory_buffer &dest) { #ifndef SPDLOG_NO_DATETIME @@ -723,8 +746,8 @@ inline void spdlog::pattern_formatter::format(details::log_msg &msg) #endif for (auto &f : formatters_) { - f->format(msg, tm_time); + f->format(msg, tm_time, dest); } // write eol - details::fmt_helper::append_str(eol_, msg.formatted); + details::fmt_helper::append_str(eol_, dest); } diff --git a/include/spdlog/details/registry.h b/include/spdlog/details/registry.h index bbc9ffef..85111d23 100644 --- a/include/spdlog/details/registry.h +++ b/include/spdlog/details/registry.h @@ -46,10 +46,9 @@ public: auto logger_name = new_logger->name(); throw_if_exists(logger_name); - if (formatter_) - { - new_logger->set_formatter(formatter_); - } + // create default formatter if not exists + + new_logger->set_pattern(formatter_pattern_); if (err_handler_) { @@ -82,23 +81,13 @@ public: return tp_; } - void set_formatter(formatter_ptr f) - { - std::lock_guard lock(mutex_); - formatter_ = f; - for (auto &l : loggers_) - { - l.second->set_formatter(formatter_); - } - } - void set_pattern(const std::string &pattern) { std::lock_guard lock(mutex_); - formatter_ = std::make_shared(pattern); + formatter_pattern_ = pattern; for (auto &l : loggers_) { - l.second->set_formatter(formatter_); + l.second->set_pattern(pattern); } } @@ -184,7 +173,7 @@ private: Mutex mutex_; Mutex tp_mutex_; std::unordered_map> loggers_; - formatter_ptr formatter_; + std::string formatter_pattern_ = "%+"; level::level_enum level_ = level::info; level::level_enum flush_level_ = level::off; log_err_handler err_handler_; diff --git a/include/spdlog/formatter.h b/include/spdlog/formatter.h index 8641491d..af54e88c 100644 --- a/include/spdlog/formatter.h +++ b/include/spdlog/formatter.h @@ -5,6 +5,7 @@ #pragma once +#include "fmt/fmt.h" #include "spdlog/details/log_msg.h" #include @@ -12,31 +13,32 @@ #include namespace spdlog { -namespace details { -class flag_formatter; -} class formatter { public: virtual ~formatter() = default; - virtual void format(details::log_msg &msg) = 0; + virtual void format(const details::log_msg &msg, fmt::memory_buffer &dest) = 0; }; +namespace details { +class flag_formatter; +} + class pattern_formatter SPDLOG_FINAL : public formatter { public: explicit pattern_formatter(const std::string &pattern, pattern_time_type pattern_time = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol); - pattern_formatter(const pattern_formatter &) = delete; - pattern_formatter &operator=(const pattern_formatter &) = delete; - void format(details::log_msg &msg) override; + pattern_formatter(const pattern_formatter &) = default; + pattern_formatter &operator=(const pattern_formatter &) = default; + void format(const details::log_msg &msg, fmt::memory_buffer &dest) override; private: const std::string eol_; const pattern_time_type pattern_time_; std::vector> formatters_; - std::tm get_time(details::log_msg &msg); + std::tm get_time(const details::log_msg &msg); void handle_flag(char flag); void compile_pattern(const std::string &pattern); }; diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index 1746c542..4fd88ff0 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -8,9 +8,12 @@ // Thread safe logger (except for set_pattern(..), set_formatter(..) and set_error_handler()) // Has name, log level, vector of std::shared sink pointers and formatter // Upon each log write the logger: -// 1. Checks if its log level is enough to log the message -// 2. Format the message using the formatter function -// 3. Pass the formatted message to its sinks to performa the actual logging +// 1. Checks if its log level is enough to log the message and if yes: +// 2. Call the underlying sinks to do the job. +// 3. Each sink use its own private copy of a formatter to format the message and send to its destination. +// +// The use of private formatter per sink provides the opportunity to cache some formatted data, +// and support customize format per each sink. #include "spdlog/common.h" #include "spdlog/formatter.h" @@ -111,8 +114,15 @@ public: void set_level(level::level_enum log_level); level::level_enum level() const; const std::string &name() const; + + // create a pattern formatter all the sinks in this logger. + // each sink gets itw own private copy of a formatter object. void set_pattern(const std::string &pattern, pattern_time_type pattern_time = pattern_time_type::local); - void set_formatter(formatter_ptr msg_formatter); + + // create a FormatterT formatter all the sinks in this logger. + // each sink gets itw own private copy of a formatter object. + template + void set_formatter(const Args &... args); void flush(); void flush_on(level::level_enum log_level); @@ -137,7 +147,6 @@ protected: const std::string name_; std::vector sinks_; - formatter_ptr formatter_; spdlog::level_t level_; spdlog::level_t flush_level_; log_err_handler err_handler_; diff --git a/include/spdlog/sinks/android_sink.h b/include/spdlog/sinks/android_sink.h index 98c0edd1..9b1259e1 100644 --- a/include/spdlog/sinks/android_sink.h +++ b/include/spdlog/sinks/android_sink.h @@ -39,7 +39,17 @@ public: void log(const details::log_msg &msg) override { const android_LogPriority priority = convert_to_android(msg.level); - const char *msg_output = (use_raw_msg_ ? msg.raw.c_str() : msg.formatted.c_str()); + fmt::memory_buffer formatted; + if (use_raw_msg_) + { + formatted.append(msg.raw.data(), msg.raw.data() + msg.raw.size()); + } + else + { + formatter_->format(msg, formatted); + } + formatted.push_back('\0'); + const char *msg_output = formatted.data(); // See system/core/liblog/logger_write.c for explanation of return value int ret = __android_log_write(priority, tag_.c_str(), msg_output); diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index 370d4339..d817dffb 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -88,20 +88,23 @@ public: // Wrap the originally formatted message in color codes. // If color is not supported in the terminal, log as is instead. std::lock_guard lock(mutex_); + + fmt::memory_buffer formatted; + formatter_->format(msg, formatted); if (should_do_colors_ && msg.color_range_end > msg.color_range_start) { // before color range - print_range_(msg, 0, msg.color_range_start); + print_range_(formatted, 0, msg.color_range_start); // in color range print_ccode_(colors_[msg.level]); - print_range_(msg, msg.color_range_start, msg.color_range_end); + print_range_(formatted, msg.color_range_start, msg.color_range_end); print_ccode_(reset); // after color range - print_range_(msg, msg.color_range_end, msg.formatted.size()); + print_range_(formatted, msg.color_range_end, formatted.size()); } else // no color { - print_range_(msg, 0, msg.formatted.size()); + print_range_(formatted, 0, formatted.size()); } fflush(target_file_); } @@ -117,9 +120,9 @@ private: { fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_); } - void print_range_(const details::log_msg &msg, size_t start, size_t end) + void print_range_(const fmt::memory_buffer &formatted, size_t start, size_t end) { - fwrite(msg.formatted.data() + start, sizeof(char), end - start, target_file_); + fwrite(formatted.data() + start, sizeof(char), end - start, target_file_); } FILE *target_file_; diff --git a/include/spdlog/sinks/base_sink.h b/include/spdlog/sinks/base_sink.h index 4d1874ad..871f2b81 100644 --- a/include/spdlog/sinks/base_sink.h +++ b/include/spdlog/sinks/base_sink.h @@ -21,7 +21,20 @@ template class base_sink : public sink { public: - base_sink() = default; + base_sink() + : sink() + { + } + + base_sink(const std::string &formatter_pattern) + : sink(formatter_pattern) + { + } + + base_sink(std::unique_ptr sink_formatter) + : sink(std::move(sink_formatter)) + { + } base_sink(const base_sink &) = delete; base_sink &operator=(const base_sink &) = delete; @@ -29,7 +42,9 @@ public: void log(const details::log_msg &msg) SPDLOG_FINAL override { std::lock_guard lock(mutex_); - sink_it_(msg); + fmt::memory_buffer formatted; + formatter_->format(msg, formatted); + sink_it_(msg, formatted); } void flush() SPDLOG_FINAL override @@ -39,7 +54,7 @@ public: } protected: - virtual void sink_it_(const details::log_msg &msg) = 0; + virtual void sink_it_(const details::log_msg &msg, const fmt::memory_buffer &formatted) = 0; virtual void flush_() = 0; Mutex mutex_; }; diff --git a/include/spdlog/sinks/daily_file_sink.h b/include/spdlog/sinks/daily_file_sink.h index f41f1218..c4dfe487 100644 --- a/include/spdlog/sinks/daily_file_sink.h +++ b/include/spdlog/sinks/daily_file_sink.h @@ -76,14 +76,14 @@ public: } protected: - void sink_it_(const details::log_msg &msg) override + void sink_it_(const details::log_msg &, const fmt::memory_buffer &formatted) override { if (std::chrono::system_clock::now() >= rotation_tp_) { file_helper_.open(FileNameCalc::calc_filename(base_filename_)); rotation_tp_ = next_rotation_tp_(); } - file_helper_.write(msg); + file_helper_.write(formatted); } void flush_() override diff --git a/include/spdlog/sinks/null_sink.h b/include/spdlog/sinks/null_sink.h index 98206fda..24a3b3ea 100644 --- a/include/spdlog/sinks/null_sink.h +++ b/include/spdlog/sinks/null_sink.h @@ -17,12 +17,12 @@ template class null_sink : public base_sink { protected: - void sink_it_(const details::log_msg &) override {} + void sink_it_(const details::log_msg &, const fmt::memory_buffer &) override {} void flush_() override {} }; -using null_sink_mt = null_sink; +using null_sink_mt = null_sink; using null_sink_st = null_sink; } // namespace sinks diff --git a/include/spdlog/sinks/ostream_sink.h b/include/spdlog/sinks/ostream_sink.h index a3ecc7f7..c18bb8f6 100644 --- a/include/spdlog/sinks/ostream_sink.h +++ b/include/spdlog/sinks/ostream_sink.h @@ -26,9 +26,9 @@ public: ostream_sink &operator=(const ostream_sink &) = delete; protected: - void sink_it_(const details::log_msg &msg) override + void sink_it_(const details::log_msg &msg, const fmt::memory_buffer &formatted) override { - ostream_.write(msg.formatted.data(), msg.formatted.size()); + ostream_.write(formatted.data(), formatted.size()); if (force_flush_) ostream_.flush(); } diff --git a/include/spdlog/sinks/rotating_file_sink.h b/include/spdlog/sinks/rotating_file_sink.h index a88b6b2e..dbbc75cd 100644 --- a/include/spdlog/sinks/rotating_file_sink.h +++ b/include/spdlog/sinks/rotating_file_sink.h @@ -55,15 +55,15 @@ public: } protected: - void sink_it_(const details::log_msg &msg) override + void sink_it_(const details::log_msg &, const fmt::memory_buffer &formatted) override { - current_size_ += msg.formatted.size(); + current_size_ += formatted.size(); if (current_size_ > max_size_) { rotate_(); - current_size_ = msg.formatted.size(); + current_size_ = formatted.size(); } - file_helper_.write(msg); + file_helper_.write(formatted); } void flush_() override diff --git a/include/spdlog/sinks/simple_file_sink.h b/include/spdlog/sinks/simple_file_sink.h index 2cf1dd51..5af863dc 100644 --- a/include/spdlog/sinks/simple_file_sink.h +++ b/include/spdlog/sinks/simple_file_sink.h @@ -33,9 +33,9 @@ public: } protected: - void sink_it_(const details::log_msg &msg) override + void sink_it_(const details::log_msg &, const fmt::memory_buffer &formatted) override { - file_helper_.write(msg); + file_helper_.write(formatted); if (force_flush_) { file_helper_.flush(); diff --git a/include/spdlog/sinks/sink.h b/include/spdlog/sinks/sink.h index 915c7e31..e6fb533e 100644 --- a/include/spdlog/sinks/sink.h +++ b/include/spdlog/sinks/sink.h @@ -6,39 +6,62 @@ #pragma once #include "spdlog/details/log_msg.h" +#include "spdlog/formatter.h" namespace spdlog { namespace sinks { class sink { public: + // default sink ctor with default pattern formatter + sink() + : formatter_(std::unique_ptr(new pattern_formatter("%+"))) + { + } + + explicit sink(const std::string &formatter_pattern) + : formatter_(std::unique_ptr(new pattern_formatter(formatter_pattern))) + { + } + + // sink with custom formatter + explicit sink(std::unique_ptr sink_formatter) + : formatter_(std::move(sink_formatter)) + { + } + virtual ~sink() = default; virtual void log(const details::log_msg &msg) = 0; virtual void flush() = 0; - bool should_log(level::level_enum msg_level) const; - void set_level(level::level_enum log_level); - level::level_enum level() const; + bool should_log(level::level_enum msg_level) const + { + return msg_level >= level_.load(std::memory_order_relaxed); + } + void set_level(level::level_enum log_level) + { + level_.store(log_level); + } + level::level_enum level() const + { + return static_cast(level_.load(std::memory_order_relaxed)); + } -private: + void set_formatter(std::unique_ptr sink_formatter) + { + formatter_ = std::move(sink_formatter); + } + + spdlog::formatter *formatter() + { + return formatter_.get(); + } + +protected: level_t level_{level::trace}; + std::unique_ptr formatter_; }; -inline bool sink::should_log(level::level_enum msg_level) const -{ - return msg_level >= level_.load(std::memory_order_relaxed); -} - -inline void sink::set_level(level::level_enum log_level) -{ - level_.store(log_level); -} - -inline level::level_enum sink::level() const -{ - return static_cast(level_.load(std::memory_order_relaxed)); -} - } // namespace sinks } // namespace spdlog diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 9d0b6c4b..1eb76fea 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -5,6 +5,7 @@ #pragma once +#include "../fmt/fmt.h" #include "spdlog/common.h" #include "spdlog/details/null_mutex.h" #include "spdlog/details/traits.h" @@ -63,22 +64,23 @@ public: void log(const details::log_msg &msg) SPDLOG_FINAL override { std::lock_guard lock(mutex_); - + fmt::memory_buffer formatted; + formatter_->format(msg, formatted); if (msg.color_range_end > msg.color_range_start) { // before color range - print_range_(msg, 0, msg.color_range_start); + print_range_(formatted, 0, msg.color_range_start); // in color range auto orig_attribs = set_console_attribs(colors_[msg.level]); - print_range_(msg, msg.color_range_start, msg.color_range_end); + print_range_(formatted, msg.color_range_start, msg.color_range_end); ::SetConsoleTextAttribute(out_handle_, orig_attribs); // reset to orig colors // after color range - print_range_(msg, msg.color_range_end, msg.formatted.size()); + print_range_(formatted, msg.color_range_end, formatted.size()); } else // print without colors if color range is invalid { - print_range_(msg, 0, msg.formatted.size()); + print_range_(formatted, 0, formatted.size()); } } @@ -103,10 +105,10 @@ private: } // print a range of formatted message to console - void print_range_(const details::log_msg &msg, size_t start, size_t end) + void print_range_(const fmt::memory_buffer formatted, size_t start, size_t end) { auto size = static_cast(end - start); - ::WriteConsoleA(out_handle_, msg.formatted.data() + start, size, nullptr, nullptr); + ::WriteConsoleA(out_handle_, formatted.data() + start, size, nullptr, nullptr); } HANDLE out_handle_; diff --git a/include/spdlog/spdlog.h b/include/spdlog/spdlog.h index 14151527..b51578fa 100644 --- a/include/spdlog/spdlog.h +++ b/include/spdlog/spdlog.h @@ -62,11 +62,6 @@ inline void set_pattern(const std::string &format_string) details::registry::instance().set_pattern(format_string); } -inline void set_formatter(formatter_ptr f) -{ - details::registry::instance().set_formatter(std::move(f)); -} - // // Set global logging level // diff --git a/tests/file_helper.cpp b/tests/file_helper.cpp index 9ef8f26a..bfe7eb9d 100644 --- a/tests/file_helper.cpp +++ b/tests/file_helper.cpp @@ -11,9 +11,9 @@ static const std::string target_filename = "logs/file_helper_test.txt"; static void write_with_helper(file_helper &helper, size_t howmany) { log_msg msg; - - fmt::format_to(msg.formatted, "{}", std::string(howmany, '1')); - helper.write(msg); + fmt::memory_buffer formatted; + fmt::format_to(formatted, "{}", std::string(howmany, '1')); + helper.write(formatted); helper.flush(); } diff --git a/tests/test_pattern_formatter.cpp b/tests/test_pattern_formatter.cpp index b9a17aea..07e103d3 100644 --- a/tests/test_pattern_formatter.cpp +++ b/tests/test_pattern_formatter.cpp @@ -1,16 +1,16 @@ #include "includes.h" // log to str and return it -static std::string log_to_str(const std::string &msg, const std::shared_ptr &formatter = nullptr) +template + +static std::string log_to_str(const std::string &msg, const Args &... args) { std::ostringstream oss; auto oss_sink = std::make_shared(oss); spdlog::logger oss_logger("pattern_tester", oss_sink); oss_logger.set_level(spdlog::level::info); - if (formatter) - { - oss_logger.set_formatter(formatter); - } + oss_logger.set_formatter(args...); + oss_logger.info(msg); return oss.str(); } @@ -19,49 +19,44 @@ TEST_CASE("custom eol", "[pattern_formatter]") { std::string msg = "Hello custom eol test"; std::string eol = ";)"; - auto formatter = std::make_shared("%v", spdlog::pattern_time_type::local, ";)"); + // auto formatter = std::make_shared("%v", spdlog::pattern_time_type::local, ";)"); + std::unique_ptr(new spdlog::pattern_formatter("%v", spdlog::pattern_time_type::local, ";)")); - REQUIRE(log_to_str(msg, formatter) == msg + eol); + REQUIRE(log_to_str(msg, "%v", spdlog::pattern_time_type::local, ";)") == msg + eol); } TEST_CASE("empty format", "[pattern_formatter]") { - auto formatter = std::make_shared("", spdlog::pattern_time_type::local, ""); - REQUIRE(log_to_str("Some message", formatter) == ""); + REQUIRE(log_to_str("Some message", "", spdlog::pattern_time_type::local, "") == ""); } TEST_CASE("empty format2", "[pattern_formatter]") { - auto formatter = std::make_shared("", spdlog::pattern_time_type::local, "\n"); - REQUIRE(log_to_str("Some message", formatter) == "\n"); + REQUIRE(log_to_str("Some message", "", spdlog::pattern_time_type::local, "\n") == "\n"); } TEST_CASE("level", "[pattern_formatter]") { - auto formatter = std::make_shared("[%l] %v", spdlog::pattern_time_type::local, "\n"); - REQUIRE(log_to_str("Some message", formatter) == "[info] Some message\n"); + REQUIRE(log_to_str("Some message", "[%l] %v", spdlog::pattern_time_type::local, "\n") == "[info] Some message\n"); } TEST_CASE("short level", "[pattern_formatter]") { - auto formatter = std::make_shared("[%L] %v", spdlog::pattern_time_type::local, "\n"); - REQUIRE(log_to_str("Some message", formatter) == "[I] Some message\n"); + REQUIRE(log_to_str("Some message", "[%L] %v", spdlog::pattern_time_type::local, "\n") == "[I] Some message\n"); } TEST_CASE("name", "[pattern_formatter]") { - auto formatter = std::make_shared("[%n] %v", spdlog::pattern_time_type::local, "\n"); - REQUIRE(log_to_str("Some message", formatter) == "[pattern_tester] Some message\n"); + REQUIRE(log_to_str("Some message", "[%n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n"); } TEST_CASE("date MM/DD/YY ", "[pattern_formatter]") { - auto formatter = std::make_shared("%D %v", spdlog::pattern_time_type::local, "\n"); auto now_tm = spdlog::details::os::localtime(); std::stringstream oss; oss << std::setfill('0') << std::setw(2) << now_tm.tm_mon + 1 << "/" << std::setw(2) << now_tm.tm_mday << "/" << std::setw(2) << (now_tm.tm_year + 1900) % 1000 << " Some message\n"; - REQUIRE(log_to_str("Some message", formatter) == oss.str()); + REQUIRE(log_to_str("Some message", "%D %v", spdlog::pattern_time_type::local, "\n") == oss.str()); } TEST_CASE("color range test1", "[pattern_formatter]") @@ -69,27 +64,30 @@ TEST_CASE("color range test1", "[pattern_formatter]") auto formatter = std::make_shared("%^%v%$", spdlog::pattern_time_type::local, "\n"); spdlog::details::log_msg msg; fmt::format_to(msg.raw, "Hello"); - formatter->format(msg); + fmt::memory_buffer formatted; + formatter->format(msg, formatted); REQUIRE(msg.color_range_start == 0); REQUIRE(msg.color_range_end == 5); - REQUIRE(log_to_str("hello", formatter) == "hello\n"); + REQUIRE(log_to_str("hello", "%^%v%$", spdlog::pattern_time_type::local, "\n") == "hello\n"); } TEST_CASE("color range test2", "[pattern_formatter]") { auto formatter = std::make_shared("%^%$", spdlog::pattern_time_type::local, "\n"); spdlog::details::log_msg msg; - formatter->format(msg); + fmt::memory_buffer formatted; + formatter->format(msg, formatted); REQUIRE(msg.color_range_start == 0); REQUIRE(msg.color_range_end == 0); - REQUIRE(log_to_str("", formatter) == "\n"); + REQUIRE(log_to_str("", "%^%$", spdlog::pattern_time_type::local, "\n") == "\n"); } TEST_CASE("color range test3", "[pattern_formatter]") { auto formatter = std::make_shared("%^***%$"); spdlog::details::log_msg msg; - formatter->format(msg); + fmt::memory_buffer formatted; + formatter->format(msg, formatted); REQUIRE(msg.color_range_start == 0); REQUIRE(msg.color_range_end == 3); } @@ -99,17 +97,19 @@ TEST_CASE("color range test4", "[pattern_formatter]") auto formatter = std::make_shared("XX%^YYY%$", spdlog::pattern_time_type::local, "\n"); spdlog::details::log_msg msg; fmt::format_to(msg.raw, "ignored"); - formatter->format(msg); + fmt::memory_buffer formatted; + formatter->format(msg, formatted); REQUIRE(msg.color_range_start == 2); REQUIRE(msg.color_range_end == 5); - REQUIRE(log_to_str("ignored", formatter) == "XXYYY\n"); + REQUIRE(log_to_str("ignored", "XX%^YYY%$", spdlog::pattern_time_type::local, "\n") == "XXYYY\n"); } TEST_CASE("color range test5", "[pattern_formatter]") { auto formatter = std::make_shared("**%^"); spdlog::details::log_msg msg; - formatter->format(msg); + fmt::memory_buffer formatted; + formatter->format(msg, formatted); REQUIRE(msg.color_range_start == 2); REQUIRE(msg.color_range_end == 0); } @@ -118,7 +118,8 @@ TEST_CASE("color range test6", "[pattern_formatter]") { auto formatter = std::make_shared("**%$"); spdlog::details::log_msg msg; - formatter->format(msg); + fmt::memory_buffer formatted; + formatter->format(msg, formatted); REQUIRE(msg.color_range_start == 0); REQUIRE(msg.color_range_end == 2); } diff --git a/tests/test_sink.h b/tests/test_sink.h index c4a09f0d..3d8ee205 100644 --- a/tests/test_sink.h +++ b/tests/test_sink.h @@ -35,7 +35,7 @@ public: } protected: - void sink_it_(const details::log_msg &) override + void sink_it_(const details::log_msg &, const fmt::memory_buffer &) override { msg_counter_++; std::this_thread::sleep_for(delay_);