Asink sink (#3309)

Replace async logger with async sink
This commit is contained in:
Gabi Melman
2025-01-05 02:17:31 +02:00
committed by GitHub
parent 166843ff3a
commit 83c9ede9e6
82 changed files with 986 additions and 1789 deletions

View File

@@ -5,7 +5,6 @@
#include <mutex>
#include "spdlog/details/null_mutex.h"
#include "spdlog/details/os.h"
#include "spdlog/pattern_formatter.h"
@@ -110,12 +109,13 @@ template <typename Mutex>
ansicolor_stderr_sink<Mutex>::ansicolor_stderr_sink(color_mode mode)
: ansicolor_sink<Mutex>(stderr, mode) {}
} // namespace sinks
} // namespace spdlog
// template instantiations
#include "spdlog/details/null_mutex.h"
template class SPDLOG_API spdlog::sinks::ansicolor_stdout_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::ansicolor_stdout_sink<spdlog::details::null_mutex>;
template class SPDLOG_API spdlog::sinks::ansicolor_stderr_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::ansicolor_stderr_sink<spdlog::details::null_mutex>;

130
src/sinks/async_sink.cpp Normal file
View File

@@ -0,0 +1,130 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include "spdlog/sinks/async_sink.h"
#include <cassert>
#include <memory>
#include "spdlog/common.h"
#include "spdlog/details/mpmc_blocking_q.h"
#include "spdlog/pattern_formatter.h"
#include "spdlog/spdlog.h"
namespace spdlog {
namespace sinks {
async_sink::async_sink(config async_config)
: config_(std::move(async_config)) {
if (config_.queue_size == 0 || config_.queue_size > max_queue_size) {
throw spdlog_ex("async_sink: invalid queue size");
}
q_ = std::make_unique<queue_t>(config_.queue_size);
worker_thread_ = std::thread([this] {
if (config_.on_thread_start) config_.on_thread_start();
this->backend_loop_();
if (config_.on_thread_stop) config_.on_thread_stop();
});
}
async_sink::~async_sink() {
try {
q_->enqueue(async_log_msg(async_log_msg::type::terminate));
worker_thread_.join();
} catch (...) {
printf("Exception in ~async_sink()\n");
}
}
void async_sink::log(const details::log_msg &msg) { send_message_(async_log_msg::type::log, msg); }
void async_sink::flush() { send_message_(async_log_msg::type::flush, details::log_msg()); }
void async_sink::set_pattern(const std::string &pattern) { set_formatter(std::make_unique<pattern_formatter>(pattern)); }
void async_sink::set_formatter(std::unique_ptr<formatter> formatter) {
const auto &sinks = config_.sinks;
for (auto it = sinks.begin(); it != sinks.end(); ++it) {
if (std::next(it) == sinks.end()) {
// last element - we can move it.
(*it)->set_formatter(std::move(formatter));
break; // to prevent clang-tidy warning
}
(*it)->set_formatter(formatter->clone());
}
}
size_t async_sink::get_overrun_counter() const { return q_->overrun_counter(); }
void async_sink::reset_overrun_counter() const { q_->reset_overrun_counter(); }
size_t async_sink::get_discard_counter() const { return q_->discard_counter(); }
void async_sink::reset_discard_counter() const { q_->reset_discard_counter(); }
const async_sink::config &async_sink::get_config() const { return config_; }
// private methods
void async_sink::send_message_(async_log_msg::type msg_type, const details::log_msg &msg) const {
switch (config_.policy) {
case overflow_policy::block:
q_->enqueue(async_log_msg(msg_type, msg));
break;
case overflow_policy::overrun_oldest:
q_->enqueue_nowait(async_log_msg(msg_type, msg));
break;
case overflow_policy::discard_new:
q_->enqueue_if_have_room(async_log_msg(msg_type, msg));
break;
default:
assert(false);
throw spdlog_ex("async_sink: invalid overflow policy");
}
}
void async_sink::backend_loop_() {
details::async_log_msg incoming_msg;
for (;;) {
q_->dequeue(incoming_msg);
switch (incoming_msg.message_type()) {
case async_log_msg::type::log:
backend_log_(incoming_msg);
break;
case async_log_msg::type::flush:
backend_flush_();
break;
case async_log_msg::type::terminate:
return;
default:
assert(false);
}
}
}
void async_sink::backend_log_(const details::log_msg &msg) {
for (const auto &sink : config_.sinks) {
if (sink->should_log(msg.log_level)) {
try {
sink->log(msg);
} catch (const std::exception &ex) {
err_helper_.handle_ex("async log", msg.source, ex);
} catch (...) {
err_helper_.handle_unknown_ex("async log", source_loc{});
}
}
}
}
void async_sink::backend_flush_() {
for (const auto &sink : config_.sinks) {
try {
sink->flush();
} catch (const std::exception &ex) {
err_helper_.handle_ex("async flush", source_loc{}, ex);
} catch (...) {
err_helper_.handle_unknown_ex("async flush", source_loc{});
}
}
}
} // namespace sinks
} // namespace spdlog

View File

@@ -5,53 +5,58 @@
#include <memory>
#include <mutex>
#include "spdlog/common.h"
#include "spdlog/details/null_mutex.h"
#include "spdlog/pattern_formatter.h"
namespace spdlog {
namespace sinks {
template <typename Mutex>
spdlog::sinks::base_sink<Mutex>::base_sink()
base_sink<Mutex>::base_sink()
: formatter_{std::make_unique<spdlog::pattern_formatter>()} {}
template <typename Mutex>
spdlog::sinks::base_sink<Mutex>::base_sink(std::unique_ptr<spdlog::formatter> formatter)
base_sink<Mutex>::base_sink(std::unique_ptr<spdlog::formatter> formatter)
: formatter_{std::move(formatter)} {}
template <typename Mutex>
void spdlog::sinks::base_sink<Mutex>::log(const details::log_msg &msg) {
void base_sink<Mutex>::log(const details::log_msg &msg) {
std::lock_guard<Mutex> lock(mutex_);
sink_it_(msg);
}
template <typename Mutex>
void spdlog::sinks::base_sink<Mutex>::flush() {
void base_sink<Mutex>::flush() {
std::lock_guard<Mutex> lock(mutex_);
flush_();
}
template <typename Mutex>
void spdlog::sinks::base_sink<Mutex>::set_pattern(const std::string &pattern) {
void base_sink<Mutex>::set_pattern(const std::string &pattern) {
std::lock_guard<Mutex> lock(mutex_);
set_pattern_(pattern);
}
template <typename Mutex>
void spdlog::sinks::base_sink<Mutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
void base_sink<Mutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
std::lock_guard<Mutex> lock(mutex_);
set_formatter_(std::move(sink_formatter));
}
template <typename Mutex>
void spdlog::sinks::base_sink<Mutex>::set_pattern_(const std::string &pattern) {
set_formatter_(std::make_unique<spdlog::pattern_formatter>(pattern));
void base_sink<Mutex>::set_pattern_(const std::string &pattern) {
set_formatter_(std::make_unique<pattern_formatter>(pattern));
}
template <typename Mutex>
void spdlog::sinks::base_sink<Mutex>::set_formatter_(std::unique_ptr<spdlog::formatter> sink_formatter) {
void base_sink<Mutex>::set_formatter_(std::unique_ptr<formatter> sink_formatter) {
formatter_ = std::move(sink_formatter);
}
} // namespace sinks
} // namespace spdlog
// template instantiations
#include "spdlog/details/null_mutex.h"
template class SPDLOG_API spdlog::sinks::base_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::base_sink<spdlog::details::null_mutex>;

View File

@@ -2,8 +2,8 @@
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/common.h"
#include <mutex>
namespace spdlog {
namespace sinks {
@@ -34,6 +34,8 @@ void basic_file_sink<Mutex>::flush_() {
} // namespace sinks
} // namespace spdlog
// template instantiations
#include "spdlog/details/null_mutex.h"
template class SPDLOG_API spdlog::sinks::basic_file_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::basic_file_sink<spdlog::details::null_mutex>;

View File

@@ -140,5 +140,6 @@ bool rotating_file_sink<Mutex>::rename_file_(const filename_t &src_filename, con
} // namespace spdlog
// template instantiations
#include "spdlog/details/null_mutex.h"
template class SPDLOG_API spdlog::sinks::rotating_file_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::rotating_file_sink<spdlog::details::null_mutex>;
template class SPDLOG_API spdlog::sinks::rotating_file_sink<spdlog::details::null_mutex>;

View File

@@ -1,14 +0,0 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include "spdlog/sinks/sink.h"
#include "spdlog/common.h"
bool spdlog::sinks::sink::should_log(spdlog::level msg_level) const {
return msg_level >= level_.load(std::memory_order_relaxed);
}
void spdlog::sinks::sink::set_level(level level) { level_.store(level, std::memory_order_relaxed); }
spdlog::level spdlog::sinks::sink::log_level() const { return level_.load(std::memory_order_relaxed); }

View File

@@ -1,57 +0,0 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/async.h"
#include "spdlog/common.h"
#include "spdlog/details/synchronous_factory.h"
#include "spdlog/logger.h"
namespace spdlog {
template <typename Factory>
std::shared_ptr<logger> stdout_color_mt(const std::string &logger_name, color_mode mode) {
return Factory::template create<sinks::stdout_color_sink_mt>(logger_name, mode);
}
template <typename Factory>
std::shared_ptr<logger> stdout_color_st(const std::string &logger_name, color_mode mode) {
return Factory::template create<sinks::stdout_color_sink_st>(logger_name, mode);
}
template <typename Factory>
std::shared_ptr<logger> stderr_color_mt(const std::string &logger_name, color_mode mode) {
return Factory::template create<sinks::stderr_color_sink_mt>(logger_name, mode);
}
template <typename Factory>
std::shared_ptr<logger> stderr_color_st(const std::string &logger_name, color_mode mode) {
return Factory::template create<sinks::stderr_color_sink_st>(logger_name, mode);
}
} // namespace spdlog
// template instantiations
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::async_factory>(const std::string &logger_name,
color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::async_factory>(const std::string &logger_name,
color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::async_factory>(const std::string &logger_name,
color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::async_factory>(const std::string &logger_name,
color_mode mode);

View File

@@ -4,6 +4,7 @@
#include "spdlog/sinks/stdout_sinks.h"
#include <memory>
#include <mutex>
#include "spdlog/details/os.h"
#include "spdlog/pattern_formatter.h"
@@ -82,55 +83,11 @@ stderr_sink<Mutex>::stderr_sink()
: stdout_sink_base<Mutex>(stderr) {}
} // namespace sinks
// factory methods
template <typename Factory>
std::shared_ptr<logger> stdout_logger_mt(const std::string &logger_name) {
return Factory::template create<sinks::stdout_sink_mt>(logger_name);
}
template <typename Factory>
std::shared_ptr<logger> stdout_logger_st(const std::string &logger_name) {
return Factory::template create<sinks::stdout_sink_st>(logger_name);
}
template <typename Factory>
std::shared_ptr<logger> stderr_logger_mt(const std::string &logger_name) {
return Factory::template create<sinks::stderr_sink_mt>(logger_name);
}
template <typename Factory>
std::shared_ptr<logger> stderr_logger_st(const std::string &logger_name) {
return Factory::template create<sinks::stderr_sink_st>(logger_name);
}
} // namespace spdlog
// template instantiations for stdout/stderr loggers
template class SPDLOG_API spdlog::sinks::stdout_sink_base<std::mutex>;
template class SPDLOG_API spdlog::sinks::stdout_sink_base<spdlog::details::null_mutex>;
// template instantiations
#include "spdlog/details/null_mutex.h"
template class SPDLOG_API spdlog::sinks::stdout_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::stdout_sink<spdlog::details::null_mutex>;
template class SPDLOG_API spdlog::sinks::stderr_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::stderr_sink<spdlog::details::null_mutex>;
// template instantiations for stdout/stderr factory functions
#include "spdlog/async.h"
#include "spdlog/details/synchronous_factory.h"
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt<spdlog::synchronous_factory>(
const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st<spdlog::synchronous_factory>(
const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt<spdlog::synchronous_factory>(
const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st<spdlog::synchronous_factory>(
const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt<spdlog::async_factory>(
const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st<spdlog::async_factory>(
const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt<spdlog::async_factory>(
const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st<spdlog::async_factory>(
const std::string &logger_name);
template class SPDLOG_API spdlog::sinks::stderr_sink<spdlog::details::null_mutex>;

View File

@@ -5,12 +5,10 @@
#include "spdlog/details/windows_include.h"
#include <wincon.h>
#include <mutex>
// clang-format on
#include "spdlog/sinks/wincolor_sink.h"
#include "spdlog/common.h"
#include "spdlog/details/null_mutex.h"
namespace spdlog {
namespace sinks {
@@ -132,15 +130,14 @@ wincolor_stdout_sink<Mutex>::wincolor_stdout_sink(color_mode mode)
template <typename Mutex>
wincolor_stderr_sink<Mutex>::wincolor_stderr_sink(color_mode mode)
: wincolor_sink<Mutex>(::GetStdHandle(STD_ERROR_HANDLE), mode) {}
} // namespace sinks
} // namespace spdlog
// template instantiations
template class SPDLOG_API spdlog::sinks::wincolor_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::wincolor_sink<spdlog::details::null_mutex>;
#include "spdlog/details/null_mutex.h"
template class SPDLOG_API spdlog::sinks::wincolor_stdout_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::wincolor_stdout_sink<spdlog::details::null_mutex>;
template class SPDLOG_API spdlog::sinks::wincolor_stderr_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::wincolor_stderr_sink<spdlog::details::null_mutex>;