From 09cb45001bfd63b2ddbab3e3d2381cad842bdcf8 Mon Sep 17 00:00:00 2001 From: gabime Date: Sat, 15 Jun 2019 19:46:41 +0300 Subject: [PATCH] Added copy ctor and assignment to logger --- include/spdlog/logger-inl.h | 364 ++++++++++++++++++++---------------- include/spdlog/logger.h | 24 ++- 2 files changed, 221 insertions(+), 167 deletions(-) diff --git a/include/spdlog/logger-inl.h b/include/spdlog/logger-inl.h index 8f2bfa0a..7df8a1cc 100644 --- a/include/spdlog/logger-inl.h +++ b/include/spdlog/logger-inl.h @@ -11,180 +11,228 @@ #include "spdlog/details/pattern_formatter.h" namespace spdlog { -// public methods -SPDLOG_INLINE void logger::log(source_loc loc, level::level_enum lvl, const char *msg) -{ - if (!should_log(lvl)) + + // public methods + SPDLOG_INLINE logger::logger(const logger &other): + name_(other.name_), + sinks_(other.sinks_), + level_(other.level_.load(std::memory_order_relaxed)), + flush_level_(other.flush_level_.load(std::memory_order_relaxed)), + custom_err_handler_(other.custom_err_handler_) { - return; } - try + SPDLOG_INLINE logger::logger(logger &&other): + name_(std::move(other.name_)), + sinks_(std::move(other.sinks_)), + level_(other.level_.load(std::memory_order_relaxed)), + flush_level_(other.flush_level_.load(std::memory_order_relaxed)), + custom_err_handler_(std::move(other.custom_err_handler_)) { - details::log_msg log_msg(loc, string_view_t(name_), lvl, string_view_t(msg)); - sink_it_(log_msg); } - catch (const std::exception &ex) + + + SPDLOG_INLINE logger &logger::operator=(logger other) { - err_handler_(ex.what()); + this->swap(other); + return *this; } - catch (...) + + SPDLOG_INLINE void logger::swap(spdlog::logger &other) { - err_handler_("Unknown exception in logger"); + name_.swap(other.name_); + sinks_.swap(other.sinks_); + + //swap level_ + auto tmp = other.level_.load(); + tmp = level_.exchange(tmp); + other.level_.store(tmp); + + //swap flush level_ + tmp = other.flush_level_.load(); + tmp = flush_level_.exchange(tmp); + other.flush_level_.store(tmp); + + custom_err_handler_.swap(other.custom_err_handler_); } -} -SPDLOG_INLINE void logger::log(level::level_enum lvl, const char *msg) -{ - log(source_loc{}, lvl, msg); -} -SPDLOG_INLINE bool logger::should_log(level::level_enum msg_level) const -{ - return msg_level >= level_.load(std::memory_order_relaxed); -} - -SPDLOG_INLINE void logger::set_level(level::level_enum log_level) -{ - level_.store(log_level); -} - -SPDLOG_INLINE level::level_enum logger::default_level() -{ - return static_cast(SPDLOG_ACTIVE_LEVEL); -} - -SPDLOG_INLINE level::level_enum logger::level() const -{ - return static_cast(level_.load(std::memory_order_relaxed)); -} - -SPDLOG_INLINE const std::string &logger::name() const -{ - return name_; -} - -// set formatting for the sinks in this logger. -// each sink will get a seperate instance of the formatter object. -SPDLOG_INLINE void logger::set_formatter(std::unique_ptr f) -{ - for (auto it = sinks_.begin(); it != sinks_.end(); ++it) + SPDLOG_INLINE void swap(logger &a, logger &b) { - if (std::next(it) == sinks_.end()) + a.swap(b); + } + + void logger::log(source_loc loc, level::level_enum lvl, const char *msg) + { + if (!should_log(lvl)) { - // last element - we can be move it. - (*it)->set_formatter(std::move(f)); + return; + } + + try + { + details::log_msg log_msg(loc, string_view_t(name_), lvl, string_view_t(msg)); + sink_it_(log_msg); + } + catch (const std::exception &ex) + { + err_handler_(ex.what()); + } + catch (...) + { + err_handler_("Unknown exception in logger"); + } + } + + SPDLOG_INLINE void logger::log(level::level_enum lvl, const char *msg) + { + log(source_loc{}, lvl, msg); + } + + SPDLOG_INLINE bool logger::should_log(level::level_enum msg_level) const + { + return msg_level >= level_.load(std::memory_order_relaxed); + } + + SPDLOG_INLINE void logger::set_level(level::level_enum log_level) + { + level_.store(log_level); + } + + SPDLOG_INLINE level::level_enum logger::default_level() + { + return static_cast(SPDLOG_ACTIVE_LEVEL); + } + + SPDLOG_INLINE level::level_enum logger::level() const + { + return static_cast(level_.load(std::memory_order_relaxed)); + } + + SPDLOG_INLINE const std::string &logger::name() const + { + return name_; + } + + // set formatting for the sinks in this logger. + // each sink will get a seperate instance of the formatter object. + SPDLOG_INLINE void logger::set_formatter(std::unique_ptr f) + { + for (auto it = sinks_.begin(); it != sinks_.end(); ++it) + { + if (std::next(it) == sinks_.end()) + { + // last element - we can be move it. + (*it)->set_formatter(std::move(f)); + } + else + { + (*it)->set_formatter(f->clone()); + } + } + } + + SPDLOG_INLINE void logger::set_pattern(std::string pattern, pattern_time_type time_type) + { + auto new_formatter = details::make_unique(std::move(pattern), time_type); + set_formatter(std::move(new_formatter)); + } + + // flush functions + SPDLOG_INLINE void logger::flush() + { + try + { + flush_(); + } + catch (const std::exception &ex) + { + err_handler_(ex.what()); + } + catch (...) + { + err_handler_("Unknown exception in logger"); + } + } + + SPDLOG_INLINE void logger::flush_on(level::level_enum log_level) + { + flush_level_.store(log_level); + } + + SPDLOG_INLINE level::level_enum logger::flush_level() const + { + return static_cast(flush_level_.load(std::memory_order_relaxed)); + } + +// sinks + SPDLOG_INLINE const std::vector &logger::sinks() const + { + return sinks_; + } + + SPDLOG_INLINE std::vector &logger::sinks() + { + return sinks_; + } + + // error handler + SPDLOG_INLINE void logger::set_error_handler(err_handler handler) + { + custom_err_handler_ = handler; + } + + // create new logger with same sinks and configuration. + SPDLOG_INLINE std::shared_ptr logger::clone(std::string logger_name) + { + auto cloned = std::make_shared(*this); + cloned->name_ = std::move(logger_name); + return cloned; + } + + // protected methods + SPDLOG_INLINE void logger::sink_it_(details::log_msg &msg) + { + for (auto &sink : sinks_) + { + if (sink->should_log(msg.level)) + { + sink->log(msg); + } + } + + if (should_flush_(msg)) + { + flush_(); + } + } + + SPDLOG_INLINE void logger::flush_() + { + for (auto &sink : sinks_) + { + sink->flush(); + } + } + + SPDLOG_INLINE bool logger::should_flush_(const details::log_msg &msg) + { + auto flush_level = flush_level_.load(std::memory_order_relaxed); + return (msg.level >= flush_level) && (msg.level != level::off); + } + + SPDLOG_INLINE void logger::err_handler_(const std::string &msg) + { + if (custom_err_handler_) + { + custom_err_handler_(msg); } else { - (*it)->set_formatter(f->clone()); + auto tm_time = details::os::localtime(); + char date_buf[64]; + std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time); + fmt::print(stderr, "[*** LOG ERROR ***] [{}] [{}] {}\n", date_buf, name(), msg); } } -} - -SPDLOG_INLINE void logger::set_pattern(std::string pattern, pattern_time_type time_type) -{ - auto new_formatter = details::make_unique(std::move(pattern), time_type); - set_formatter(std::move(new_formatter)); -} - -// flush functions -SPDLOG_INLINE void logger::flush() -{ - try - { - flush_(); - } - catch (const std::exception &ex) - { - err_handler_(ex.what()); - } - catch (...) - { - err_handler_("Unknown exception in logger"); - } -} - -SPDLOG_INLINE void logger::flush_on(level::level_enum log_level) -{ - flush_level_.store(log_level); -} - -SPDLOG_INLINE level::level_enum logger::flush_level() const -{ - return static_cast(flush_level_.load(std::memory_order_relaxed)); -} - -// sinks -SPDLOG_INLINE const std::vector &logger::sinks() const -{ - return sinks_; -} - -SPDLOG_INLINE std::vector &logger::sinks() -{ - return sinks_; -} - -// error handler -SPDLOG_INLINE void logger::set_error_handler(err_handler handler) -{ - custom_err_handler_ = handler; -} - -// create new logger with same sinks and configuration. -SPDLOG_INLINE std::shared_ptr logger::clone(std::string logger_name) -{ - auto cloned = std::make_shared(std::move(logger_name), sinks_.begin(), sinks_.end()); - cloned->set_level(this->level()); - cloned->flush_on(this->flush_level()); - cloned->set_error_handler(this->custom_err_handler_); - return cloned; -} - -// protected methods -SPDLOG_INLINE void logger::sink_it_(details::log_msg &msg) -{ - for (auto &sink : sinks_) - { - if (sink->should_log(msg.level)) - { - sink->log(msg); - } - } - - if (should_flush_(msg)) - { - flush_(); - } -} - -SPDLOG_INLINE void logger::flush_() -{ - for (auto &sink : sinks_) - { - sink->flush(); - } -} - -SPDLOG_INLINE bool logger::should_flush_(const details::log_msg &msg) -{ - auto flush_level = flush_level_.load(std::memory_order_relaxed); - return (msg.level >= flush_level) && (msg.level != level::off); -} - -SPDLOG_INLINE void logger::err_handler_(const std::string &msg) -{ - if (custom_err_handler_) - { - custom_err_handler_(msg); - } - else - { - auto tm_time = details::os::localtime(); - char date_buf[64]; - std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time); - fmt::print(stderr, "[*** LOG ERROR ***] [{}] [{}] {}\n", date_buf, name(), msg); - } -} } // namespace spdlog \ No newline at end of file diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index f2732d28..b11b7820 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -56,8 +56,11 @@ public: virtual ~logger() = default; - logger(const logger &) = delete; - logger &operator=(const logger &) = delete; + logger(const logger &other); + logger(logger &&other); + logger &operator=(logger other); + + void swap(spdlog::logger &other); template void log(source_loc loc, level::level_enum lvl, const char *fmt, const Args &... args) @@ -328,23 +331,26 @@ public: virtual std::shared_ptr clone(std::string logger_name); protected: - virtual void sink_it_(details::log_msg &msg); + std::string name_; + std::vector sinks_; + spdlog::level_t level_{spdlog::logger::default_level()}; + spdlog::level_t flush_level_{level::off}; + err_handler custom_err_handler_{nullptr}; + virtual void sink_it_(details::log_msg &msg); virtual void flush_(); bool should_flush_(const details::log_msg &msg); // default error handler. // print the error to stderr with the max rate of 1 message/minute. void err_handler_(const std::string &msg); - - const std::string name_; - std::vector sinks_; - spdlog::level_t level_{spdlog::logger::default_level()}; - spdlog::level_t flush_level_{level::off}; - err_handler custom_err_handler_{nullptr}; }; + +void swap(logger& a, logger& b); + } // namespace spdlog + #ifdef SPDLOG_HEADER_ONLY #include "logger-inl.h" #endif