From 1d86803e3846d89618b22feaa60a5f254e81f204 Mon Sep 17 00:00:00 2001 From: gabime Date: Thu, 20 Jun 2019 00:29:23 +0300 Subject: [PATCH] Fix #1116 --- include/spdlog/async.h | 3 +- include/spdlog/sinks/stdout_sinks-inl.h | 89 ++++++++++++++++++++++++ include/spdlog/sinks/stdout_sinks.h | 92 ++++++++++--------------- src/spdlog.cpp | 25 +++++++ 4 files changed, 152 insertions(+), 57 deletions(-) create mode 100644 include/spdlog/sinks/stdout_sinks-inl.h diff --git a/include/spdlog/async.h b/include/spdlog/async.h index 70f6c3fb..bf8187db 100644 --- a/include/spdlog/async.h +++ b/include/spdlog/async.h @@ -18,7 +18,6 @@ #include "spdlog/details/registry.h" #include "spdlog/details/thread_pool.h" - #include #include #include @@ -81,7 +80,7 @@ inline void init_thread_pool(size_t q_size, size_t thread_count, std::function +SPDLOG_INLINE stdout_sink_base::stdout_sink_base(FILE *file) + : mutex_(ConsoleMutex::mutex()) + , file_(file) +{} + +template +SPDLOG_INLINE void stdout_sink_base::log(const details::log_msg &msg) +{ + std::lock_guard lock(mutex_); + fmt::memory_buffer formatted; + formatter_->format(msg, formatted); + fwrite(formatted.data(), sizeof(char), formatted.size(), file_); + fflush(file_); // flush every line to terminal +} + +template +SPDLOG_INLINE void stdout_sink_base::flush() +{ + std::lock_guard lock(mutex_); + fflush(file_); +} + +template +SPDLOG_INLINE void stdout_sink_base::set_pattern(const std::string &pattern) +{ + std::lock_guard lock(mutex_); + formatter_ = std::unique_ptr(new pattern_formatter(pattern)); +} + +template +SPDLOG_INLINE void stdout_sink_base::set_formatter(std::unique_ptr sink_formatter) +{ + std::lock_guard lock(mutex_); + formatter_ = std::move(sink_formatter); +} + +// stdout sink +template +SPDLOG_INLINE stdout_sink::stdout_sink() + : stdout_sink_base(stdout) +{} + +// stderr sink +template +SPDLOG_INLINE stderr_sink::stderr_sink() + : stdout_sink_base(stderr) +{} + +} // namespace sinks + +// factory methods +template +SPDLOG_INLINE std::shared_ptr stdout_logger_mt(const std::string &logger_name) +{ + return Factory::template create(logger_name); +} + +template +SPDLOG_INLINE std::shared_ptr stdout_logger_st(const std::string &logger_name) +{ + return Factory::template create(logger_name); +} + +template +SPDLOG_INLINE std::shared_ptr stderr_logger_mt(const std::string &logger_name) +{ + return Factory::template create(logger_name); +} + +template +SPDLOG_INLINE std::shared_ptr stderr_logger_st(const std::string &logger_name) +{ + return Factory::template create(logger_name); +} +} // namespace spdlog diff --git a/include/spdlog/sinks/stdout_sinks.h b/include/spdlog/sinks/stdout_sinks.h index d313a249..48d6dc59 100644 --- a/include/spdlog/sinks/stdout_sinks.h +++ b/include/spdlog/sinks/stdout_sinks.h @@ -16,82 +16,64 @@ namespace spdlog { namespace sinks { -template -class stdout_sink final : public sink +template +class stdout_sink_base : public sink { public: using mutex_t = typename ConsoleMutex::mutex_t; - stdout_sink() - : mutex_(ConsoleMutex::mutex()) - , file_(TargetStream::stream()) - {} - ~stdout_sink() override = default; + explicit stdout_sink_base(FILE *file); + ~stdout_sink_base() override = default; + stdout_sink_base(const stdout_sink_base &other) = delete; + stdout_sink_base &operator=(const stdout_sink_base &other) = delete; - stdout_sink(const stdout_sink &other) = delete; - stdout_sink &operator=(const stdout_sink &other) = delete; + void log(const details::log_msg &msg) override; + void flush() override; + void set_pattern(const std::string &pattern) override; - void log(const details::log_msg &msg) override - { - std::lock_guard lock(mutex_); - fmt::memory_buffer formatted; - formatter_->format(msg, formatted); - fwrite(formatted.data(), sizeof(char), formatted.size(), file_); - fflush(TargetStream::stream()); - } - - void flush() override - { - std::lock_guard lock(mutex_); - fflush(file_); - } - - void set_pattern(const std::string &pattern) override - { - std::lock_guard lock(mutex_); - formatter_ = std::unique_ptr(new pattern_formatter(pattern)); - } - - void set_formatter(std::unique_ptr sink_formatter) override - { - std::lock_guard lock(mutex_); - formatter_ = std::move(sink_formatter); - } + void set_formatter(std::unique_ptr sink_formatter) override; private: mutex_t &mutex_; FILE *file_; }; -using stdout_sink_mt = stdout_sink; -using stdout_sink_st = stdout_sink; +template +class stdout_sink : public stdout_sink_base +{ +public: + stdout_sink(); +}; -using stderr_sink_mt = stdout_sink; -using stderr_sink_st = stdout_sink; +template +class stderr_sink : public stdout_sink_base +{ +public: + stderr_sink(); +}; + +using stdout_sink_mt = stdout_sink; +using stdout_sink_st = stdout_sink; + +using stderr_sink_mt = stderr_sink; +using stderr_sink_st = stderr_sink; } // namespace sinks // factory methods template -inline std::shared_ptr stdout_logger_mt(const std::string &logger_name) -{ - return Factory::template create(logger_name); -} +std::shared_ptr stdout_logger_mt(const std::string &logger_name); template -inline std::shared_ptr stdout_logger_st(const std::string &logger_name) -{ - return Factory::template create(logger_name); -} +std::shared_ptr stdout_logger_st(const std::string &logger_name); template -inline std::shared_ptr stderr_logger_mt(const std::string &logger_name) -{ - return Factory::template create(logger_name); -} +std::shared_ptr stderr_logger_mt(const std::string &logger_name); template -inline std::shared_ptr stderr_logger_st(const std::string &logger_name) -{ - return Factory::template create(logger_name); -} +std::shared_ptr stderr_logger_st(const std::string &logger_name); + } // namespace spdlog + +#ifdef SPDLOG_HEADER_ONLY +#include "stdout_sinks-inl.h" +#endif diff --git a/src/spdlog.cpp b/src/spdlog.cpp index dc67f39f..2d22b2bf 100644 --- a/src/spdlog.cpp +++ b/src/spdlog.cpp @@ -61,6 +61,7 @@ template class spdlog::sinks::ansicolor_stderr_sink; #endif +// factory methods for color sinks #include "spdlog/sinks/stdout_color_sinks-inl.h" template std::shared_ptr spdlog::stdout_color_mt( const std::string &logger_name, color_mode mode); @@ -76,6 +77,30 @@ template std::shared_ptr spdlog::stdout_color_st spdlog::stderr_color_mt(const std::string &logger_name, color_mode mode); template std::shared_ptr spdlog::stderr_color_st(const std::string &logger_name, color_mode mode); +// stdout/stderr sinks + +#include "spdlog/sinks/stdout_sinks-inl.h" + +template class spdlog::sinks::stdout_sink_base; +template class spdlog::sinks::stdout_sink_base; + +template class spdlog::sinks::stdout_sink; +template class spdlog::sinks::stdout_sink; + +template class spdlog::sinks::stderr_sink; +template class spdlog::sinks::stderr_sink; + +// factory methods +template std::shared_ptr spdlog::stdout_logger_mt(const std::string &logger_name); +template std::shared_ptr spdlog::stdout_logger_st(const std::string &logger_name); +template std::shared_ptr spdlog::stdout_logger_mt(const std::string &logger_name); +template std::shared_ptr spdlog::stdout_logger_st(const std::string &logger_name); + +template std::shared_ptr spdlog::stderr_logger_mt(const std::string &logger_name); +template std::shared_ptr spdlog::stderr_logger_st(const std::string &logger_name); +template std::shared_ptr spdlog::stderr_logger_mt(const std::string &logger_name); +template std::shared_ptr spdlog::stderr_logger_st(const std::string &logger_name); + // Slightly modified version of fmt lib's format.cc source file. // Copyright (c) 2012 - 2016, Victor Zverovich // All rights reserved.