spdlog/include/spdlog/details/registry.h

264 lines
7.9 KiB
C
Raw Normal View History

2016-04-20 04:57:49 -04:00
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
// Loggers registy of unique name->logger pointer
// An attempt to create a logger with an already existing name will be ignored
// If user requests a non existing logger, nullptr will be returned
// This class is thread safe
#include "../async_logger.h"
#include "../common.h"
2018-03-09 08:26:33 -05:00
#include "../details/null_mutex.h"
#include "../logger.h"
2016-04-20 04:57:49 -04:00
#include <chrono>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
2018-03-17 06:47:46 -04:00
namespace spdlog {
namespace details {
2018-03-16 11:35:56 -04:00
template<class Mutex>
class registry_t
2016-04-20 04:57:49 -04:00
{
public:
2018-03-09 08:26:33 -05:00
registry_t<Mutex>(const registry_t<Mutex> &) = delete;
registry_t<Mutex> &operator=(const registry_t<Mutex> &) = delete;
2016-04-20 04:57:49 -04:00
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;
}
2018-03-09 08:26:33 -05:00
std::shared_ptr<logger> get(const std::string &logger_name)
2016-04-20 04:57:49 -04:00
{
std::lock_guard<Mutex> lock(_mutex);
auto found = _loggers.find(logger_name);
return found == _loggers.end() ? nullptr : found->second;
}
2018-03-16 11:35:56 -04:00
template<class It>
std::shared_ptr<logger> create(const std::string &logger_name, const It &sinks_begin, const It &sinks_end)
2016-04-20 04:57:49 -04:00
{
std::lock_guard<Mutex> lock(_mutex);
throw_if_exists(logger_name);
std::shared_ptr<logger> new_logger;
if (_async_mode)
{
2018-03-09 08:26:33 -05:00
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);
}
2016-04-20 04:57:49 -04:00
else
{
2016-04-20 04:57:49 -04:00
new_logger = std::make_shared<logger>(logger_name, sinks_begin, sinks_end);
}
2016-04-20 04:57:49 -04:00
if (_formatter)
{
2016-04-20 04:57:49 -04:00
new_logger->set_formatter(_formatter);
}
2016-04-20 04:57:49 -04:00
2016-08-04 21:43:20 -04:00
if (_err_handler)
{
2016-08-04 21:43:20 -04:00
new_logger->set_error_handler(_err_handler);
}
2016-08-04 20:56:40 -04:00
2016-04-20 04:57:49 -04:00
new_logger->set_level(_level);
2018-01-03 10:19:56 -05:00
new_logger->flush_on(_flush_level);
2016-08-04 20:56:40 -04:00
2018-03-09 08:26:33 -05:00
// Add to registry
2016-04-20 04:57:49 -04:00
_loggers[logger_name] = new_logger;
return new_logger;
}
2018-03-16 11:13:50 -04:00
template<class It>
2018-03-09 08:26:33 -05:00
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)
{
std::lock_guard<Mutex> lock(_mutex);
throw_if_exists(logger_name);
2018-03-09 08:26:33 -05:00
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)
{
new_logger->set_formatter(_formatter);
}
if (_err_handler)
{
new_logger->set_error_handler(_err_handler);
}
new_logger->set_level(_level);
2018-01-03 10:19:56 -05:00
new_logger->flush_on(_flush_level);
2018-03-09 08:26:33 -05:00
// Add to registry
_loggers[logger_name] = new_logger;
return new_logger;
}
2016-08-20 06:55:50 -04:00
void apply_all(std::function<void(std::shared_ptr<logger>)> fun)
{
std::lock_guard<Mutex> lock(_mutex);
for (auto &l : _loggers)
{
2016-08-20 06:55:50 -04:00
fun(l.second);
}
2016-08-20 06:55:50 -04:00
}
2018-03-09 08:26:33 -05:00
void drop(const std::string &logger_name)
2016-04-20 04:57:49 -04:00
{
std::lock_guard<Mutex> lock(_mutex);
_loggers.erase(logger_name);
}
void drop_all()
{
std::lock_guard<Mutex> lock(_mutex);
_loggers.clear();
}
2018-02-24 19:40:46 -05:00
2018-03-09 08:26:33 -05:00
std::shared_ptr<logger> create(const std::string &logger_name, sinks_init_list sinks)
2016-04-20 04:57:49 -04:00
{
return create(logger_name, sinks.begin(), sinks.end());
}
2018-03-09 08:26:33 -05:00
std::shared_ptr<logger> create(const std::string &logger_name, sink_ptr sink)
2016-04-20 04:57:49 -04:00
{
2018-03-09 08:26:33 -05:00
return create(logger_name, {sink});
2016-04-20 04:57:49 -04:00
}
2018-03-09 08:26:33 -05:00
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)
{
2018-03-09 08:26:33 -05:00
return create_async(
logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks.begin(), sinks.end());
}
2018-03-09 08:26:33 -05:00
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)
{
2018-03-09 08:26:33 -05:00
return create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, {sink});
}
2016-04-20 04:57:49 -04:00
void formatter(formatter_ptr f)
{
std::lock_guard<Mutex> lock(_mutex);
_formatter = f;
2018-03-09 08:26:33 -05:00
for (auto &l : _loggers)
{
2016-04-20 04:57:49 -04:00
l.second->set_formatter(_formatter);
}
2016-04-20 04:57:49 -04:00
}
2018-03-09 08:26:33 -05:00
void set_pattern(const std::string &pattern)
2016-04-20 04:57:49 -04:00
{
std::lock_guard<Mutex> lock(_mutex);
_formatter = std::make_shared<pattern_formatter>(pattern);
2018-03-09 08:26:33 -05:00
for (auto &l : _loggers)
{
2016-04-20 04:57:49 -04:00
l.second->set_formatter(_formatter);
}
2016-04-20 04:57:49 -04:00
}
void set_level(level::level_enum log_level)
{
std::lock_guard<Mutex> lock(_mutex);
2018-03-09 08:26:33 -05:00
for (auto &l : _loggers)
{
2016-04-20 04:57:49 -04:00
l.second->set_level(log_level);
}
2016-04-20 04:57:49 -04:00
_level = log_level;
}
2018-01-03 10:19:56 -05:00
void flush_on(level::level_enum log_level)
{
std::lock_guard<Mutex> lock(_mutex);
2018-03-09 08:26:33 -05:00
for (auto &l : _loggers)
{
2018-01-03 10:19:56 -05:00
l.second->flush_on(log_level);
}
2018-01-03 10:19:56 -05:00
_flush_level = log_level;
}
2016-08-04 21:43:20 -04:00
void set_error_handler(log_err_handler handler)
{
2018-03-09 08:26:33 -05:00
for (auto &l : _loggers)
{
2016-08-04 21:43:20 -04:00
l.second->set_error_handler(handler);
}
2016-08-04 21:43:20 -04:00
_err_handler = handler;
}
2016-08-04 20:56:40 -04:00
2018-03-09 08:26:33 -05:00
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)
2016-04-20 04:57:49 -04:00
{
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;
2016-04-20 04:57:49 -04:00
}
void set_sync_mode()
{
std::lock_guard<Mutex> lock(_mutex);
_async_mode = false;
}
2018-03-09 08:26:33 -05:00
static registry_t<Mutex> &instance()
2016-04-20 04:57:49 -04:00
{
static registry_t<Mutex> s_instance;
return s_instance;
}
private:
2018-02-24 19:25:15 -05:00
registry_t<Mutex>() = default;
2016-04-20 04:57:49 -04:00
void throw_if_exists(const std::string &logger_name)
{
if (_loggers.find(logger_name) != _loggers.end())
{
2016-04-20 04:57:49 -04:00
throw spdlog_ex("logger with name '" + logger_name + "' already exists");
}
2016-04-20 04:57:49 -04:00
}
2018-02-24 19:25:15 -05:00
2016-04-20 04:57:49 -04:00
Mutex _mutex;
2018-03-09 08:26:33 -05:00
std::unordered_map<std::string, std::shared_ptr<logger>> _loggers;
2016-04-20 04:57:49 -04:00
formatter_ptr _formatter;
level::level_enum _level = level::info;
2018-01-03 10:19:56 -05:00
level::level_enum _flush_level = level::off;
2016-08-04 21:43:20 -04:00
log_err_handler _err_handler;
2016-04-20 04:57:49 -04:00
bool _async_mode = false;
size_t _async_q_size = 0;
async_overflow_policy _overflow_policy = async_overflow_policy::block_retry;
2018-02-24 20:43:26 -05:00
std::function<void()> _worker_warmup_cb;
std::chrono::milliseconds _flush_interval_ms{std::chrono::milliseconds::zero()};
2018-02-24 20:43:26 -05:00
std::function<void()> _worker_teardown_cb;
2016-04-20 04:57:49 -04:00
};
2018-02-24 16:35:09 -05:00
2016-04-20 04:57:49 -04:00
#ifdef SPDLOG_NO_REGISTRY_MUTEX
2018-02-24 16:35:09 -05:00
using registry = registry_t<spdlog::details::null_mutex>;
2016-04-20 04:57:49 -04:00
#else
2018-02-24 16:35:09 -05:00
using registry = registry_t<std::mutex>;
2016-04-20 04:57:49 -04:00
#endif
2018-02-24 16:35:09 -05:00
2018-03-17 06:47:46 -04:00
} // namespace details
} // namespace spdlog