diff --git a/include/spdlog/details/log_msg.h b/include/spdlog/details/log_msg.h index a9fe9201..850b9a81 100644 --- a/include/spdlog/details/log_msg.h +++ b/include/spdlog/details/log_msg.h @@ -11,6 +11,7 @@ #include #include +#include namespace spdlog { @@ -19,10 +20,11 @@ namespace details struct log_msg { log_msg() = default; - log_msg(const std::string *loggers_name, level::level_enum lvl) : + log_msg(const std::string *loggers_name, level::level_enum lvl, std::unordered_map* flags) : logger_name(loggers_name), level(lvl), - msg_id(0) + msg_id(0), + custom_flags(flags) { #ifndef SPDLOG_NO_DATETIME time = os::now(); @@ -45,6 +47,7 @@ struct log_msg fmt::MemoryWriter raw; fmt::MemoryWriter formatted; size_t msg_id; + std::unordered_map* custom_flags; }; } } diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index 88044747..bfb39333 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -64,7 +64,7 @@ inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Ar try { - details::log_msg log_msg(&_name, lvl); + details::log_msg log_msg(&_name, lvl, &_custom_flags); #if defined(SPDLOG_FMT_PRINTF) fmt::printf(log_msg.raw, fmt, args...); @@ -90,7 +90,7 @@ inline void spdlog::logger::log(level::level_enum lvl, const char* msg) if (!should_log(lvl)) return; try { - details::log_msg log_msg(&_name, lvl); + details::log_msg log_msg(&_name, lvl, &_custom_flags); log_msg.raw << msg; _sink_it(log_msg); } @@ -111,7 +111,7 @@ inline void spdlog::logger::log(level::level_enum lvl, const T& msg) if (!should_log(lvl)) return; try { - details::log_msg log_msg(&_name, lvl); + details::log_msg log_msg(&_name, lvl,&_custom_flags); log_msg.raw << msg; _sink_it(log_msg); } @@ -279,6 +279,25 @@ inline void spdlog::logger::set_level(spdlog::level::level_enum log_level) _level.store(log_level); } +inline void spdlog::logger::set_custom_flag(char flag,const std::string& value) +{ + _custom_flags[flag] = value; +} + +inline const std::string& spdlog::logger::value_custom_flag(char flag) +{ + auto end = _custom_flags.end(); + auto it = _custom_flags.find(flag); + if (it != end) + { + return it->second; + } + else + { + return ""; + } +} + inline void spdlog::logger::set_error_handler(spdlog::log_err_handler err_handler) { _err_handler = err_handler; diff --git a/include/spdlog/details/pattern_formatter_impl.h b/include/spdlog/details/pattern_formatter_impl.h index a73f5dea..2dd67863 100644 --- a/include/spdlog/details/pattern_formatter_impl.h +++ b/include/spdlog/details/pattern_formatter_impl.h @@ -414,6 +414,27 @@ private: char _ch; }; +class custom_formatter SPDLOG_FINAL:public flag_formatter +{ +public: + explicit custom_formatter(char flag) : _flag(_flag) + {} + void format(details::log_msg& msg, const std::tm&) override + { + auto end = msg.custom_flags->end(); + auto it = msg.custom_flags->find(_flag); + if (it != end) + { + msg.formatted << it->second; + } + else { + msg.formatted << _flag; + } + } +private: + char _flag; +}; + //aggregate user chars to display as is class aggregate_formatter SPDLOG_FINAL:public flag_formatter @@ -655,8 +676,7 @@ inline void spdlog::pattern_formatter::handle_flag(char flag) break; default: //Unknown 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))); + _formatters.push_back(std::unique_ptr(new details::custom_formatter(flag))); break; } } diff --git a/include/spdlog/details/registry.h b/include/spdlog/details/registry.h index b68b9f5a..9ded577a 100644 --- a/include/spdlog/details/registry.h +++ b/include/spdlog/details/registry.h @@ -155,6 +155,28 @@ public: _level = log_level; } + void set_custom_flag(char flag, const std::string& value) + { + std::lock_guard lock(_mutex); + for (auto& l : _loggers) + l.second->set_custom_flag(flag, value); + _custom_flags[flag] = value; + } + + const std::string& value_custom_flag(char flag) + { + auto end = _custom_flags.end(); + auto it = _custom_flags.find(flag); + if (it != end) + { + return it->second; + } + else + { + return std::move(std::string("")); + } + } + void flush_on(level::level_enum log_level) { std::lock_guard lock(_mutex); @@ -215,6 +237,7 @@ private: std::function _worker_warmup_cb = nullptr; std::chrono::milliseconds _flush_interval_ms; std::function _worker_teardown_cb = nullptr; + std::unordered_map _custom_flags; }; #ifdef SPDLOG_NO_REGISTRY_MUTEX typedef registry_t registry; diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index 25c7b7e9..bcbf3014 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -236,6 +236,16 @@ inline void spdlog::set_level(level::level_enum log_level) return details::registry::instance().set_level(log_level); } +inline void spdlog::set_custom_flag(char flag, const std::string& value) +{ + return details::registry::instance().set_custom_flag(flag, value); +} + +inline const std::string& spdlog::value_custom_flag(char flag) +{ + return details::registry::instance().value_custom_flag(flag); +} + inline void spdlog::flush_on(level::level_enum log_level) { return details::registry::instance().flush_on(log_level); diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index 742f667f..6f0c50ad 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace spdlog { @@ -66,6 +67,8 @@ public: bool should_log(level::level_enum) const; void set_level(level::level_enum); + void set_custom_flag(char flag, const std::string& value); + const std::string& value_custom_flag(char flag); level::level_enum level() const; const std::string& name() const; void set_pattern(const std::string&, pattern_time_type = pattern_time_type::local); @@ -104,6 +107,7 @@ protected: log_err_handler _err_handler; std::atomic _last_err_time; std::atomic _msg_counter; + std::unordered_map _custom_flags; }; } diff --git a/include/spdlog/spdlog.h b/include/spdlog/spdlog.h index ff79ef6e..7cf14f2a 100644 --- a/include/spdlog/spdlog.h +++ b/include/spdlog/spdlog.h @@ -50,6 +50,15 @@ void flush_on(level::level_enum log_level); // void set_error_handler(log_err_handler); +// +// Set custom flag +// +void set_custom_flag(char flag, const std::string& value); + +// +// value custom flag +// +const std::string& value_custom_flag(char flag); // // Turn on async mode (off by default) and set the queue size for each async_logger. // effective only for loggers created after this call.