diff --git a/example/example.cpp b/example/example.cpp index b3d6c439..63e842e5 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -55,6 +55,10 @@ int main(int, char*[]) spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); file_logger->info("This is another message with custom format"); + auto formatter = std::make_shared("%k: %v"); + formatter->add_customer_formatter('k', [](spd::details::log_msg &msg){ msg.formatted << "Channel 1"; }); + file_logger->set_formatter(formatter); + file_logger->info("This is another message with another custom format using a custom flag"); // Compile time debug or trace macros. // Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON diff --git a/include/spdlog/details/pattern_formatter_impl.h b/include/spdlog/details/pattern_formatter_impl.h index 3965b831..092a5347 100644 --- a/include/spdlog/details/pattern_formatter_impl.h +++ b/include/spdlog/details/pattern_formatter_impl.h @@ -377,6 +377,18 @@ private: char _ch; }; +class flag_custom_formatter : public flag_formatter +{ +private: + custom_flag_formatter _formatter; +public: + explicit flag_custom_formatter(custom_flag_formatter formatter) : _formatter(formatter) { }; + void format(details::log_msg& msg, const std::tm&) override + { + _formatter(msg); + } +}; + //aggregate user chars to display as is class aggregate_formatter :public flag_formatter @@ -448,7 +460,7 @@ class full_formatter :public flag_formatter /////////////////////////////////////////////////////////////////////////////// // pattern_formatter inline impl /////////////////////////////////////////////////////////////////////////////// -inline spdlog::pattern_formatter::pattern_formatter(const std::string& pattern) +inline spdlog::pattern_formatter::pattern_formatter(const std::string& pattern) : _pattern(pattern) { compile_pattern(pattern); } @@ -457,6 +469,7 @@ inline void spdlog::pattern_formatter::compile_pattern(const std::string& patter { auto end = pattern.end(); std::unique_ptr user_chars; + _formatters.clear(); for (auto it = pattern.begin(); it != end; ++it) { if (*it == '%') @@ -480,8 +493,8 @@ inline void spdlog::pattern_formatter::compile_pattern(const std::string& patter { _formatters.push_back(std::move(user_chars)); } - } + inline void spdlog::pattern_formatter::handle_flag(char flag) { switch (flag) @@ -602,12 +615,61 @@ inline void spdlog::pattern_formatter::handle_flag(char flag) break; default: //Unkown flag appears as is - _formatters.push_back(std::unique_ptr(new details::ch_formatter('%'))); - _formatters.push_back(std::unique_ptr(new details::ch_formatter(flag))); + auto it = _custom_formatters.find(flag); + if(it == _custom_formatters.end()) + { + _formatters.push_back(std::unique_ptr(new details::ch_formatter('%'))); + _formatters.push_back(std::unique_ptr(new details::ch_formatter(flag))); + } + else + { + _formatters.push_back(std::unique_ptr(new details::flag_custom_formatter(it->second))); + } break; } } +inline void spdlog::pattern_formatter::add_customer_formatter(char flag, custom_flag_formatter formatter) +{ + switch (flag) + {//these flags are already in use. + case('a') : + case('A') : + case('b') : + case('B') : + case('c') : + case('C') : + case('d') : + case('D') : + case('e') : + case('f') : + case('F') : + case('h') : + case('H') : + case('I') : + case('n'): + case('l'): + case('L'): + case('m') : + case('M') : + case('p') : + case('r') : + case('R') : + case('S') : + case('t') : + case('T') : + case('v') : + case('x') : + case('X') : + case('Y') : + case('z') : + case ('+'): + throw spdlog::spdlog_ex(std::string("Can't add custom pattern formatter with non unique signature")); + default: //Unkown flag appears as is + _custom_formatters.emplace(flag, formatter); + compile_pattern(_pattern); + } +} inline void spdlog::pattern_formatter::format(details::log_msg& msg) { diff --git a/include/spdlog/formatter.h b/include/spdlog/formatter.h index 0ffcec03..94e506ff 100644 --- a/include/spdlog/formatter.h +++ b/include/spdlog/formatter.h @@ -10,6 +10,8 @@ #include #include #include +#include +#include namespace spdlog { @@ -25,16 +27,20 @@ public: virtual void format(details::log_msg& msg) = 0; }; +typedef std::function custom_flag_formatter; + class pattern_formatter : public formatter { - public: explicit pattern_formatter(const std::string& pattern); pattern_formatter(const pattern_formatter&) = delete; pattern_formatter& operator=(const pattern_formatter&) = delete; void format(details::log_msg& msg) override; + void add_customer_formatter(char sig, custom_flag_formatter formatter); + private: const std::string _pattern; + std::unordered_map _custom_formatters; std::vector> _formatters; void handle_flag(char flag); void compile_pattern(const std::string& pattern);