Commit ea3476cf authored by gabime's avatar gabime

Removed registry and backtracer

parent c716aa2e
...@@ -29,6 +29,8 @@ void custom_flags_example(); ...@@ -29,6 +29,8 @@ void custom_flags_example();
#include "spdlog/cfg/env.h" // support for loading levels from the environment variable #include "spdlog/cfg/env.h" // support for loading levels from the environment variable
#include "spdlog/fmt/ostr.h" // support for user defined types #include "spdlog/fmt/ostr.h" // support for user defined types
using spdlog::details::make_unique; // for pre c++14
int main(int, char *[]) int main(int, char *[])
{ {
// Log levels can be loaded from argv/env using "SPDLOG_LEVEL" // Log levels can be loaded from argv/env using "SPDLOG_LEVEL"
...@@ -43,28 +45,16 @@ int main(int, char *[]) ...@@ -43,28 +45,16 @@ int main(int, char *[])
spdlog::info("{:>8} aligned, {:<8} aligned", "right", "left"); spdlog::info("{:>8} aligned, {:<8} aligned", "right", "left");
// Runtime log levels // Runtime log levels
spdlog::set_level(spdlog::level::info); // Set global log level to info spdlog::default_logger()->set_level(spdlog::level::info); // Set global log level to info
spdlog::debug("This message should not be displayed!"); spdlog::debug("This message should not be displayed!");
spdlog::set_level(spdlog::level::trace); // Set specific logger's log level spdlog::default_logger()->set_level(spdlog::level::trace); // Set specific logger's log level
spdlog::debug("This message should be displayed.."); spdlog::debug("This message should be displayed..");
// Customize msg format for all loggers // Customize msg format
spdlog::set_pattern("[%H:%M:%S %z] [%^%L%$] [thread %t] %v"); spdlog::default_logger()->set_formatter(make_unique<spdlog::pattern_formatter>("[%H:%M:%S %z] [%^%L%$] [thread %t] %v"));
spdlog::info("This an info message with custom format"); spdlog::info("This an info message with custom format");
using spdlog::details::make_unique; // for pre c++14 spdlog::default_logger()->set_formatter(make_unique<spdlog::default_formatter>()); // back to default format
spdlog::set_formatter(make_unique<spdlog::default_formatter>()); // back to default format spdlog::default_logger()->set_level(spdlog::level::info);
spdlog::set_level(spdlog::level::info);
// Backtrace support
// Loggers can store in a ring buffer all messages (including debug/trace) for later inspection.
// When needed, call dump_backtrace() to see what happened:
spdlog::enable_backtrace(10); // create ring buffer with capacity of 10 messages
for (int i = 0; i < 100; i++)
{
spdlog::debug("Backtrace message {}", i); // not logged..
}
// e.g. if some error happened:
spdlog::dump_backtrace(); // log them now!
try try
{ {
...@@ -82,13 +72,6 @@ int main(int, char *[]) ...@@ -82,13 +72,6 @@ int main(int, char *[])
udp_example(); udp_example();
custom_flags_example(); custom_flags_example();
// Flush all *registered* loggers using a worker thread every 3 seconds.
// note: registered loggers *must* be thread safe for this to work correctly!
spdlog::flush_every(std::chrono::seconds(3));
// Apply some function on all registered loggers
spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) { l->info("End of example."); });
// Release all spdlog resources, and drop all loggers in the registry. // Release all spdlog resources, and drop all loggers in the registry.
// This is optional (only mandatory if using windows + async log). // This is optional (only mandatory if using windows + async log).
spdlog::shutdown(); spdlog::shutdown();
...@@ -197,8 +180,8 @@ void trace_example() ...@@ -197,8 +180,8 @@ void trace_example()
SPDLOG_DEBUG("Some debug message.. {} ,{}", 1, 3.23); SPDLOG_DEBUG("Some debug message.. {} ,{}", 1, 3.23);
// trace from logger object // trace from logger object
auto logger = spdlog::get("file_logger"); auto some_logger = spdlog::stdout_color_mt("console");
SPDLOG_LOGGER_TRACE(logger, "another trace message"); SPDLOG_LOGGER_TRACE(some_logger, "another trace message");
} }
// stopwatch example // stopwatch example
...@@ -223,7 +206,6 @@ void udp_example() ...@@ -223,7 +206,6 @@ void udp_example()
// A logger with multiple sinks (stdout and file) - each with a different format and log level. // A logger with multiple sinks (stdout and file) - each with a different format and log level.
void multi_sink_example() void multi_sink_example()
{ {
using spdlog::details::make_unique; // for pre c++14
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>(); auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::warn); console_sink->set_level(spdlog::level::warn);
console_sink->set_formatter(make_unique<spdlog::pattern_formatter>("[multi_sink_example] [%^%l%$] %v")); console_sink->set_formatter(make_unique<spdlog::pattern_formatter>("[multi_sink_example] [%^%l%$] %v"));
...@@ -257,7 +239,7 @@ void user_defined_example() ...@@ -257,7 +239,7 @@ void user_defined_example()
void err_handler_example() void err_handler_example()
{ {
// can be set globally or per logger(logger->set_error_handler(..)) // can be set globally or per logger(logger->set_error_handler(..))
spdlog::set_error_handler([](const std::string &msg) { printf("*** Custom log error handler: %s ***\n", msg.c_str()); }); spdlog::default_logger()->set_error_handler([](const std::string &msg) { printf("*** Custom log error handler: %s ***\n", msg.c_str()); });
} }
// syslog example (linux/osx/freebsd) // syslog example (linux/osx/freebsd)
...@@ -302,9 +284,7 @@ public: ...@@ -302,9 +284,7 @@ public:
void custom_flags_example() void custom_flags_example()
{ {
using spdlog::details::make_unique; // for pre c++14
auto formatter = make_unique<spdlog::pattern_formatter>(""); auto formatter = make_unique<spdlog::pattern_formatter>("");
formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v"); formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v");
spdlog::set_formatter(std::move(formatter)); spdlog::default_logger()->set_formatter(std::move(formatter));
} }
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
// originating logger. // originating logger.
#include <spdlog/async_logger.h> #include <spdlog/async_logger.h>
#include <spdlog/details/registry.h>
#include <spdlog/details/thread_pool.h> #include <spdlog/details/thread_pool.h>
#include <memory> #include <memory>
...@@ -26,6 +25,8 @@ namespace spdlog { ...@@ -26,6 +25,8 @@ namespace spdlog {
namespace details { namespace details {
static const size_t default_async_q_size = 8192; static const size_t default_async_q_size = 8192;
static std::shared_ptr<thread_pool> s_thread_pool;
static std::recursive_mutex s_thread_pool_mutex;
} }
// async logger factory - creates async loggers backed with thread pool. // async logger factory - creates async loggers backed with thread pool.
...@@ -37,22 +38,17 @@ struct async_factory_impl ...@@ -37,22 +38,17 @@ struct async_factory_impl
template<typename Sink, typename... SinkArgs> template<typename Sink, typename... SinkArgs>
static std::shared_ptr<async_logger> create(std::string logger_name, SinkArgs &&...args) static std::shared_ptr<async_logger> create(std::string logger_name, SinkArgs &&...args)
{ {
auto &registry_inst = details::registry::instance();
// create global thread pool if not already exists.. // create global thread pool if not already exists..
auto &mutex = registry_inst.tp_mutex(); std::lock_guard<std::recursive_mutex> tp_lock(details::s_thread_pool_mutex);
std::lock_guard<std::recursive_mutex> tp_lock(mutex);
auto tp = registry_inst.get_tp(); if (!details::s_thread_pool)
if (tp == nullptr)
{ {
tp = std::make_shared<details::thread_pool>(details::default_async_q_size, 1U); details::s_thread_pool = std::make_shared<details::thread_pool>(details::default_async_q_size, 1U);
registry_inst.set_tp(tp);
}
}
auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...); auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
auto new_logger = std::make_shared<async_logger>(std::move(logger_name), std::move(sink), std::move(tp), OverflowPolicy); auto new_logger = std::make_shared<async_logger>(std::move(logger_name), std::move(sink), std::move(details::s_thread_pool), OverflowPolicy);
registry_inst.initialize_logger(new_logger);
return new_logger; return new_logger;
} }
}; };
...@@ -76,7 +72,7 @@ inline std::shared_ptr<spdlog::logger> create_async_nb(std::string logger_name, ...@@ -76,7 +72,7 @@ inline std::shared_ptr<spdlog::logger> create_async_nb(std::string logger_name,
inline void init_thread_pool(size_t q_size, size_t thread_count, std::function<void()> on_thread_start) inline void init_thread_pool(size_t q_size, size_t thread_count, std::function<void()> on_thread_start)
{ {
auto tp = std::make_shared<details::thread_pool>(q_size, thread_count, on_thread_start); auto tp = std::make_shared<details::thread_pool>(q_size, thread_count, on_thread_start);
details::registry::instance().set_tp(std::move(tp)); details::s_thread_pool = std::move(tp);
} }
// set global thread pool. // set global thread pool.
...@@ -88,6 +84,6 @@ inline void init_thread_pool(size_t q_size, size_t thread_count) ...@@ -88,6 +84,6 @@ inline void init_thread_pool(size_t q_size, size_t thread_count)
// get the global thread pool. // get the global thread pool.
inline std::shared_ptr<spdlog::details::thread_pool> thread_pool() inline std::shared_ptr<spdlog::details::thread_pool> thread_pool()
{ {
return details::registry::instance().get_tp(); return details::s_thread_pool;
} }
} // namespace spdlog } // namespace spdlog
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
#pragma once #pragma once
#include <spdlog/cfg/helpers.h> #include <spdlog/cfg/helpers.h>
#include <spdlog/details/registry.h>
#include <spdlog/details/os.h> #include <spdlog/details/os.h>
// //
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <spdlog/details/os.h> #include <spdlog/details/os.h>
#include <spdlog/details/registry.h>
#include <algorithm> #include <algorithm>
#include <string> #include <string>
...@@ -112,7 +111,8 @@ SPDLOG_INLINE void load_levels(const std::string &input) ...@@ -112,7 +111,8 @@ SPDLOG_INLINE void load_levels(const std::string &input)
} }
} }
details::registry::instance().set_levels(std::move(levels), global_level_found ? &global_level : nullptr); // TODO what to do here with registry?
//details::registry::instance().set_levels(std::move(levels), global_level_found ? &global_level : nullptr);
} }
} // namespace helpers } // namespace helpers
......
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#ifndef SPDLOG_HEADER_ONLY
# include <spdlog/details/backtracer.h>
#endif
namespace spdlog {
namespace details {
SPDLOG_INLINE backtracer::backtracer(const backtracer &other)
{
std::lock_guard<std::mutex> lock(other.mutex_);
enabled_ = other.enabled();
messages_ = other.messages_;
}
SPDLOG_INLINE backtracer::backtracer(backtracer &&other) SPDLOG_NOEXCEPT
{
std::lock_guard<std::mutex> lock(other.mutex_);
enabled_ = other.enabled();
messages_ = std::move(other.messages_);
}
SPDLOG_INLINE backtracer &backtracer::operator=(backtracer other)
{
std::lock_guard<std::mutex> lock(mutex_);
enabled_ = other.enabled();
messages_ = std::move(other.messages_);
return *this;
}
SPDLOG_INLINE void backtracer::enable(size_t size)
{
std::lock_guard<std::mutex> lock{mutex_};
enabled_.store(true, std::memory_order_relaxed);
messages_ = circular_q<log_msg_buffer>{size};
}
SPDLOG_INLINE void backtracer::disable()
{
std::lock_guard<std::mutex> lock{mutex_};
enabled_.store(false, std::memory_order_relaxed);
}
SPDLOG_INLINE bool backtracer::enabled() const
{
return enabled_.load(std::memory_order_relaxed);
}
SPDLOG_INLINE void backtracer::push_back(const log_msg &msg)
{
std::lock_guard<std::mutex> lock{mutex_};
messages_.push_back(log_msg_buffer{msg});
}
// pop all items in the q and apply the given fun on each of them.
SPDLOG_INLINE void backtracer::foreach_pop(std::function<void(const details::log_msg &)> fun)
{
std::lock_guard<std::mutex> lock{mutex_};
while (!messages_.empty())
{
auto &front_msg = messages_.front();
fun(front_msg);
messages_.pop_front();
}
}
} // namespace details
} // namespace spdlog
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#include <spdlog/details/log_msg_buffer.h>
#include <spdlog/details/circular_q.h>
#include <atomic>
#include <mutex>
#include <functional>
// Store log messages in circular buffer.
// Useful for storing debug data in case of error/warning happens.
namespace spdlog {
namespace details {
class SPDLOG_API backtracer
{
mutable std::mutex mutex_;
std::atomic<bool> enabled_{false};
circular_q<log_msg_buffer> messages_;
public:
backtracer() = default;
backtracer(const backtracer &other);
backtracer(backtracer &&other) SPDLOG_NOEXCEPT;
backtracer &operator=(backtracer other);
void enable(size_t size);
void disable();
bool enabled() const;
void push_back(const log_msg &msg);
// pop all items in the q and apply the given fun on each of them.
void foreach_pop(std::function<void(const details::log_msg &)> fun);
};
} // namespace details
} // namespace spdlog
#ifdef SPDLOG_HEADER_ONLY
# include "backtracer-inl.h"
#endif
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#ifndef SPDLOG_HEADER_ONLY
# include <spdlog/details/registry.h>
#endif
#include <spdlog/common.h>
#include <spdlog/details/periodic_worker.h>
#include <spdlog/logger.h>
#include <spdlog/default_formatter.h>
#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
// support for the default stdout color logger
# ifdef _WIN32
# include <spdlog/sinks/wincolor_sink.h>
# else
# include <spdlog/sinks/ansicolor_sink.h>
# endif
#endif // SPDLOG_DISABLE_DEFAULT_LOGGER
#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
namespace spdlog {
namespace details {
SPDLOG_INLINE registry::registry()
: formatter_(new default_formatter())
{
#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
// create default logger (ansicolor_stdout_sink_mt or wincolor_stdout_sink_mt in windows).
# ifdef _WIN32
auto color_sink = std::make_shared<sinks::wincolor_stdout_sink_mt>();
# else
auto color_sink = std::make_shared<sinks::ansicolor_stdout_sink_mt>();
# endif
const char *default_logger_name = "";
default_logger_ = std::make_shared<spdlog::logger>(default_logger_name, std::move(color_sink));
loggers_[default_logger_name] = default_logger_;
#endif // SPDLOG_DISABLE_DEFAULT_LOGGER
}
SPDLOG_INLINE registry::~registry() = default;
SPDLOG_INLINE void registry::register_logger(std::shared_ptr<logger> new_logger)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
register_logger_(std::move(new_logger));
}
SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr<logger> new_logger)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
new_logger->set_formatter(formatter_->clone());
if (err_handler_)
{
new_logger->set_error_handler(err_handler_);
}
// set new level according to previously configured level or default level
auto it = log_levels_.find(new_logger->name());
auto new_level = it != log_levels_.end() ? it->second : global_log_level_;
new_logger->set_level(new_level);
new_logger->flush_on(flush_level_);
if (backtrace_n_messages_ > 0)
{
new_logger->enable_backtrace(backtrace_n_messages_);
}
if (automatic_registration_)
{
register_logger_(std::move(new_logger));
}
}
SPDLOG_INLINE std::shared_ptr<logger> registry::get(const std::string &logger_name)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
auto found = loggers_.find(logger_name);
return found == loggers_.end() ? nullptr : found->second;
}
SPDLOG_INLINE std::shared_ptr<logger> registry::default_logger()
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
return default_logger_;
}
// Return raw ptr to the default logger.
// To be used directly by the spdlog default api (e.g. spdlog::info)
// This make the default API faster, but cannot be used concurrently with set_default_logger().
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
SPDLOG_INLINE logger *registry::get_default_raw()
{
return default_logger_.get();
}
// set default logger.
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
SPDLOG_INLINE void registry::set_default_logger(std::shared_ptr<logger> new_default_logger)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
// remove previous default logger from the map
if (default_logger_ != nullptr)
{
loggers_.erase(default_logger_->name());
}
if (new_default_logger != nullptr)
{
loggers_[new_default_logger->name()] = new_default_logger;
}
default_logger_ = std::move(new_default_logger);
}
SPDLOG_INLINE void registry::set_tp(std::shared_ptr<thread_pool> tp)
{
std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
tp_ = std::move(tp);
}
SPDLOG_INLINE std::shared_ptr<thread_pool> registry::get_tp()
{
std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
return tp_;
}
// Set global formatter. Each sink in each logger will get a clone of this object
SPDLOG_INLINE void registry::set_formatter(std::unique_ptr<formatter> formatter)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
formatter_ = std::move(formatter);
for (auto &l : loggers_)
{
l.second->set_formatter(formatter_->clone());
}
}
SPDLOG_INLINE void registry::enable_backtrace(size_t n_messages)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
backtrace_n_messages_ = n_messages;
for (auto &l : loggers_)
{
l.second->enable_backtrace(n_messages);
}
}
SPDLOG_INLINE void registry::disable_backtrace()
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
backtrace_n_messages_ = 0;
for (auto &l : loggers_)
{
l.second->disable_backtrace();
}
}
SPDLOG_INLINE void registry::set_level(level::level_enum log_level)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
for (auto &l : loggers_)
{
l.second->set_level(log_level);
}
global_log_level_ = log_level;
}
SPDLOG_INLINE void registry::flush_on(level::level_enum log_level)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
for (auto &l : loggers_)
{
l.second->flush_on(log_level);
}
flush_level_ = log_level;
}
SPDLOG_INLINE void registry::flush_every(std::chrono::seconds interval)
{
std::lock_guard<std::mutex> lock(flusher_mutex_);
auto clbk = [this]() { this->flush_all(); };
periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
}
SPDLOG_INLINE void registry::set_error_handler(err_handler handler)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
for (auto &l : loggers_)
{
l.second->set_error_handler(handler);
}
err_handler_ = std::move(handler);
}
SPDLOG_INLINE void registry::apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
for (auto &l : loggers_)
{
fun(l.second);
}
}
SPDLOG_INLINE void registry::flush_all()
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
for (auto &l : loggers_)
{
l.second->flush();
}
}
SPDLOG_INLINE void registry::drop(const std::string &logger_name)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
loggers_.erase(logger_name);
if (default_logger_ && default_logger_->name() == logger_name)
{
default_logger_.reset();
}
}
SPDLOG_INLINE void registry::drop_all()
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
loggers_.clear();
default_logger_.reset();
}
// clean all resources and threads started by the registry
SPDLOG_INLINE void registry::shutdown()
{
{
std::lock_guard<std::mutex> lock(flusher_mutex_);
periodic_flusher_.reset();
}
drop_all();
{
std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
tp_.reset();
}
}
SPDLOG_INLINE std::recursive_mutex &registry::tp_mutex()
{
return tp_mutex_;
}
SPDLOG_INLINE void registry::set_automatic_registration(bool automatic_registration)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
automatic_registration_ = automatic_registration;
}
SPDLOG_INLINE void registry::set_levels(log_levels levels, level::level_enum *global_level)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
log_levels_ = std::move(levels);
auto global_level_requested = global_level != nullptr;
global_log_level_ = global_level_requested ? *global_level : global_log_level_;
for (auto &logger : loggers_)
{
auto logger_entry = log_levels_.find(logger.first);
if (logger_entry != log_levels_.end())
{
logger.second->set_level(logger_entry->second);
}
else if (global_level_requested)
{
logger.second->set_level(*global_level);
}
}
}
SPDLOG_INLINE registry &registry::instance()
{
static registry s_instance;
return s_instance;
}
SPDLOG_INLINE void registry::throw_if_exists_(const std::string &logger_name)
{
if (loggers_.find(logger_name) != loggers_.end())
{
throw_spdlog_ex("logger with name '" + logger_name + "' already exists");
}
}
SPDLOG_INLINE void registry::register_logger_(std::shared_ptr<logger> new_logger)
{
auto logger_name = new_logger->name();
throw_if_exists_(logger_name);
loggers_[logger_name] = std::move(new_logger);
}
} // namespace details
} // namespace spdlog
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
// Loggers registry of unique name->logger pointer
// An attempt to create a logger with an already existing name will result with spdlog_ex exception.
// If user requests a non existing logger, nullptr will be returned
// This class is thread safe
#include <spdlog/common.h>
#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <mutex>
namespace spdlog {
class logger;
namespace details {
class thread_pool;
class periodic_worker;
class SPDLOG_API registry
{
public:
using log_levels = std::unordered_map<std::string, level::level_enum>;
registry(const registry &) = delete;
registry &operator=(const registry &) = delete;
void register_logger(std::shared_ptr<logger> new_logger);
void initialize_logger(std::shared_ptr<logger> new_logger);
std::shared_ptr<logger> get(const std::string &logger_name);
std::shared_ptr<logger> default_logger();
// Return raw ptr to the default logger.
// To be used directly by the spdlog default api (e.g. spdlog::info)
// This make the default API faster, but cannot be used concurrently with set_default_logger().
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
logger *get_default_raw();
// set default logger.
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
void set_default_logger(std::shared_ptr<logger> new_default_logger);
void set_tp(std::shared_ptr<thread_pool> tp);
std::shared_ptr<thread_pool> get_tp();
// Set global formatter. Each sink in each logger will get a clone of this object
void set_formatter(std::unique_ptr<formatter> formatter);
void enable_backtrace(size_t n_messages);
void disable_backtrace();
void set_level(level::level_enum log_level);
void flush_on(level::level_enum log_level);
void flush_every(std::chrono::seconds interval);
void set_error_handler(err_handler handler);
void apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun);
void flush_all();
void drop(const std::string &logger_name);
void drop_all();
// clean all resources and threads started by the registry
void shutdown();
std::recursive_mutex &tp_mutex();
void set_automatic_registration(bool automatic_registration);
// set levels for all existing/future loggers. global_level can be null if should not set.
void set_levels(log_levels levels, level::level_enum *global_level);
static registry &instance();
private:
registry();
~registry();
void throw_if_exists_(const std::string &logger_name);
void register_logger_(std::shared_ptr<logger> new_logger);
bool set_level_from_cfg_(logger *logger);
std::mutex logger_map_mutex_, flusher_mutex_;
std::recursive_mutex tp_mutex_;
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
log_levels log_levels_;
std::unique_ptr<formatter> formatter_;
spdlog::level::level_enum global_log_level_ = level::info;
level::level_enum flush_level_ = level::off;
err_handler err_handler_;
std::shared_ptr<thread_pool> tp_;
std::unique_ptr<periodic_worker> periodic_flusher_;
std::shared_ptr<logger> default_logger_;
bool automatic_registration_ = true;
size_t backtrace_n_messages_ = 0;
};
} // namespace details
} // namespace spdlog
#ifdef SPDLOG_HEADER_ONLY
# include "registry-inl.h"
#endif
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
#pragma once #pragma once
#include "registry.h"
namespace spdlog { namespace spdlog {
// Default logger factory- creates synchronous loggers // Default logger factory- creates synchronous loggers
...@@ -16,9 +14,7 @@ struct synchronous_factory ...@@ -16,9 +14,7 @@ struct synchronous_factory
static std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&...args) static std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&...args)
{ {
auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...); auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
auto new_logger = std::make_shared<spdlog::logger>(std::move(logger_name), std::move(sink)); return std::make_shared<spdlog::logger>(std::move(logger_name), std::move(sink));
details::registry::instance().initialize_logger(new_logger);
return new_logger;
} }
}; };
} // namespace spdlog } // namespace spdlog
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#endif #endif
#include <spdlog/sinks/sink.h> #include <spdlog/sinks/sink.h>
#include <spdlog/details/backtracer.h>
#include <cstdio> #include <cstdio>
...@@ -21,15 +20,14 @@ SPDLOG_INLINE logger::logger(const logger &other) ...@@ -21,15 +20,14 @@ SPDLOG_INLINE logger::logger(const logger &other)
, level_(other.level_.load(std::memory_order_relaxed)) , level_(other.level_.load(std::memory_order_relaxed))
, flush_level_(other.flush_level_.load(std::memory_order_relaxed)) , flush_level_(other.flush_level_.load(std::memory_order_relaxed))
, custom_err_handler_(other.custom_err_handler_) , custom_err_handler_(other.custom_err_handler_)
, tracer_(other.tracer_)
{} {}
SPDLOG_INLINE logger::logger(logger &&other) SPDLOG_NOEXCEPT : name_(std::move(other.name_)), SPDLOG_INLINE logger::logger(logger &&other) SPDLOG_NOEXCEPT : name_(std::move(other.name_)),
sinks_(std::move(other.sinks_)), sinks_(std::move(other.sinks_)),
level_(other.level_.load(std::memory_order_relaxed)), level_(other.level_.load(std::memory_order_relaxed)),
flush_level_(other.flush_level_.load(std::memory_order_relaxed)), flush_level_(other.flush_level_.load(std::memory_order_relaxed)),
custom_err_handler_(std::move(other.custom_err_handler_)), custom_err_handler_(std::move(other.custom_err_handler_))
tracer_(std::move(other.tracer_))
{} {}
...@@ -55,7 +53,6 @@ SPDLOG_INLINE void logger::swap(spdlog::logger &other) SPDLOG_NOEXCEPT ...@@ -55,7 +53,6 @@ SPDLOG_INLINE void logger::swap(spdlog::logger &other) SPDLOG_NOEXCEPT
other.flush_level_.store(my_level); other.flush_level_.store(my_level);
custom_err_handler_.swap(other.custom_err_handler_); custom_err_handler_.swap(other.custom_err_handler_);
std::swap(tracer_, other.tracer_);
} }
SPDLOG_INLINE void swap(logger &a, logger &b) SPDLOG_INLINE void swap(logger &a, logger &b)
...@@ -97,23 +94,6 @@ SPDLOG_INLINE void logger::set_formatter(std::unique_ptr<formatter> f) ...@@ -97,23 +94,6 @@ SPDLOG_INLINE void logger::set_formatter(std::unique_ptr<formatter> f)
} }
} }
// create new backtrace sink and move to it all our child sinks
SPDLOG_INLINE void logger::enable_backtrace(size_t n_messages)
{
tracer_.enable(n_messages);
}
// restore orig sinks and level and delete the backtrace sink
SPDLOG_INLINE void logger::disable_backtrace()
{
tracer_.disable();
}
SPDLOG_INLINE void logger::dump_backtrace()
{
dump_backtrace_();
}
// flush functions // flush functions
SPDLOG_INLINE void logger::flush() SPDLOG_INLINE void logger::flush()
{ {
...@@ -155,18 +135,6 @@ SPDLOG_INLINE std::shared_ptr<logger> logger::clone(std::string logger_name) ...@@ -155,18 +135,6 @@ SPDLOG_INLINE std::shared_ptr<logger> logger::clone(std::string logger_name)
return cloned; return cloned;
} }
// protected methods
SPDLOG_INLINE void logger::log_it_(const spdlog::details::log_msg &log_msg, bool log_enabled, bool traceback_enabled)
{
if (log_enabled)
{
sink_it_(log_msg);
}
if (traceback_enabled)
{
tracer_.push_back(log_msg);
}
}
SPDLOG_INLINE void logger::sink_it_(const details::log_msg &msg) SPDLOG_INLINE void logger::sink_it_(const details::log_msg &msg)
{ {
...@@ -200,16 +168,6 @@ SPDLOG_INLINE void logger::flush_() ...@@ -200,16 +168,6 @@ SPDLOG_INLINE void logger::flush_()
} }
} }
SPDLOG_INLINE void logger::dump_backtrace_()
{
using details::log_msg;
if (tracer_.enabled())
{
sink_it_(log_msg{name(), level::info, "****************** Backtrace Start ******************"});
tracer_.foreach_pop([this](const log_msg &msg) { this->sink_it_(msg); });
sink_it_(log_msg{name(), level::info, "****************** Backtrace End ********************"});
}
}
SPDLOG_INLINE bool logger::should_flush_(const details::log_msg &msg) SPDLOG_INLINE bool logger::should_flush_(const details::log_msg &msg)
{ {
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <spdlog/common.h> #include <spdlog/common.h>
#include <spdlog/details/log_msg.h> #include <spdlog/details/log_msg.h>
#include <spdlog/details/backtracer.h>
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
# ifndef _WIN32 # ifndef _WIN32
...@@ -118,28 +117,23 @@ public: ...@@ -118,28 +117,23 @@ public:
void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg) void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg)
{ {
bool log_enabled = should_log(lvl); if (!should_log(lvl))
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled)
{ {
return; return;
} }
details::log_msg log_msg(log_time, loc, name_, lvl, msg); details::log_msg log_msg(log_time, loc, name_, lvl, msg);
log_it_(log_msg, log_enabled, traceback_enabled); sink_it_(log_msg);
} }
void log(source_loc loc, level::level_enum lvl, string_view_t msg) void log(source_loc loc, level::level_enum lvl, string_view_t msg)
{ {
bool log_enabled = should_log(lvl); if (!should_log(lvl))
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled)
{ {
return; return;
} }
details::log_msg log_msg(loc, name_, lvl, msg); details::log_msg log_msg(loc, name_, lvl, msg);
log_it_(log_msg, log_enabled, traceback_enabled); sink_it_(log_msg);
} }
void log(level::level_enum lvl, string_view_t msg) void log(level::level_enum lvl, string_view_t msg)
...@@ -275,12 +269,6 @@ public: ...@@ -275,12 +269,6 @@ public:
return msg_level >= level_.load(std::memory_order_relaxed); return msg_level >= level_.load(std::memory_order_relaxed);
} }
// return true if backtrace logging is enabled.
bool should_backtrace() const
{
return tracer_.enabled();
}
void set_level(level::level_enum log_level); void set_level(level::level_enum log_level);
level::level_enum level() const; level::level_enum level() const;
...@@ -291,12 +279,6 @@ public: ...@@ -291,12 +279,6 @@ public:
// each sink will get a separate instance of the formatter object. // each sink will get a separate instance of the formatter object.
void set_formatter(std::unique_ptr<formatter> f); void set_formatter(std::unique_ptr<formatter> f);
// backtrace support.
// efficiently store all debug/trace messages in a circular buffer until needed for debugging.
void enable_backtrace(size_t n_messages);
void disable_backtrace();
void dump_backtrace();
// flush functions // flush functions
void flush(); void flush();
void flush_on(level::level_enum log_level); void flush_on(level::level_enum log_level);
...@@ -319,15 +301,12 @@ protected: ...@@ -319,15 +301,12 @@ protected:
spdlog::level_t level_{level::info}; spdlog::level_t level_{level::info};
spdlog::level_t flush_level_{level::off}; spdlog::level_t flush_level_{level::off};
err_handler custom_err_handler_{nullptr}; err_handler custom_err_handler_{nullptr};
details::backtracer tracer_;
// common implementation for after templated public api has been resolved // common implementation for after templated public api has been resolved
template<typename... Args> template<typename... Args>
void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&...args) void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&...args)
{ {
bool log_enabled = should_log(lvl); if (!should_log(lvl))
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled)
{ {
return; return;
} }
...@@ -336,7 +315,7 @@ protected: ...@@ -336,7 +315,7 @@ protected:
memory_buf_t buf; memory_buf_t buf;
fmt::detail::vformat_to(buf, fmt, fmt::make_format_args(args...)); fmt::detail::vformat_to(buf, fmt, fmt::make_format_args(args...));
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size())); details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
log_it_(log_msg, log_enabled, traceback_enabled); sink_it_(log_msg);
} }
SPDLOG_LOGGER_CATCH(loc) SPDLOG_LOGGER_CATCH(loc)
} }
...@@ -347,7 +326,7 @@ protected: ...@@ -347,7 +326,7 @@ protected:
{ {
bool log_enabled = should_log(lvl); bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled(); bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled) if (!log_enabled)
{ {
return; return;
} }
...@@ -359,7 +338,8 @@ protected: ...@@ -359,7 +338,8 @@ protected:
memory_buf_t buf; memory_buf_t buf;
details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf); details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf);
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size())); details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
log_it_(log_msg, log_enabled, traceback_enabled); //log_it_(log_msg, log_enabled, traceback_enabled);
sink_it_(log_msg);
} }
SPDLOG_LOGGER_CATCH(loc) SPDLOG_LOGGER_CATCH(loc)
} }
...@@ -379,7 +359,7 @@ protected: ...@@ -379,7 +359,7 @@ protected:
memory_buf_t buf; memory_buf_t buf;
details::os::wstr_to_utf8buf(msg, buf); details::os::wstr_to_utf8buf(msg, buf);
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size())); details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
log_it_(log_msg, log_enabled, traceback_enabled); sink_it(log_msg);
} }
SPDLOG_LOGGER_CATCH(loc) SPDLOG_LOGGER_CATCH(loc)
} }
...@@ -388,7 +368,6 @@ protected: ...@@ -388,7 +368,6 @@ protected:
// log the given message (if the given log level is high enough), // log the given message (if the given log level is high enough),
// and save backtrace (if backtrace is enabled). // and save backtrace (if backtrace is enabled).
void log_it_(const details::log_msg &log_msg, bool log_enabled, bool traceback_enabled);
virtual void sink_it_(const details::log_msg &msg); virtual void sink_it_(const details::log_msg &msg);
virtual void flush_(); virtual void flush_();
void dump_backtrace_(); void dump_backtrace_();
......
...@@ -1289,11 +1289,6 @@ SPDLOG_INLINE void pattern_formatter::compile_pattern_(const std::string &patter ...@@ -1289,11 +1289,6 @@ SPDLOG_INLINE void pattern_formatter::compile_pattern_(const std::string &patter
} }
} }
SPDLOG_INLINE void set_pattern(std::string pattern)
{
set_formatter(details::make_unique<pattern_formatter>(std::move(pattern)));
}
SPDLOG_INLINE void set_pattern(logger& logger, std::string pattern) SPDLOG_INLINE void set_pattern(logger& logger, std::string pattern)
{ {
logger.set_formatter(details::make_unique<pattern_formatter>(std::move(pattern))); logger.set_formatter(details::make_unique<pattern_formatter>(std::move(pattern)));
......
...@@ -118,8 +118,6 @@ private: ...@@ -118,8 +118,6 @@ private:
void compile_pattern_(const std::string &pattern); void compile_pattern_(const std::string &pattern);
}; };
// Set global log pattern.
SPDLOG_API void set_pattern(std::string pattern);
// set pattern to logger // set pattern to logger
SPDLOG_API void set_pattern(logger& logger, std::string pattern); SPDLOG_API void set_pattern(logger& logger, std::string pattern);
......
...@@ -11,109 +11,33 @@ ...@@ -11,109 +11,33 @@
namespace spdlog { namespace spdlog {
SPDLOG_INLINE void initialize_logger(std::shared_ptr<logger> logger) // TODO what to do with flush_every ?
{ /*SPDLOG_INLINE void flush_every(std::chrono::seconds interval)
details::registry::instance().initialize_logger(std::move(logger));
}
SPDLOG_INLINE std::shared_ptr<logger> get(const std::string &name)
{
return details::registry::instance().get(name);
}
SPDLOG_INLINE void set_formatter(std::unique_ptr<spdlog::formatter> formatter)
{
details::registry::instance().set_formatter(std::move(formatter));
}
SPDLOG_INLINE void enable_backtrace(size_t n_messages)
{
details::registry::instance().enable_backtrace(n_messages);
}
SPDLOG_INLINE void disable_backtrace()
{
details::registry::instance().disable_backtrace();
}
SPDLOG_INLINE void dump_backtrace()
{
default_logger_raw()->dump_backtrace();
}
SPDLOG_INLINE level::level_enum get_level()
{
return default_logger_raw()->level();
}
SPDLOG_INLINE bool should_log(level::level_enum log_level)
{
return default_logger_raw()->should_log(log_level);
}
SPDLOG_INLINE void set_level(level::level_enum log_level)
{
details::registry::instance().set_level(log_level);
}
SPDLOG_INLINE void flush_on(level::level_enum log_level)
{
details::registry::instance().flush_on(log_level);
}
SPDLOG_INLINE void flush_every(std::chrono::seconds interval)
{ {
details::registry::instance().flush_every(interval); details::registry::instance().flush_every(interval);
} }*/
SPDLOG_INLINE void set_error_handler(void (*handler)(const std::string &msg))
{
details::registry::instance().set_error_handler(handler);
}
SPDLOG_INLINE void register_logger(std::shared_ptr<logger> logger)
{
details::registry::instance().register_logger(std::move(logger));
}
SPDLOG_INLINE void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun)
{
details::registry::instance().apply_all(fun);
}
SPDLOG_INLINE void drop(const std::string &name)
{
details::registry::instance().drop(name);
}
SPDLOG_INLINE void drop_all()
{
details::registry::instance().drop_all();
}
SPDLOG_INLINE void shutdown() SPDLOG_INLINE void shutdown()
{ {
details::registry::instance().shutdown(); // TODO call tp_ reset ?
} //details::registry::instance().shutdown();
SPDLOG_INLINE void set_automatic_registration(bool automatic_registration)
{
details::registry::instance().set_automatic_registration(automatic_registration);
} }
SPDLOG_INLINE std::shared_ptr<spdlog::logger> default_logger() SPDLOG_INLINE std::shared_ptr<spdlog::logger> default_logger()
{ {
return details::registry::instance().default_logger(); static std::shared_ptr<spdlog::logger> default_logger_ = std::make_shared<spdlog::logger>("");
return default_logger_;
} }
SPDLOG_INLINE spdlog::logger *default_logger_raw() SPDLOG_INLINE logger *default_logger_raw()
{ {
return details::registry::instance().get_default_raw(); return default_logger().get(); //TODO remove this
} }
SPDLOG_INLINE void set_default_logger(std::shared_ptr<spdlog::logger> default_logger) SPDLOG_INLINE void set_default_logger(std::shared_ptr<spdlog::logger> default_logger)
{ {
details::registry::instance().set_default_logger(std::move(default_logger)); default_logger = std::move(default_logger);
} }
} // namespace spdlog } // namespace spdlog
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#pragma once #pragma once
#include <spdlog/common.h> #include <spdlog/common.h>
#include <spdlog/details/registry.h>
#include <spdlog/logger.h> #include <spdlog/logger.h>
#include <spdlog/version.h> #include <spdlog/version.h>
#include <spdlog/details/synchronous_factory.h> #include <spdlog/details/synchronous_factory.h>
...@@ -24,7 +23,7 @@ namespace spdlog { ...@@ -24,7 +23,7 @@ namespace spdlog {
using default_factory = synchronous_factory; using default_factory = synchronous_factory;
// Create and register a logger with a templated sink type // Create a logger with a templated sink type
// The logger's level, formatter and flush level will be set according the // The logger's level, formatter and flush level will be set according the
// global settings. // global settings.
// //
...@@ -36,74 +35,9 @@ inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs ...@@ -36,74 +35,9 @@ inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs
return default_factory::create<Sink>(std::move(logger_name), std::forward<SinkArgs>(sink_args)...); return default_factory::create<Sink>(std::move(logger_name), std::forward<SinkArgs>(sink_args)...);
} }
// Initialize and register a logger, // stop any running threads started by spdlog for async logging
// formatter and flush level will be set according the global settings.
//
// Useful for initializing manually created loggers with the global settings.
//
// Example:
// auto mylogger = std::make_shared<spdlog::logger>("mylogger", ...);
// spdlog::initialize_logger(mylogger);
SPDLOG_API void initialize_logger(std::shared_ptr<logger> logger);
// Return an existing logger or nullptr if a logger with such name doesn't
// exist.
// example: spdlog::get("my_logger")->info("hello {}", "world");
SPDLOG_API std::shared_ptr<logger> get(const std::string &name);
// Set global formatter. Each sink in each logger will get a clone of this object
// example: spdlog::set_formatter(std::make_unique<spdlog::pattern_formatter>("%Y-%m-%d %H:%M:%S.%e %l : %v"));
// Note: to use spdlog::set_pattern(format_string) include the "spdlog/pattern_formatter.h" file.
SPDLOG_API void set_formatter(std::unique_ptr<spdlog::formatter> formatter);
// enable global backtrace support
SPDLOG_API void enable_backtrace(size_t n_messages);
// disable global backtrace support
SPDLOG_API void disable_backtrace();
// call dump backtrace on default logger
SPDLOG_API void dump_backtrace();
// Get global logging level
SPDLOG_API level::level_enum get_level();
// Set global logging level
SPDLOG_API void set_level(level::level_enum log_level);
// Determine whether the default logger should log messages with a certain level
SPDLOG_API bool should_log(level::level_enum lvl);
// Set global flush level
SPDLOG_API void flush_on(level::level_enum log_level);
// Start/Restart a periodic flusher thread
// Warning: Use only if all your loggers are thread safe!
SPDLOG_API void flush_every(std::chrono::seconds interval);
// Set global error handler
SPDLOG_API void set_error_handler(void (*handler)(const std::string &msg));
// Register the given logger with the given name
SPDLOG_API void register_logger(std::shared_ptr<logger> logger);
// Apply a user defined function on all registered loggers
// Example:
// spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->flush();});
SPDLOG_API void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun);
// Drop the reference to the given logger
SPDLOG_API void drop(const std::string &name);
// Drop all references from the registry
SPDLOG_API void drop_all();
// stop any running threads started by spdlog and clean registry loggers
SPDLOG_API void shutdown(); SPDLOG_API void shutdown();
// Automatic registration of loggers when using spdlog::create() or spdlog::create_async
SPDLOG_API void set_automatic_registration(bool automatic_registration);
// API for using default logger (stdout_color_mt), // API for using default logger (stdout_color_mt),
// e.g: spdlog::info("Message {}", 1); // e.g: spdlog::info("Message {}", 1);
// //
......
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
#include <spdlog/spdlog-inl.h> #include <spdlog/spdlog-inl.h>
#include <spdlog/common-inl.h> #include <spdlog/common-inl.h>
#include <spdlog/details/backtracer-inl.h>
#include <spdlog/details/registry-inl.h>
#include <spdlog/details/os-inl.h> #include <spdlog/details/os-inl.h>
#include <spdlog/pattern_formatter-inl.h> #include <spdlog/pattern_formatter-inl.h>
#include <spdlog/details/log_msg-inl.h> #include <spdlog/details/log_msg-inl.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