4#include <condition_variable>
15#include <fmt/format.h>
16#include <fmt/ranges.h>
27 using sink_type = std::function<void(std::string_view)>;
30 : sink_([](std::string_view msg)
32 fmt::print(
"{}\n", msg);
34 worker_([
this](
const std::stop_token& st)
42 : sink_(std::move(sink)), worker_([this](const std::stop_token& st)
54 async_logger(
const async_logger&) =
delete;
55 async_logger& operator=(
const async_logger&) =
delete;
56 async_logger(async_logger&&) =
delete;
57 async_logger& operator=(async_logger&&) =
delete;
63 template <
typename... FormatArgs>
64 void log(fmt::format_string<FormatArgs...> fmt_s, FormatArgs&&...
args)
66 enqueue(fmt::format(fmt_s, std::forward<FormatArgs>(
args)...));
73 enqueue(std::move(msg));
79 std::unique_lock lock(mtx_);
80 drained_cv_.wait(lock, [
this]()
89 bool should_join =
false;
91 std::lock_guard lock(mtx_);
101 worker_.request_stop();
103 if (worker_.joinable())
114 std::lock_guard lock(mtx_);
115 sink_ = std::move(sink);
121 void enqueue(std::string msg)
123 std::lock_guard lock(mtx_);
129 queue_.emplace_back(std::move(msg));
136 void run(
const std::stop_token& st)
144 std::unique_lock lock(mtx_);
145 cv_.wait(lock, [
this, &st]()
147 return st.stop_requested() || !queue_.empty();
150 if (st.stop_requested() && queue_.empty())
155 message = std::move(queue_.front());
172 std::lock_guard lock(mtx_);
179 drained_cv_.notify_all();
184 std::lock_guard lock(mtx_);
187 drained_cv_.notify_all();
191 mutable std::mutex mtx_;
192 std::condition_variable cv_;
193 std::condition_variable drained_cv_;
194 std::deque<std::string> queue_;
196 std::jthread worker_;
197 std::size_t pending_{0};
198 bool stopped_{
false};
225 fmt::print(
"{}\n", msg);
238 template <
typename... Args>
241 std::vector<std::string> parts = {fmt::format(
"{}", std::forward<Args>(
args))...};
void set_printer_sink(async_logger::sink_type sink)
Set the sink function for the global async logger.
Definition async_logger.h:211
void flush_printer()
Flush the global async logger, blocking until all pending messages are processed.
Definition async_logger.h:230
void printer(Args &&... args)
Log a message using the global async logger.
Definition async_logger.h:239
async_logger & global_async_logger()
Get the global async logger instance.
Definition async_logger.h:203
void reset_printer_sink()
Flush the global async logger, blocking until all pending messages are processed.
Definition async_logger.h:219
Command-line argument handler with JSON support.
Definition args.h:19
Asynchronous logger class.
Definition async_logger.h:24
void log_message(std::string msg)
Log a message.
Definition async_logger.h:71
std::function< void(std::string_view)> sink_type
Type alias for the sink function.
Definition async_logger.h:27
void stop() noexcept
Stop the logger, blocking until all pending messages are processed.
Definition async_logger.h:87
void set_sink(sink_type sink)
Set the sink function for the logger.
Definition async_logger.h:112
void flush()
Flush the logger, blocking until all pending messages are processed.
Definition async_logger.h:77
void log(fmt::format_string< FormatArgs... > fmt_s, FormatArgs &&... args)
Log a formatted message.
Definition async_logger.h:64