Commit 6f4cd8d3 authored by gabime's avatar gabime

thread_pool and refactoring async

parent 5e08950e
......@@ -6,10 +6,10 @@
//
// bench.cpp : spdlog benchmarks
//
#include "spdlog/async_logger.h"
#include "spdlog/sinks/file_sinks.h"
#include "spdlog/async.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/spdlog.h"
#include "utils.h"
#include <atomic>
#include <cstdlib> // EXIT_FAILURE
......@@ -71,11 +71,10 @@ int main(int argc, char *argv[])
cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " iterations " << endl;
cout << "*******************************************************************************\n";
spdlog::set_async_mode(queue_size);
for (int i = 0; i < 3; ++i)
{
auto as = spdlog::daily_logger_st("as", "logs/daily_async.log");
spdlog::init_thread_pool(queue_size, 1);
auto as = spdlog::daily_logger_mt<spdlog::create_async>("as", "logs/daily_async.log");
bench_mt(howmany, as, threads);
spdlog::drop("as");
}
......
......@@ -10,6 +10,7 @@
#define SPDLOG_TRACE_ON
#define SPDLOG_DEBUG_ON
#include "spdlog/async.h"
#include "spdlog/spdlog.h"
#include <iostream>
......@@ -27,9 +28,10 @@ int main(int, char *[])
try
{
// Console logger with color
auto console = spd::stdout_color_mt("console");
auto console = spdlog::console<spd::stdout_color_mt>("console");
auto console2 = spdlog::console<spd::stdout_color_mt>("console");
console->info("Welcome to spdlog!");
console->error("Some error message with arg{}..", 1);
console->error("Some error message with arg: {}", 1);
// Formatting examples
console->warn("Easy padding in numbers like {:08d}", 12);
......@@ -105,13 +107,16 @@ int main(int, char *[])
void async_example()
{
size_t q_size = 4096; // queue size must be power of 2
spdlog::set_async_mode(q_size);
auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log.txt");
auto async_file = spd::basic_logger_mt<spdlog::create_async>("async_file_logger", "logs/async_log.txt");
for (int i = 0; i < 100; ++i)
{
async_file->info("Async message #{}", i);
}
// optional change thread pool settings *before* creating the logger:
// spdlog::init_thread_pool(8192, 1);
// if not called a defaults are: 8192 queue size and 1 worker thread.
}
// syslog example (linux/osx/freebsd)
......
......@@ -20,52 +20,39 @@
#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
namespace spdlog {
namespace details {
class async_log_helper;
class thread_pool;
}
class async_logger SPDLOG_FINAL : public logger
class async_logger SPDLOG_FINAL : public std::enable_shared_from_this<async_logger>, public logger
{
friend class details::thread_pool;
public:
template<class It>
async_logger(const std::string &logger_name, const It &begin, const It &end, size_t queue_size,
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
const std::function<void()> &worker_warmup_cb = nullptr,
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
const std::function<void()> &worker_teardown_cb = nullptr);
async_logger(const std::string &logger_name, const It &begin, const It &end, std::weak_ptr<details::thread_pool> tp,
async_overflow_policy overflow_policy = async_overflow_policy::block_retry);
async_logger(const std::string &logger_name, sinks_init_list sinks, size_t queue_size,
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
const std::function<void()> &worker_warmup_cb = nullptr,
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
const std::function<void()> &worker_teardown_cb = nullptr);
async_logger(const std::string &logger_name, sinks_init_list sinks, std::weak_ptr<details::thread_pool> tp,
async_overflow_policy overflow_policy = async_overflow_policy::block_retry);
async_logger(const std::string &logger_name, sink_ptr single_sink, size_t queue_size,
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
const std::function<void()> &worker_warmup_cb = nullptr,
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
const std::function<void()> &worker_teardown_cb = nullptr);
// Wait for the queue to be empty, and flush synchronously
// Warning: this can potentially last forever as we wait it to complete
void flush() override;
// Error handler
void set_error_handler(log_err_handler) override;
log_err_handler error_handler() override;
async_logger(const std::string &logger_name, sink_ptr single_sink, std::weak_ptr<details::thread_pool> tp,
async_overflow_policy overflow_policy = async_overflow_policy::block_retry);
protected:
void _sink_it(details::log_msg &msg) override;
void _set_formatter(spdlog::formatter_ptr msg_formatter) override;
void _set_pattern(const std::string &pattern, pattern_time_type pattern_time) override;
void _flush() override;
void _backend_log(details::log_msg &incoming_log_msg);
void _backend_flush();
private:
std::unique_ptr<details::async_log_helper> _async_log_helper;
std::weak_ptr<details::thread_pool> _thread_pool;
async_overflow_policy _overflow_policy;
};
} // namespace spdlog
......
Please put here your contribs. Popular contribs will be moved to main tree after stablization
......@@ -72,8 +72,7 @@ class async_log_helper
msg_id(other.msg_id)
{
}
async_msg &operator=(async_msg &&other) SPDLOG_NOEXCEPT
dsdfsfs async_msg &operator=(async_msg &&other) SPDLOG_NOEXCEPT
{
logger_name = std::move(other.logger_name);
level = other.level;
......
......@@ -5,82 +5,110 @@
#pragma once
// Async Logger implementation
// Use an async_sink (queue per logger) to perform the logging in a worker thread
// async logger implementation
// uses a thread pool to perform the actual logging
#include "../async_logger.h"
#include "../details/async_log_helper.h"
#include "../details/thread_pool.h"
#include <chrono>
#include <functional>
#include <memory>
#include <string>
template<class It>
inline spdlog::async_logger::async_logger(const std::string &logger_name, const It &begin, const It &end, size_t queue_size,
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
inline spdlog::async_logger::async_logger(const std::string &logger_name, const It &begin, const It &end,
std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy)
: logger(logger_name, begin, end)
, _async_log_helper(new details::async_log_helper(
_formatter, _sinks, queue_size, _err_handler, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb))
, _thread_pool(tp)
, _overflow_policy(overflow_policy)
{
}
inline spdlog::async_logger::async_logger(const std::string &logger_name, sinks_init_list sinks_list, size_t queue_size,
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
: async_logger(logger_name, sinks_list.begin(), sinks_list.end(), queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms,
worker_teardown_cb)
inline spdlog::async_logger::async_logger(const std::string &logger_name, sinks_init_list sinks_list,
std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy)
: async_logger(logger_name, sinks_list.begin(), sinks_list.end(), tp, overflow_policy)
{
}
inline spdlog::async_logger::async_logger(const std::string &logger_name, sink_ptr single_sink, size_t queue_size,
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
: async_logger(
logger_name, {std::move(single_sink)}, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb)
inline spdlog::async_logger::async_logger(
const std::string &logger_name, sink_ptr single_sink, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy)
: async_logger(logger_name, {single_sink}, tp, overflow_policy)
{
}
inline void spdlog::async_logger::flush()
{
_async_log_helper->flush(true);
}
// Error handler
inline void spdlog::async_logger::set_error_handler(spdlog::log_err_handler err_handler)
{
_err_handler = err_handler;
_async_log_helper->set_error_handler(err_handler);
}
inline spdlog::log_err_handler spdlog::async_logger::error_handler()
// send the log message to the thread pool
inline void spdlog::async_logger::_sink_it(details::log_msg &msg)
{
return _err_handler;
try
{
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
_incr_msg_counter(msg);
#endif
if (auto pool_ptr = _thread_pool.lock())
{
pool_ptr->post_log(shared_from_this(), std::move(msg), _overflow_policy);
}
else
{
throw spdlog_ex("async log: thread pool doens't exist anymore");
}
}
catch (const std::exception &ex)
{
_err_handler(ex.what());
}
catch (...)
{
_err_handler("Unknown exception in async logger " + _name);
}
}
inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_formatter)
// send flush request to the thread pool
inline void spdlog::async_logger::_flush()
{
_formatter = msg_formatter;
_async_log_helper->set_formatter(_formatter);
if (auto pool_ptr = _thread_pool.lock())
{
pool_ptr->post_flush(shared_from_this(), _overflow_policy);
}
else
{
throw spdlog_ex("async flush: thread pool doens't exist anymore");
}
}
inline void spdlog::async_logger::_set_pattern(const std::string &pattern, pattern_time_type pattern_time)
//
// backend functions - called from the thread pool to do the actual job
//
inline void spdlog::async_logger::_backend_log(details::log_msg &incoming_log_msg)
{
_formatter = std::make_shared<pattern_formatter>(pattern, pattern_time);
_async_log_helper->set_formatter(_formatter);
try
{
_formatter->format(incoming_log_msg);
for (auto &s : _sinks)
{
if (s->should_log(incoming_log_msg.level))
{
s->log(incoming_log_msg);
}
}
}
catch (const std::exception &ex)
{
_err_handler(ex.what());
}
catch (...)
{
_err_handler("Unknown exception in async logger " + _name);
}
}
inline void spdlog::async_logger::_sink_it(details::log_msg &msg)
inline void spdlog::async_logger::_backend_flush()
{
try
{
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
_incr_msg_counter(msg);
#endif
_async_log_helper->log(msg);
if (_should_flush_on(msg))
for (auto &sink : _sinks)
{
_async_log_helper->flush(false); // do async flush
sink->flush();
}
}
catch (const std::exception &ex)
......@@ -89,7 +117,6 @@ inline void spdlog::async_logger::_sink_it(details::log_msg &msg)
}
catch (...)
{
_err_handler("Unknown exception in logger " + _name);
throw;
_err_handler("Unknown exception in async logger " + _name);
}
}
......@@ -30,8 +30,8 @@ struct log_msg
}
log_msg(const log_msg &other) = delete;
log_msg &operator=(log_msg &&other) = delete;
log_msg(log_msg &&other) = delete;
log_msg &operator=(log_msg &&other) = delete;
const std::string *logger_name{nullptr};
level::level_enum level;
......@@ -40,7 +40,7 @@ struct log_msg
fmt::MemoryWriter raw;
fmt::MemoryWriter formatted;
size_t msg_id{0};
// wrap this range with color codes
// info about wrapping the formatted text with color
size_t color_range_start{0};
size_t color_range_end{0};
};
......
......@@ -42,12 +42,12 @@ inline spdlog::logger::~logger() = default;
inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter)
{
_set_formatter(std::move(msg_formatter));
_formatter = std::move(msg_formatter);
}
inline void spdlog::logger::set_pattern(const std::string &pattern, pattern_time_type pattern_time)
{
_set_pattern(pattern, pattern_time);
_formatter = std::make_shared<pattern_formatter>(pattern, pattern_time);
}
template<typename... Args>
......@@ -282,11 +282,22 @@ inline spdlog::log_err_handler spdlog::logger::error_handler()
return _err_handler;
}
inline void spdlog::logger::flush()
{
_flush();
}
inline void spdlog::logger::flush_on(level::level_enum log_level)
{
_flush_level.store(log_level);
}
inline bool spdlog::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);
}
inline spdlog::level::level_enum spdlog::logger::level() const
{
return static_cast<spdlog::level::level_enum>(_level.load(std::memory_order_relaxed));
......@@ -314,23 +325,13 @@ inline void spdlog::logger::_sink_it(details::log_msg &msg)
}
}
if (_should_flush_on(msg))
if (_should_flush(msg))
{
flush();
}
}
inline void spdlog::logger::_set_pattern(const std::string &pattern, pattern_time_type pattern_time)
{
_formatter = std::make_shared<pattern_formatter>(pattern, pattern_time);
}
inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter)
{
_formatter = std::move(msg_formatter);
}
inline void spdlog::logger::flush()
inline void spdlog::logger::_flush()
{
for (auto &sink : _sinks)
{
......@@ -345,19 +346,11 @@ inline void spdlog::logger::_default_err_handler(const std::string &msg)
{
return;
}
_last_err_time = now;
auto tm_time = details::os::localtime(now);
char date_buf[100];
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
details::log_msg err_msg;
err_msg.formatted.write("[*** LOG ERROR ***] [{}] [{}] [{}]{}", name(), msg, date_buf, details::os::default_eol);
sinks::stderr_sink_mt::instance()->log(err_msg);
_last_err_time = now;
}
inline bool spdlog::logger::_should_flush_on(const details::log_msg &msg)
{
const auto flush_level = _flush_level.load(std::memory_order_relaxed);
return (msg.level >= flush_level) && (msg.level != level::off);
fmt::print(stderr, "[*** LOG ERROR ***] [{}] [{}] {}\n", date_buf, name(), msg);
}
inline void spdlog::logger::_incr_msg_counter(details::log_msg &msg)
......
......@@ -10,86 +10,41 @@
// If user requests a non existing logger, nullptr will be returned
// This class is thread safe
#include "../async_logger.h"
#include "../common.h"
#include "../details/null_mutex.h"
#include "../logger.h"
#include <chrono>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
namespace spdlog {
namespace details {
class thread_pool;
template<class Mutex>
class registry_t
{
public:
using MutexT = Mutex;
registry_t<Mutex>(const registry_t<Mutex> &) = delete;
registry_t<Mutex> &operator=(const registry_t<Mutex> &) = delete;
void register_logger(std::shared_ptr<logger> logger)
{
std::lock_guard<Mutex> lock(_mutex);
auto logger_name = logger->name();
throw_if_exists(logger_name);
_loggers[logger_name] = logger;
}
std::shared_ptr<logger> get(const std::string &logger_name)
{
std::lock_guard<Mutex> lock(_mutex);
auto found = _loggers.find(logger_name);
return found == _loggers.end() ? nullptr : found->second;
}
template<class It>
std::shared_ptr<logger> create(const std::string &logger_name, const It &sinks_begin, const It &sinks_end)
void register_logger(std::shared_ptr<logger> new_logger)
{
std::lock_guard<Mutex> lock(_mutex);
auto logger_name = new_logger->name();
throw_if_exists(logger_name);
std::shared_ptr<logger> new_logger;
if (_async_mode)
{
new_logger = std::make_shared<async_logger>(logger_name, sinks_begin, sinks_end, _async_q_size, _overflow_policy,
_worker_warmup_cb, _flush_interval_ms, _worker_teardown_cb);
}
else
{
new_logger = std::make_shared<logger>(logger_name, sinks_begin, sinks_end);
}
if (_formatter)
{
new_logger->set_formatter(_formatter);
}
if (_err_handler)
{
new_logger->set_error_handler(_err_handler);
}
new_logger->set_level(_level);
new_logger->flush_on(_flush_level);
// Add to registry
_loggers[logger_name] = new_logger;
return new_logger;
}
template<class It>
std::shared_ptr<async_logger> create_async(const std::string &logger_name, size_t queue_size,
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb, const It &sinks_begin,
const It &sinks_end)
void register_and_init(std::shared_ptr<logger> new_logger)
{
std::lock_guard<Mutex> lock(_mutex);
auto logger_name = new_logger->name();
throw_if_exists(logger_name);
auto new_logger = std::make_shared<async_logger>(
logger_name, sinks_begin, sinks_end, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb);
if (_formatter)
{
......@@ -106,56 +61,28 @@ public:
// Add to registry
_loggers[logger_name] = new_logger;
return new_logger;
}
void apply_all(std::function<void(std::shared_ptr<logger>)> fun)
std::shared_ptr<logger> get(const std::string &logger_name)
{
std::lock_guard<Mutex> lock(_mutex);
for (auto &l : _loggers)
{
fun(l.second);
}
auto found = _loggers.find(logger_name);
return found == _loggers.end() ? nullptr : found->second;
}
void drop(const std::string &logger_name)
void set_thread_pool(std::shared_ptr<thread_pool> tp)
{
std::lock_guard<Mutex> lock(_mutex);
_loggers.erase(logger_name);
_tp = std::move(tp);
}
void drop_all()
std::shared_ptr<thread_pool> get_thread_pool()
{
std::lock_guard<Mutex> lock(_mutex);
_loggers.clear();
}
std::shared_ptr<logger> create(const std::string &logger_name, sinks_init_list sinks)
{
return create(logger_name, sinks.begin(), sinks.end());
}
std::shared_ptr<logger> create(const std::string &logger_name, sink_ptr sink)
{
return create(logger_name, {sink});
}
std::shared_ptr<async_logger> create_async(const std::string &logger_name, size_t queue_size,
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb, sinks_init_list sinks)
{
return create_async(
logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks.begin(), sinks.end());
}
std::shared_ptr<async_logger> create_async(const std::string &logger_name, size_t queue_size,
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb, sink_ptr sink)
{
return create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, {sink});
return _tp;
}
void formatter(formatter_ptr f)
void set_formatter(formatter_ptr f)
{
std::lock_guard<Mutex> lock(_mutex);
_formatter = f;
......@@ -204,22 +131,30 @@ public:
_err_handler = handler;
}
void set_async_mode(size_t q_size, const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
void apply_all(std::function<void(std::shared_ptr<logger>)> fun)
{
std::lock_guard<Mutex> lock(_mutex);
_async_mode = true;
_async_q_size = q_size;
_overflow_policy = overflow_policy;
_worker_warmup_cb = worker_warmup_cb;
_flush_interval_ms = flush_interval_ms;
_worker_teardown_cb = worker_teardown_cb;
for (auto &l : _loggers)
{
fun(l.second);
}
}
void set_sync_mode()
void drop(const std::string &logger_name)
{
std::lock_guard<Mutex> lock(_mutex);
_async_mode = false;
_loggers.erase(logger_name);
}
void drop_all()
{
std::lock_guard<Mutex> lock(_mutex);
_loggers.clear();
}
Mutex &tp_mutex()
{
return _tp_mutex;
}
static registry_t<Mutex> &instance()
......@@ -240,24 +175,22 @@ private:
}
Mutex _mutex;
Mutex _tp_mutex;
std::unordered_map<std::string, std::shared_ptr<logger>> _loggers;
formatter_ptr _formatter;
level::level_enum _level = level::info;
level::level_enum _flush_level = level::off;
log_err_handler _err_handler;
bool _async_mode = false;
size_t _async_q_size = 0;
async_overflow_policy _overflow_policy = async_overflow_policy::block_retry;
std::function<void()> _worker_warmup_cb;
std::chrono::milliseconds _flush_interval_ms{std::chrono::milliseconds::zero()};
std::function<void()> _worker_teardown_cb;
std::shared_ptr<thread_pool> _tp;
};
#ifdef SPDLOG_NO_REGISTRY_MUTEX
#include "../details/null_mutex.h"
using registry = registry_t<spdlog::details::null_mutex>;
#else
#include <mutex>
using registry = registry_t<std::mutex>;
#endif
} // namespace details
} // namespace spdlog
} // namespace spdlog
\ No newline at end of file
This diff is collapsed.
......@@ -785,7 +785,7 @@ inline typename MakeUnsigned<Int>::Type to_unsigned(Int value)
// to avoid dynamic memory allocation.
enum
{
INLINE_BUFFER_SIZE = 500
INLINE_BUFFER_SIZE = 500 // TODO reduce to 250
};
#if FMT_SECURE_SCL
......
//
// Copyright(c) 2015 Gabi Melman.
// Copyright(c) 2015-2108 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
......@@ -113,27 +113,23 @@ public:
void set_pattern(const std::string &pattern, pattern_time_type pattern_time = pattern_time_type::local);
void set_formatter(formatter_ptr msg_formatter);
// automatically call flush() if message level >= log_level
void flush();
void flush_on(level::level_enum log_level);
virtual void flush();
const std::vector<sink_ptr> &sinks() const;
// error handler
virtual void set_error_handler(log_err_handler err_handler);
virtual log_err_handler error_handler();
void set_error_handler(log_err_handler err_handler);
log_err_handler error_handler();
protected:
virtual void _sink_it(details::log_msg &msg);
virtual void _set_pattern(const std::string &pattern, pattern_time_type pattern_time);
virtual void _set_formatter(formatter_ptr msg_formatter);
virtual void _flush();
// default error handler: print the error to stderr with the max rate of 1 message/minute
virtual void _default_err_handler(const std::string &msg);
bool _should_flush(const details::log_msg &msg);
// return true if the given message level should trigger a flush
bool _should_flush_on(const details::log_msg &msg);
// default error handler: print the error to stderr with the max rate of 1 message/minute
void _default_err_handler(const std::string &msg);
// increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER))
void _incr_msg_counter(details::log_msg &msg);
......
......@@ -94,7 +94,7 @@ protected:
// after color range
_print_range(msg, msg.color_range_end, msg.formatted.size());
}
else
else // no color
{
_print_range(msg, 0, msg.formatted.size());
}
......
......@@ -23,12 +23,6 @@ class stdout_sink SPDLOG_FINAL : public base_sink<Mutex>
public:
explicit stdout_sink() = default;
static std::shared_ptr<MyType> instance()
{
static std::shared_ptr<MyType> instance = std::make_shared<MyType>();
return instance;
}
protected:
void _sink_it(const details::log_msg &msg) override
{
......@@ -53,12 +47,6 @@ class stderr_sink SPDLOG_FINAL : public base_sink<Mutex>
public:
explicit stderr_sink() = default;
static std::shared_ptr<MyType> instance()
{
static std::shared_ptr<MyType> instance = std::make_shared<MyType>();
return instance;
}
protected:
void _sink_it(const details::log_msg &msg) override
{
......
This diff is collapsed.
......@@ -67,10 +67,11 @@ TEST_CASE("async_error_handler", "[errors]]")
{
prepare_logdir();
std::string err_msg("log failed with some msg");
spdlog::set_async_mode(128);
std::string filename = "logs/simple_async_log.txt";
{
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
spdlog::init_thread_pool(128, 1);
auto logger = spdlog::create_as<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
logger->set_error_handler([=](const std::string &msg) {
std::ofstream ofs("logs/custom_err.txt");
if (!ofs)
......@@ -85,8 +86,8 @@ TEST_CASE("async_error_handler", "[errors]]")
#endif
logger->info("Good message #2");
spdlog::drop("logger"); // force logger to drain the queue and shutdown
spdlog::set_sync_mode();
}
spdlog::init_thread_pool(128, 1);
REQUIRE(count_lines(filename) == 2);
REQUIRE(file_contents("logs/custom_err.txt") == err_msg);
}
......@@ -96,9 +97,9 @@ TEST_CASE("async_error_handler2", "[errors]]")
{
prepare_logdir();
std::string err_msg("This is async handler error message");
spdlog::set_async_mode(128);
{
auto logger = spdlog::create<failing_sink>("failed_logger");
spdlog::init_thread_pool(128, 1);
auto logger = spdlog::create_as<failing_sink>("failed_logger");
logger->set_error_handler([=](const std::string &msg) {
std::ofstream ofs("logs/custom_err2.txt");
if (!ofs)
......@@ -107,8 +108,8 @@ TEST_CASE("async_error_handler2", "[errors]]")
});
logger->info("Hello failure");
spdlog::drop("failed_logger"); // force logger to drain the queue and shutdown
spdlog::set_sync_mode();
}
spdlog::init_thread_pool(128, 1);
REQUIRE(file_contents("logs/custom_err2.txt") == err_msg);
}
......@@ -12,6 +12,7 @@
#define SPDLOG_TRACE_ON
#define SPDLOG_DEBUG_ON
#include "../include/spdlog/async.h"
#include "../include/spdlog/sinks/null_sink.h"
#include "../include/spdlog/sinks/ostream_sink.h"
#include "../include/spdlog/spdlog.h"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment