Loading external/spdlog/async.h +21 −15 Original line number Diff line number Diff line // // Copyright(c) 2018 Gabi Melman. // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) // #pragma once // // Async logging using global thread pool // All loggers created here share same global thread pool. // Each log message is pushed to a queue along withe a shared pointer to the // Each log message is pushed to a queue along with a shared pointer to the // logger. // If a logger deleted while having pending messages in the queue, it's actual // destruction will defer Loading @@ -17,12 +14,13 @@ // This is because each message in the queue holds a shared_ptr to the // originating logger. #include "spdlog/async_logger.h" #include "spdlog/details/registry.h" #include "spdlog/details/thread_pool.h" #include <spdlog/async_logger.h> #include <spdlog/details/registry.h> #include <spdlog/details/thread_pool.h> #include <memory> #include <mutex> #include <functional> namespace spdlog { Loading @@ -42,11 +40,13 @@ struct async_factory_impl auto ®istry_inst = details::registry::instance(); // create global thread pool if not already exists.. std::lock_guard<std::recursive_mutex> tp_lock(registry_inst.tp_mutex()); auto &mutex = registry_inst.tp_mutex(); std::lock_guard<std::recursive_mutex> tp_lock(mutex); auto tp = registry_inst.get_tp(); if (tp == nullptr) { tp = std::make_shared<details::thread_pool>(details::default_async_q_size, 1); tp = std::make_shared<details::thread_pool>(details::default_async_q_size, 1U); registry_inst.set_tp(tp); } Loading @@ -73,12 +73,18 @@ inline std::shared_ptr<spdlog::logger> create_async_nb(std::string logger_name, } // set global thread pool. inline void init_thread_pool(size_t q_size, size_t thread_count) 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); auto tp = std::make_shared<details::thread_pool>(q_size, thread_count, on_thread_start); details::registry::instance().set_tp(std::move(tp)); } // set global thread pool. inline void init_thread_pool(size_t q_size, size_t thread_count) { init_thread_pool(q_size, thread_count, [] {}); } // get the global thread pool. inline std::shared_ptr<spdlog::details::thread_pool> thread_pool() { Loading external/spdlog/details/async_logger_impl.h→external/spdlog/async_logger-inl.h +92 −0 Original line number Diff line number Diff line // // Copyright(c) 2015 Gabi Melman. // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) // #pragma once // async logger implementation // uses a thread pool to perform the actual logging #ifndef SPDLOG_HEADER_ONLY # include <spdlog/async_logger.h> #endif #include "spdlog/details/thread_pool.h" #include <spdlog/sinks/sink.h> #include <spdlog/details/thread_pool.h> #include <chrono> #include <memory> #include <string> template<typename It> inline spdlog::async_logger::async_logger( std::string logger_name, It begin, It end, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy) : logger(std::move(logger_name), begin, end) , thread_pool_(std::move(tp)) , overflow_policy_(overflow_policy) { } inline spdlog::async_logger::async_logger( SPDLOG_INLINE spdlog::async_logger::async_logger( std::string logger_name, sinks_init_list sinks_list, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy) : async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy) { } {} inline spdlog::async_logger::async_logger( SPDLOG_INLINE spdlog::async_logger::async_logger( std::string logger_name, sink_ptr single_sink, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy) : async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy) { } {} // send the log message to the thread pool inline void spdlog::async_logger::sink_it_(details::log_msg &msg) SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg) { #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(), msg, overflow_policy_); } else { throw spdlog_ex("async log: thread pool doesn't exist anymore"); throw_spdlog_ex("async log: thread pool doesn't exist anymore"); } } // send flush request to the thread pool inline void spdlog::async_logger::flush_() SPDLOG_INLINE void spdlog::async_logger::flush_() { if (auto pool_ptr = thread_pool_.lock()) { Loading @@ -60,51 +45,48 @@ inline void spdlog::async_logger::flush_() } else { throw spdlog_ex("async flush: thread pool doesn't exist anymore"); throw_spdlog_ex("async flush: thread pool doesn't exist anymore"); } } // // backend functions - called from the thread pool to do the actual job // inline void spdlog::async_logger::backend_log_(const details::log_msg &incoming_log_msg) SPDLOG_INLINE void spdlog::async_logger::backend_sink_it_(const details::log_msg &msg) { try for (auto &sink : sinks_) { for (auto &s : sinks_) if (sink->should_log(msg.level)) { if (s->should_log(incoming_log_msg.level)) SPDLOG_TRY { s->log(incoming_log_msg); sink->log(msg); } SPDLOG_LOGGER_CATCH() } } SPDLOG_CATCH_AND_HANDLE if (should_flush_(incoming_log_msg)) if (should_flush_(msg)) { backend_flush_(); } } inline void spdlog::async_logger::backend_flush_() { try SPDLOG_INLINE void spdlog::async_logger::backend_flush_() { for (auto &sink : sinks_) { SPDLOG_TRY { sink->flush(); } SPDLOG_LOGGER_CATCH() } SPDLOG_CATCH_AND_HANDLE } inline std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::string new_name) SPDLOG_INLINE std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::string new_name) { auto cloned = std::make_shared<spdlog::async_logger>(std::move(new_name), sinks_.begin(), sinks_.end(), thread_pool_, overflow_policy_); cloned->set_level(this->level()); cloned->flush_on(this->flush_level()); cloned->set_error_handler(this->error_handler()); return std::move(cloned); auto cloned = std::make_shared<spdlog::async_logger>(*this); cloned->name_ = std::move(new_name); return cloned; } external/spdlog/async_logger.h +15 −20 Original line number Diff line number Diff line // // Copyright(c) 2015 Gabi Melman. // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) // #pragma once // Very fast asynchronous logger (millions of logs per second on an average // desktop) // Uses pre allocated lockfree queue for maximum throughput even under large // number of threads. // Fast asynchronous logger. // Uses pre allocated queue. // Creates a single back thread to pop messages from the queue and log them. // // Upon each log write the logger: // 1. Checks if its log level is enough to log the message // 2. Push a new copy of the message to a queue (or block the caller until // space is available in the queue) // 3. will throw spdlog_ex upon log exceptions // Upon destruction, logs all remaining messages in the queue before // destructing.. #include "spdlog/common.h" #include "spdlog/logger.h" #include <chrono> #include <memory> #include <string> #include <spdlog/logger.h> namespace spdlog { Loading @@ -40,14 +30,18 @@ namespace details { class thread_pool; } class async_logger final : public std::enable_shared_from_this<async_logger>, public logger class SPDLOG_API async_logger final : public std::enable_shared_from_this<async_logger>, public logger { friend class details::thread_pool; public: template<typename It> async_logger(std::string logger_name, It begin, It end, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy = async_overflow_policy::block); async_overflow_policy overflow_policy = async_overflow_policy::block) : logger(std::move(logger_name), begin, end) , thread_pool_(std::move(tp)) , overflow_policy_(overflow_policy) {} async_logger(std::string logger_name, sinks_init_list sinks_list, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy = async_overflow_policy::block); Loading @@ -58,10 +52,9 @@ public: std::shared_ptr<logger> clone(std::string new_name) override; protected: void sink_it_(details::log_msg &msg) override; void sink_it_(const details::log_msg &msg) override; void flush_() override; void backend_log_(const details::log_msg &incoming_log_msg); void backend_sink_it_(const details::log_msg &incoming_log_msg); void backend_flush_(); private: Loading @@ -70,4 +63,6 @@ private: }; } // namespace spdlog #include "details/async_logger_impl.h" #ifdef SPDLOG_HEADER_ONLY # include "async_logger-inl.h" #endif external/spdlog/cfg/argv.h 0 → 100644 +44 −0 Original line number Diff line number Diff line // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) #pragma once #include <spdlog/cfg/helpers.h> #include <spdlog/details/registry.h> // // Init log levels using each argv entry that starts with "SPDLOG_LEVEL=" // // set all loggers to debug level: // example.exe "SPDLOG_LEVEL=debug" // set logger1 to trace level // example.exe "SPDLOG_LEVEL=logger1=trace" // turn off all logging except for logger1 and logger2: // example.exe "SPDLOG_LEVEL=off,logger1=debug,logger2=info" namespace spdlog { namespace cfg { // search for SPDLOG_LEVEL= in the args and use it to init the levels inline void load_argv_levels(int argc, const char **argv) { const std::string spdlog_level_prefix = "SPDLOG_LEVEL="; for (int i = 1; i < argc; i++) { std::string arg = argv[i]; if (arg.find(spdlog_level_prefix) == 0) { auto levels_string = arg.substr(spdlog_level_prefix.size()); helpers::load_levels(levels_string); } } } inline void load_argv_levels(int argc, char **argv) { load_argv_levels(argc, const_cast<const char **>(argv)); } } // namespace cfg } // namespace spdlog external/spdlog/cfg/env.h 0 → 100644 +38 −0 Original line number Diff line number Diff line // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) #pragma once #include <spdlog/cfg/helpers.h> #include <spdlog/details/registry.h> #include <spdlog/details/os.h> // // Init levels and patterns from env variables SPDLOG_LEVEL // Inspired from Rust's "env_logger" crate (https://crates.io/crates/env_logger). // Note - fallback to "info" level on unrecognized levels // // Examples: // // set global level to debug: // export SPDLOG_LEVEL=debug // // turn off all logging except for logger1: // export SPDLOG_LEVEL="*=off,logger1=debug" // // turn off all logging except for logger1 and logger2: // export SPDLOG_LEVEL="off,logger1=debug,logger2=info" namespace spdlog { namespace cfg { inline void load_env_levels() { auto env_val = details::os::getenv("SPDLOG_LEVEL"); if (!env_val.empty()) { helpers::load_levels(env_val); } } } // namespace cfg } // namespace spdlog Loading
external/spdlog/async.h +21 −15 Original line number Diff line number Diff line // // Copyright(c) 2018 Gabi Melman. // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) // #pragma once // // Async logging using global thread pool // All loggers created here share same global thread pool. // Each log message is pushed to a queue along withe a shared pointer to the // Each log message is pushed to a queue along with a shared pointer to the // logger. // If a logger deleted while having pending messages in the queue, it's actual // destruction will defer Loading @@ -17,12 +14,13 @@ // This is because each message in the queue holds a shared_ptr to the // originating logger. #include "spdlog/async_logger.h" #include "spdlog/details/registry.h" #include "spdlog/details/thread_pool.h" #include <spdlog/async_logger.h> #include <spdlog/details/registry.h> #include <spdlog/details/thread_pool.h> #include <memory> #include <mutex> #include <functional> namespace spdlog { Loading @@ -42,11 +40,13 @@ struct async_factory_impl auto ®istry_inst = details::registry::instance(); // create global thread pool if not already exists.. std::lock_guard<std::recursive_mutex> tp_lock(registry_inst.tp_mutex()); auto &mutex = registry_inst.tp_mutex(); std::lock_guard<std::recursive_mutex> tp_lock(mutex); auto tp = registry_inst.get_tp(); if (tp == nullptr) { tp = std::make_shared<details::thread_pool>(details::default_async_q_size, 1); tp = std::make_shared<details::thread_pool>(details::default_async_q_size, 1U); registry_inst.set_tp(tp); } Loading @@ -73,12 +73,18 @@ inline std::shared_ptr<spdlog::logger> create_async_nb(std::string logger_name, } // set global thread pool. inline void init_thread_pool(size_t q_size, size_t thread_count) 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); auto tp = std::make_shared<details::thread_pool>(q_size, thread_count, on_thread_start); details::registry::instance().set_tp(std::move(tp)); } // set global thread pool. inline void init_thread_pool(size_t q_size, size_t thread_count) { init_thread_pool(q_size, thread_count, [] {}); } // get the global thread pool. inline std::shared_ptr<spdlog::details::thread_pool> thread_pool() { Loading
external/spdlog/details/async_logger_impl.h→external/spdlog/async_logger-inl.h +92 −0 Original line number Diff line number Diff line // // Copyright(c) 2015 Gabi Melman. // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) // #pragma once // async logger implementation // uses a thread pool to perform the actual logging #ifndef SPDLOG_HEADER_ONLY # include <spdlog/async_logger.h> #endif #include "spdlog/details/thread_pool.h" #include <spdlog/sinks/sink.h> #include <spdlog/details/thread_pool.h> #include <chrono> #include <memory> #include <string> template<typename It> inline spdlog::async_logger::async_logger( std::string logger_name, It begin, It end, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy) : logger(std::move(logger_name), begin, end) , thread_pool_(std::move(tp)) , overflow_policy_(overflow_policy) { } inline spdlog::async_logger::async_logger( SPDLOG_INLINE spdlog::async_logger::async_logger( std::string logger_name, sinks_init_list sinks_list, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy) : async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy) { } {} inline spdlog::async_logger::async_logger( SPDLOG_INLINE spdlog::async_logger::async_logger( std::string logger_name, sink_ptr single_sink, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy) : async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy) { } {} // send the log message to the thread pool inline void spdlog::async_logger::sink_it_(details::log_msg &msg) SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg) { #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(), msg, overflow_policy_); } else { throw spdlog_ex("async log: thread pool doesn't exist anymore"); throw_spdlog_ex("async log: thread pool doesn't exist anymore"); } } // send flush request to the thread pool inline void spdlog::async_logger::flush_() SPDLOG_INLINE void spdlog::async_logger::flush_() { if (auto pool_ptr = thread_pool_.lock()) { Loading @@ -60,51 +45,48 @@ inline void spdlog::async_logger::flush_() } else { throw spdlog_ex("async flush: thread pool doesn't exist anymore"); throw_spdlog_ex("async flush: thread pool doesn't exist anymore"); } } // // backend functions - called from the thread pool to do the actual job // inline void spdlog::async_logger::backend_log_(const details::log_msg &incoming_log_msg) SPDLOG_INLINE void spdlog::async_logger::backend_sink_it_(const details::log_msg &msg) { try for (auto &sink : sinks_) { for (auto &s : sinks_) if (sink->should_log(msg.level)) { if (s->should_log(incoming_log_msg.level)) SPDLOG_TRY { s->log(incoming_log_msg); sink->log(msg); } SPDLOG_LOGGER_CATCH() } } SPDLOG_CATCH_AND_HANDLE if (should_flush_(incoming_log_msg)) if (should_flush_(msg)) { backend_flush_(); } } inline void spdlog::async_logger::backend_flush_() { try SPDLOG_INLINE void spdlog::async_logger::backend_flush_() { for (auto &sink : sinks_) { SPDLOG_TRY { sink->flush(); } SPDLOG_LOGGER_CATCH() } SPDLOG_CATCH_AND_HANDLE } inline std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::string new_name) SPDLOG_INLINE std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::string new_name) { auto cloned = std::make_shared<spdlog::async_logger>(std::move(new_name), sinks_.begin(), sinks_.end(), thread_pool_, overflow_policy_); cloned->set_level(this->level()); cloned->flush_on(this->flush_level()); cloned->set_error_handler(this->error_handler()); return std::move(cloned); auto cloned = std::make_shared<spdlog::async_logger>(*this); cloned->name_ = std::move(new_name); return cloned; }
external/spdlog/async_logger.h +15 −20 Original line number Diff line number Diff line // // Copyright(c) 2015 Gabi Melman. // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) // #pragma once // Very fast asynchronous logger (millions of logs per second on an average // desktop) // Uses pre allocated lockfree queue for maximum throughput even under large // number of threads. // Fast asynchronous logger. // Uses pre allocated queue. // Creates a single back thread to pop messages from the queue and log them. // // Upon each log write the logger: // 1. Checks if its log level is enough to log the message // 2. Push a new copy of the message to a queue (or block the caller until // space is available in the queue) // 3. will throw spdlog_ex upon log exceptions // Upon destruction, logs all remaining messages in the queue before // destructing.. #include "spdlog/common.h" #include "spdlog/logger.h" #include <chrono> #include <memory> #include <string> #include <spdlog/logger.h> namespace spdlog { Loading @@ -40,14 +30,18 @@ namespace details { class thread_pool; } class async_logger final : public std::enable_shared_from_this<async_logger>, public logger class SPDLOG_API async_logger final : public std::enable_shared_from_this<async_logger>, public logger { friend class details::thread_pool; public: template<typename It> async_logger(std::string logger_name, It begin, It end, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy = async_overflow_policy::block); async_overflow_policy overflow_policy = async_overflow_policy::block) : logger(std::move(logger_name), begin, end) , thread_pool_(std::move(tp)) , overflow_policy_(overflow_policy) {} async_logger(std::string logger_name, sinks_init_list sinks_list, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy = async_overflow_policy::block); Loading @@ -58,10 +52,9 @@ public: std::shared_ptr<logger> clone(std::string new_name) override; protected: void sink_it_(details::log_msg &msg) override; void sink_it_(const details::log_msg &msg) override; void flush_() override; void backend_log_(const details::log_msg &incoming_log_msg); void backend_sink_it_(const details::log_msg &incoming_log_msg); void backend_flush_(); private: Loading @@ -70,4 +63,6 @@ private: }; } // namespace spdlog #include "details/async_logger_impl.h" #ifdef SPDLOG_HEADER_ONLY # include "async_logger-inl.h" #endif
external/spdlog/cfg/argv.h 0 → 100644 +44 −0 Original line number Diff line number Diff line // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) #pragma once #include <spdlog/cfg/helpers.h> #include <spdlog/details/registry.h> // // Init log levels using each argv entry that starts with "SPDLOG_LEVEL=" // // set all loggers to debug level: // example.exe "SPDLOG_LEVEL=debug" // set logger1 to trace level // example.exe "SPDLOG_LEVEL=logger1=trace" // turn off all logging except for logger1 and logger2: // example.exe "SPDLOG_LEVEL=off,logger1=debug,logger2=info" namespace spdlog { namespace cfg { // search for SPDLOG_LEVEL= in the args and use it to init the levels inline void load_argv_levels(int argc, const char **argv) { const std::string spdlog_level_prefix = "SPDLOG_LEVEL="; for (int i = 1; i < argc; i++) { std::string arg = argv[i]; if (arg.find(spdlog_level_prefix) == 0) { auto levels_string = arg.substr(spdlog_level_prefix.size()); helpers::load_levels(levels_string); } } } inline void load_argv_levels(int argc, char **argv) { load_argv_levels(argc, const_cast<const char **>(argv)); } } // namespace cfg } // namespace spdlog
external/spdlog/cfg/env.h 0 → 100644 +38 −0 Original line number Diff line number Diff line // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) #pragma once #include <spdlog/cfg/helpers.h> #include <spdlog/details/registry.h> #include <spdlog/details/os.h> // // Init levels and patterns from env variables SPDLOG_LEVEL // Inspired from Rust's "env_logger" crate (https://crates.io/crates/env_logger). // Note - fallback to "info" level on unrecognized levels // // Examples: // // set global level to debug: // export SPDLOG_LEVEL=debug // // turn off all logging except for logger1: // export SPDLOG_LEVEL="*=off,logger1=debug" // // turn off all logging except for logger1 and logger2: // export SPDLOG_LEVEL="off,logger1=debug,logger2=info" namespace spdlog { namespace cfg { inline void load_env_levels() { auto env_val = details::os::getenv("SPDLOG_LEVEL"); if (!env_val.empty()) { helpers::load_levels(env_val); } } } // namespace cfg } // namespace spdlog