support set_formatter in spdlog.h

This commit is contained in:
gabime 2018-07-22 21:52:46 +03:00
parent 7184c42376
commit 693103af9c
7 changed files with 63 additions and 53 deletions

View File

@ -37,19 +37,18 @@ inline spdlog::logger::logger(std::string logger_name, spdlog::sink_ptr single_s
inline spdlog::logger::~logger() = default; inline spdlog::logger::~logger() = default;
template<typename FormatterT, typename... Args>
inline void spdlog::logger::set_formatter(const Args &... args) inline void spdlog::logger::set_formatter(std::unique_ptr<spdlog::formatter> f)
{ {
for (auto &sink : sinks_) for (auto &sink : sinks_)
{ {
std::unique_ptr<FormatterT> formatter(new FormatterT(args...)); sink->set_formatter(f->clone());
sink->set_formatter(std::move(formatter)); }
}
} }
inline void spdlog::logger::set_pattern(std::string pattern, pattern_time_type time_type) inline void spdlog::logger::set_pattern(std::string pattern, pattern_time_type time_type)
{ {
set_formatter<spdlog::pattern_formatter>(std::move(pattern), time_type); set_formatter(std::unique_ptr<spdlog::formatter>(new pattern_formatter(std::move(pattern), time_type)));
} }
template<typename... Args> template<typename... Args>

View File

@ -541,18 +541,25 @@ private:
class pattern_formatter SPDLOG_FINAL : public formatter class pattern_formatter SPDLOG_FINAL : public formatter
{ {
public: public:
explicit pattern_formatter( explicit pattern_formatter(
std::string pattern, pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol) std::string pattern, pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol)
: eol_(std::move(eol)) : pattern_(std::move(pattern))
, pattern_time_type_(time_type) , eol_(std::move(eol))
, last_log_secs_(0) , pattern_time_type_(time_type)
{ , last_log_secs_(0)
std::memset(&cached_tm_, 0, sizeof(cached_tm_)); {
compile_pattern_(std::move(pattern)); std::memset(&cached_tm_, 0, sizeof(cached_tm_));
} compile_pattern_(pattern_);
}
pattern_formatter(const pattern_formatter &other) = delete;
pattern_formatter &operator=(const pattern_formatter &other) = delete;
virtual std::unique_ptr<formatter> clone() const override
{
return std::unique_ptr<formatter>(new pattern_formatter(pattern_, pattern_time_type_, eol_));
}
pattern_formatter(const pattern_formatter &) = delete;
pattern_formatter &operator=(const pattern_formatter &) = delete;
void format(const details::log_msg &msg, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, fmt::memory_buffer &dest) override
{ {
#ifndef SPDLOG_NO_DATETIME #ifndef SPDLOG_NO_DATETIME
@ -572,7 +579,8 @@ public:
} }
private: private:
const std::string eol_; std::string pattern_;
std::string eol_;
pattern_time_type pattern_time_type_; pattern_time_type pattern_time_type_;
std::tm cached_tm_; std::tm cached_tm_;
std::chrono::seconds last_log_secs_; std::chrono::seconds last_log_secs_;
@ -734,9 +742,10 @@ private:
} }
void compile_pattern_(const std::string &pattern) void compile_pattern_(const std::string &pattern)
{ {
auto end = pattern.end(); auto end = pattern.end();
std::unique_ptr<details::aggregate_formatter> user_chars; std::unique_ptr<details::aggregate_formatter> user_chars;
formatters_.clear();
for (auto it = pattern.begin(); it != end; ++it) for (auto it = pattern.begin(); it != end; ++it)
{ {
if (*it == '%') if (*it == '%')

View File

@ -48,7 +48,7 @@ public:
throw_if_exists_(logger_name); throw_if_exists_(logger_name);
// set the global formatter pattern // set the global formatter pattern
new_logger->set_formatter<pattern_formatter>(formatter_pattern_, pattern_time_type_); new_logger->set_formatter(formatter_->clone());
if (err_handler_) if (err_handler_)
{ {
@ -81,16 +81,17 @@ public:
return tp_; return tp_;
} }
void set_pattern(const std::string &pattern, pattern_time_type time_type)
{ // Set global formatter. Each sink in each logger will get a clone of this object
std::lock_guard<Mutex> lock(loggers_mutex_); void set_formatter(std::unique_ptr<formatter> formatter)
formatter_pattern_ = pattern; {
pattern_time_type_ = time_type; std::lock_guard<Mutex> lock(loggers_mutex_);
for (auto &l : loggers_) formatter_ = std::move(formatter);
{ for (auto &l : loggers_)
l.second->set_pattern(pattern, time_type); {
} l.second->set_formatter(formatter_->clone());
} }
}
void set_level(level::level_enum log_level) void set_level(level::level_enum log_level)
{ {
@ -195,8 +196,7 @@ private:
Mutex loggers_mutex_; Mutex loggers_mutex_;
std::recursive_mutex tp_mutex_; std::recursive_mutex tp_mutex_;
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_; std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
std::string formatter_pattern_ = "%+"; std::unique_ptr<formatter> formatter_{ new pattern_formatter("%+") };
pattern_time_type pattern_time_type_ = pattern_time_type::local;
level::level_enum level_ = level::info; level::level_enum level_ = level::info;
level::level_enum flush_level_ = level::off; level::level_enum flush_level_ = level::off;
log_err_handler err_handler_; log_err_handler err_handler_;

View File

@ -15,5 +15,6 @@ class formatter
public: public:
virtual ~formatter() = default; virtual ~formatter() = default;
virtual void format(const details::log_msg &msg, fmt::memory_buffer &dest) = 0; virtual void format(const details::log_msg &msg, fmt::memory_buffer &dest) = 0;
virtual std::unique_ptr<formatter> clone() const = 0;
}; };
} // namespace spdlog } // namespace spdlog

View File

@ -114,24 +114,19 @@ public:
void set_level(level::level_enum log_level); void set_level(level::level_enum log_level);
level::level_enum level() const; level::level_enum level() const;
const std::string &name() const; const std::string &name() const;
// create a pattern formatter all the sinks in this logger. // set formatting for the sinks in this logger.
// each sink gets itw own private copy of a formatter object. // each sink will get a seperate instance of the formatter object.
void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local); void set_formatter(std::unique_ptr<formatter> formatter);
void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
// create a FormatterT formatter for each sink in this logger.
// each sink gets its own private copy of a formatter object.
template<typename FormatterT, typename... Args>
void set_formatter(const Args &... args);
void flush(); void flush();
void flush_on(level::level_enum log_level); void flush_on(level::level_enum log_level);
const std::vector<sink_ptr> &sinks() const; const std::vector<sink_ptr> &sinks() const;
std::vector<sink_ptr> &sinks(); std::vector<sink_ptr> &sinks();
// error handler
void set_error_handler(log_err_handler err_handler); void set_error_handler(log_err_handler err_handler);
log_err_handler error_handler(); log_err_handler error_handler();

View File

@ -38,8 +38,7 @@ using default_factory = synchronous_factory;
// The logger's level, formatter and flush level will be set according the // The logger's level, formatter and flush level will be set according the
// global settings. // global settings.
// Example: // Example:
// spdlog::create<daily_file_sink_st>("logger_name", "dailylog_filename", 11, // spdlog::create<daily_file_sink_st>("logger_name", "dailylog_filename", 11, 59);
// 59);
template<typename Sink, typename... SinkArgs> template<typename Sink, typename... SinkArgs>
inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&... sink_args) inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&... sink_args)
{ {
@ -54,11 +53,17 @@ inline std::shared_ptr<logger> get(const std::string &name)
return details::registry::instance().get(name); return details::registry::instance().get(name);
} }
// Set global formatting // Set global formatter. Each sink in each logger will get a clone of this object
// example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v"); inline void set_formatter(std::unique_ptr<spdlog::formatter> formatter)
inline void set_pattern(std::string format_string, pattern_time_type time_type = pattern_time_type::local)
{ {
details::registry::instance().set_pattern(std::move(format_string), time_type); details::registry::instance().set_formatter(std::move(formatter));
}
// Set global format string.
// example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v");
inline void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local)
{
set_formatter(std::unique_ptr<spdlog::formatter>(new pattern_formatter(pattern, time_type)));
} }
// Set global logging level // Set global logging level

View File

@ -9,7 +9,8 @@ static std::string log_to_str(const std::string &msg, const Args &... args)
auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss);
spdlog::logger oss_logger("pattern_tester", oss_sink); spdlog::logger oss_logger("pattern_tester", oss_sink);
oss_logger.set_level(spdlog::level::info); oss_logger.set_level(spdlog::level::info);
oss_logger.set_formatter<spdlog::pattern_formatter>(args...);
oss_logger.set_formatter(std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(args...)));
oss_logger.info(msg); oss_logger.info(msg);
return oss.str(); return oss.str();