http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/939751c1/include/spdlog/details/line_logger.h ---------------------------------------------------------------------- diff --git a/include/spdlog/details/line_logger.h b/include/spdlog/details/line_logger.h deleted file mode 100644 index 80d7cc1..0000000 --- a/include/spdlog/details/line_logger.h +++ /dev/null @@ -1,221 +0,0 @@ -/*************************************************************************/ -/* spdlog - an extremely fast and easy to use c++11 logging library. */ -/* Copyright (c) 2014 Gabi Melman. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#pragma once -#include <type_traits> -#include "../common.h" -#include "../logger.h" - -// Line logger class - aggregates operator<< calls to fast ostream -// and logs upon destruction - -namespace spdlog -{ -namespace details -{ -class line_logger -{ -public: - line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled): - _callback_logger(callback_logger), - _log_msg(msg_level), - _enabled(enabled) - {} - - // No copy intended. Only move - line_logger(const line_logger& other) = delete; - line_logger& operator=(const line_logger&) = delete; - line_logger& operator=(line_logger&&) = delete; - - - line_logger(line_logger&& other) : - _callback_logger(other._callback_logger), - _log_msg(std::move(other._log_msg)), - _enabled(other._enabled) - { - other.disable(); - } - - //Log the log message using the callback logger - ~line_logger() - { - if (_enabled) - { -#ifndef SPDLOG_NO_NAME - _log_msg.logger_name = _callback_logger->name(); -#endif -#ifndef SPDLOG_NO_DATETIME - _log_msg.time = os::now(); -#endif - -#ifndef SPDLOG_NO_THREAD_ID - _log_msg.thread_id = os::thread_id(); -#endif - _callback_logger->_log_msg(_log_msg); - } - } - - // - // Support for format string with variadic args - // - - - void write(const char* what) - { - if (_enabled) - _log_msg.raw << what; - } - - template <typename... Args> - void write(const char* fmt, const Args&... args) - { - if (!_enabled) - return; - try - { - _log_msg.raw.write(fmt, args...); - } - catch (const fmt::FormatError& e) - { - throw spdlog_ex(fmt::format("formatting error while processing format string '{}': {}", fmt, e.what())); - } - } - - - // - // Support for operator<< - // - line_logger& operator<<(const char* what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - line_logger& operator<<(const std::string& what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - line_logger& operator<<(int what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - line_logger& operator<<(unsigned int what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - - line_logger& operator<<(long what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - line_logger& operator<<(unsigned long what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - line_logger& operator<<(long long what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - line_logger& operator<<(unsigned long long what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - line_logger& operator<<(double what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - line_logger& operator<<(long double what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - line_logger& operator<<(float what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - line_logger& operator<<(char what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } - - //Support user types which implements operator<< - template<typename T> - line_logger& operator<<(const T& what) - { - if (_enabled) - _log_msg.raw.write("{}", what); - return *this; - } - - - void disable() - { - _enabled = false; - } - - bool is_enabled() const - { - return _enabled; - } - - -private: - logger* _callback_logger; - log_msg _log_msg; - bool _enabled; -}; -} //Namespace details -} // Namespace spdlog
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/939751c1/include/spdlog/details/log_msg.h ---------------------------------------------------------------------- diff --git a/include/spdlog/details/log_msg.h b/include/spdlog/details/log_msg.h index bf58aca..ecdc73d 100644 --- a/include/spdlog/details/log_msg.h +++ b/include/spdlog/details/log_msg.h @@ -1,32 +1,16 @@ -/*************************************************************************/ -/* spdlog - an extremely fast and easy to use c++11 logging library. */ -/* Copyright (c) 2014 Gabi Melman. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +// +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// #pragma once -#include <thread> -#include "../common.h" -#include "./format.h" +#include <spdlog/common.h> +#include <spdlog/details/os.h> + + +#include <string> +#include <utility> namespace spdlog { @@ -35,59 +19,23 @@ namespace details struct log_msg { log_msg() = default; - log_msg(level::level_enum l): - logger_name(), - level(l), - raw(), - formatted() {} - - - log_msg(const log_msg& other) : - logger_name(other.logger_name), - level(other.level), - time(other.time), - thread_id(other.thread_id) + log_msg(const std::string *loggers_name, level::level_enum lvl) : logger_name(loggers_name), level(lvl) { - if (other.raw.size()) - raw << fmt::BasicStringRef<char>(other.raw.data(), other.raw.size()); - if (other.formatted.size()) - formatted << fmt::BasicStringRef<char>(other.formatted.data(), other.formatted.size()); - } +#ifndef SPDLOG_NO_DATETIME + time = os::now(); +#endif - log_msg(log_msg&& other) : - logger_name(std::move(other.logger_name)), - level(other.level), - time(std::move(other.time)), - thread_id(other.thread_id), - raw(std::move(other.raw)), - formatted(std::move(other.formatted)) - { - other.clear(); +#ifndef SPDLOG_NO_THREAD_ID + thread_id = os::thread_id(); +#endif } - log_msg& operator=(log_msg&& other) - { - if (this == &other) - return *this; - - logger_name = std::move(other.logger_name); - level = other.level; - time = std::move(other.time); - thread_id = other.thread_id; - raw = std::move(other.raw); - formatted = std::move(other.formatted); - other.clear(); - return *this; - } + log_msg(const log_msg& other) = delete; + log_msg& operator=(log_msg&& other) = delete; + log_msg(log_msg&& other) = delete; - void clear() - { - level = level::off; - raw.clear(); - formatted.clear(); - } - std::string logger_name; + const std::string *logger_name; level::level_enum level; log_clock::time_point time; size_t thread_id; http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/939751c1/include/spdlog/details/logger_impl.h ---------------------------------------------------------------------- diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index d658ac0..2b27f10 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -1,58 +1,47 @@ -/*************************************************************************/ -/* spdlog - an extremely fast and easy to use c++11 logging library. */ -/* Copyright (c) 2014 Gabi Melman. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#pragma once // -// Logger implementation +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) // -#include "./line_logger.h" +#pragma once + +#include <spdlog/logger.h> +#include <spdlog/sinks/stdout_sinks.h> + +#include <memory> +#include <string> // create logger with given name, sinks and the default pattern formatter // all other ctors will call this one template<class It> -inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end) : +inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end): _name(logger_name), _sinks(begin, end), _formatter(std::make_shared<pattern_formatter>("%+")) { - - // no support under vs2013 for member initialization for std::atomic _level = level::info; + _flush_level = level::off; + _last_err_time = 0; + _err_handler = [this](const std::string &msg) + { + this->_default_err_handler(msg); + }; } // ctor with sinks as init list -inline spdlog::logger::logger(const std::string& logger_name, sinks_init_list sinks_list) : - logger(logger_name, sinks_list.begin(), sinks_list.end()) {} +inline spdlog::logger::logger(const std::string& logger_name, sinks_init_list sinks_list): + logger(logger_name, sinks_list.begin(), sinks_list.end()) +{} // ctor with single sink -inline spdlog::logger::logger(const std::string& logger_name, spdlog::sink_ptr single_sink) : - logger(logger_name, { +inline spdlog::logger::logger(const std::string& logger_name, spdlog::sink_ptr single_sink): + logger(logger_name, +{ single_sink -}) {} +}) +{} inline spdlog::logger::~logger() = default; @@ -68,221 +57,176 @@ inline void spdlog::logger::set_pattern(const std::string& pattern) _set_pattern(pattern); } -// -// log only if given level>=logger's log level -// - template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args) -{ - bool msg_enabled = should_log(lvl); - details::line_logger l(this, lvl, msg_enabled); - l.write(fmt, args...); - return l; +inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Args&... args) +{ + if (!should_log(lvl)) return; + + try + { + details::log_msg log_msg(&_name, lvl); + log_msg.raw.write(fmt, args...); + _sink_it(log_msg); + } + catch (const std::exception &ex) + { + _err_handler(ex.what()); + } + catch (...) + { + _err_handler("Unknown exception"); + } } -inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl) -{ - return details::line_logger(this, lvl, should_log(lvl)); +template <typename... Args> +inline void spdlog::logger::log(level::level_enum lvl, const char* msg) +{ + if (!should_log(lvl)) return; + try + { + details::log_msg log_msg(&_name, lvl); + log_msg.raw << msg; + _sink_it(log_msg); + } + catch (const std::exception &ex) + { + _err_handler(ex.what()); + } + catch (...) + { + _err_handler("Unknown exception"); + } + } template<typename T> -inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl, const T& msg) -{ - bool msg_enabled = should_log(lvl); - details::line_logger l(this, lvl, msg_enabled); - l << msg; - return l; +inline void spdlog::logger::log(level::level_enum lvl, const T& msg) +{ + if (!should_log(lvl)) return; + try + { + details::log_msg log_msg(&_name, lvl); + log_msg.raw << msg; + _sink_it(log_msg); + } + catch (const std::exception &ex) + { + _err_handler(ex.what()); + } + catch (...) + { + _err_handler("Unknown exception"); + } } -// -// logger.info(cppformat_string, arg1, arg2, arg3, ...) call style -// -template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::trace(const char* fmt, const Args&... args) -{ - return _log_if_enabled(level::trace, fmt, args...); -} template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::debug(const char* fmt, const Args&... args) +inline void spdlog::logger::trace(const char* fmt, const Args&... args) { - return _log_if_enabled(level::debug, fmt, args...); + log(level::trace, fmt, args...); } template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::info(const char* fmt, const Args&... args) +inline void spdlog::logger::debug(const char* fmt, const Args&... args) { - return _log_if_enabled(level::info, fmt, args...); + log(level::debug, fmt, args...); } template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::notice(const char* fmt, const Args&... args) +inline void spdlog::logger::info(const char* fmt, const Args&... args) { - return _log_if_enabled(level::notice, fmt, args...); + log(level::info, fmt, args...); } -template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::warn(const char* fmt, const Args&... args) -{ - return _log_if_enabled(level::warn, fmt, args...); -} template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::error(const char* fmt, const Args&... args) +inline void spdlog::logger::warn(const char* fmt, const Args&... args) { - return _log_if_enabled(level::err, fmt, args...); + log(level::warn, fmt, args...); } template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::critical(const char* fmt, const Args&... args) +inline void spdlog::logger::error(const char* fmt, const Args&... args) { - return _log_if_enabled(level::critical, fmt, args...); + log(level::err, fmt, args...); } template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::alert(const char* fmt, const Args&... args) +inline void spdlog::logger::critical(const char* fmt, const Args&... args) { - return _log_if_enabled(level::alert, fmt, args...); + log(level::critical, fmt, args...); } -template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::emerg(const char* fmt, const Args&... args) -{ - return _log_if_enabled(level::emerg, fmt, args...); -} -// -// logger.info(msg) << ".." call style -// template<typename T> -inline spdlog::details::line_logger spdlog::logger::trace(const T& msg) +inline void spdlog::logger::trace(const T& msg) { - return _log_if_enabled(level::trace, msg); + log(level::trace, msg); } template<typename T> -inline spdlog::details::line_logger spdlog::logger::debug(const T& msg) +inline void spdlog::logger::debug(const T& msg) { - return _log_if_enabled(level::debug, msg); + log(level::debug, msg); } template<typename T> -inline spdlog::details::line_logger spdlog::logger::info(const T& msg) +inline void spdlog::logger::info(const T& msg) { - return _log_if_enabled(level::info, msg); + log(level::info, msg); } -template<typename T> -inline spdlog::details::line_logger spdlog::logger::notice(const T& msg) -{ - return _log_if_enabled(level::notice, msg); -} template<typename T> -inline spdlog::details::line_logger spdlog::logger::warn(const T& msg) +inline void spdlog::logger::warn(const T& msg) { - return _log_if_enabled(level::warn, msg); + log(level::warn, msg); } template<typename T> -inline spdlog::details::line_logger spdlog::logger::error(const T& msg) +inline void spdlog::logger::error(const T& msg) { - return _log_if_enabled(level::err, msg); + log(level::err, msg); } template<typename T> -inline spdlog::details::line_logger spdlog::logger::critical(const T& msg) +inline void spdlog::logger::critical(const T& msg) { - return _log_if_enabled(level::critical, msg); -} - -template<typename T> -inline spdlog::details::line_logger spdlog::logger::alert(const T& msg) -{ - return _log_if_enabled(level::alert, msg); -} - -template<typename T> -inline spdlog::details::line_logger spdlog::logger::emerg(const T& msg) -{ - return _log_if_enabled(level::emerg, msg); + log(level::critical, msg); } // -// logger.info() << ".." call style +// name and level // -inline spdlog::details::line_logger spdlog::logger::trace() -{ - return _log_if_enabled(level::trace); -} - -inline spdlog::details::line_logger spdlog::logger::debug() -{ - return _log_if_enabled(level::debug); -} - -inline spdlog::details::line_logger spdlog::logger::info() -{ - return _log_if_enabled(level::info); -} - -inline spdlog::details::line_logger spdlog::logger::notice() -{ - return _log_if_enabled(level::notice); -} - -inline spdlog::details::line_logger spdlog::logger::warn() -{ - return _log_if_enabled(level::warn); -} - -inline spdlog::details::line_logger spdlog::logger::error() -{ - return _log_if_enabled(level::err); -} - -inline spdlog::details::line_logger spdlog::logger::critical() +inline const std::string& spdlog::logger::name() const { - return _log_if_enabled(level::critical); + return _name; } -inline spdlog::details::line_logger spdlog::logger::alert() +inline void spdlog::logger::set_level(spdlog::level::level_enum log_level) { - return _log_if_enabled(level::alert); + _level.store(log_level); } -inline spdlog::details::line_logger spdlog::logger::emerg() +inline void spdlog::logger::set_error_handler(spdlog::log_err_handler err_handler) { - return _log_if_enabled(level::emerg); + _err_handler = err_handler; } - -// always log, no matter what is the actual logger's log level -template <typename... Args> -inline spdlog::details::line_logger spdlog::logger::force_log(level::level_enum lvl, const char* fmt, const Args&... args) +inline spdlog::log_err_handler spdlog::logger::error_handler() { - details::line_logger l(this, lvl, true); - l.write(fmt, args...); - return l; + return _err_handler; } -// -// name and level -// -inline const std::string& spdlog::logger::name() const -{ - return _name; -} -inline void spdlog::logger::set_level(spdlog::level::level_enum log_level) +inline void spdlog::logger::flush_on(level::level_enum log_level) { - _level.store(log_level); + _flush_level.store(log_level); } inline spdlog::level::level_enum spdlog::logger::level() const @@ -298,11 +242,19 @@ inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) cons // // protected virtual called at end of each user log call (if enabled) by the line_logger // -inline void spdlog::logger::_log_msg(details::log_msg& msg) +inline void spdlog::logger::_sink_it(details::log_msg& msg) { _formatter->format(msg); for (auto &sink : _sinks) - sink->log(msg); + { + if( sink->should_log( msg.level)) + { + sink->log(msg); + } + } + + if(_should_flush_on(msg)) + flush(); } inline void spdlog::logger::_set_pattern(const std::string& pattern) @@ -314,7 +266,33 @@ inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter) _formatter = msg_formatter; } -inline void spdlog::logger::flush() { +inline void spdlog::logger::flush() +{ for (auto& sink : _sinks) sink->flush(); -} \ No newline at end of file +} + +inline void spdlog::logger::_default_err_handler(const std::string &msg) +{ + auto now = time(nullptr); + if (now - _last_err_time < 60) + return; + 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::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); +} + +inline const std::vector<spdlog::sink_ptr>& spdlog::logger::sinks() const +{ + return _sinks; +} http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/939751c1/include/spdlog/details/mpmc_bounded_q.h ---------------------------------------------------------------------- diff --git a/include/spdlog/details/mpmc_bounded_q.h b/include/spdlog/details/mpmc_bounded_q.h index 7cbcfd7..3a46e8e 100644 --- a/include/spdlog/details/mpmc_bounded_q.h +++ b/include/spdlog/details/mpmc_bounded_q.h @@ -36,33 +36,17 @@ should not be interpreted as representing official policies, either expressed or /* The code in its current form adds the license below: -spdlog - an extremely fast and easy to use c++11 logging library. -Copyright (c) 2014 Gabi Melman. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Copyright(c) 2015 Gabi Melman. +Distributed under the MIT License (http://opensource.org/licenses/MIT) + */ #pragma once +#include <spdlog/common.h> + #include <atomic> -#include "../common.h" +#include <utility> namespace spdlog { @@ -76,8 +60,9 @@ public: using item_type = T; mpmc_bounded_queue(size_t buffer_size) - : buffer_(new cell_t [buffer_size]), - buffer_mask_(buffer_size - 1) + :max_size_(buffer_size), + buffer_(new cell_t [buffer_size]), + buffer_mask_(buffer_size - 1) { //queue size must be power of two if(!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0))) @@ -148,6 +133,16 @@ public: return true; } + size_t approx_size() + { + size_t first_pos = dequeue_pos_.load(std::memory_order_relaxed); + size_t last_pos = enqueue_pos_.load(std::memory_order_relaxed); + if (last_pos <= first_pos) + return 0; + auto size = last_pos - first_pos; + return size < max_size_ ? size : max_size_; + } + private: struct cell_t { @@ -155,6 +150,8 @@ private: T data_; }; + size_t const max_size_; + static size_t const cacheline_size = 64; typedef char cacheline_pad_t [cacheline_size]; @@ -167,8 +164,8 @@ private: std::atomic<size_t> dequeue_pos_; cacheline_pad_t pad3_; - mpmc_bounded_queue(mpmc_bounded_queue const&); - void operator = (mpmc_bounded_queue const&); + mpmc_bounded_queue(mpmc_bounded_queue const&) = delete; + void operator= (mpmc_bounded_queue const&) = delete; }; } // ns details http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/939751c1/include/spdlog/details/null_mutex.h ---------------------------------------------------------------------- diff --git a/include/spdlog/details/null_mutex.h b/include/spdlog/details/null_mutex.h index ebb56a5..67b0aee 100644 --- a/include/spdlog/details/null_mutex.h +++ b/include/spdlog/details/null_mutex.h @@ -1,30 +1,12 @@ -/*************************************************************************/ -/* spdlog - an extremely fast and easy to use c++11 logging library. */ -/* Copyright (c) 2014 Gabi Melman. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +// +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// #pragma once -// null, no cost mutex +#include <atomic> +// null, no cost dummy "mutex" and dummy "atomic" int namespace spdlog { @@ -39,5 +21,25 @@ struct null_mutex return true; } }; + +struct null_atomic_int +{ + int value; + null_atomic_int() = default; + + null_atomic_int(int val):value(val) + {} + + int load(std::memory_order) const + { + return value; + } + + void store(int val) + { + value = val; + } +}; + } } http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/939751c1/include/spdlog/details/os.h ---------------------------------------------------------------------- diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 753b6d9..b63ce66 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -1,50 +1,57 @@ -/*************************************************************************/ -/* spdlog - an extremely fast and easy to use c++11 logging library. */ -/* Copyright (c) 2014 Gabi Melman. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - +// +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// #pragma once -#include<string> -#include<cstdio> -#include<ctime> + +#include <spdlog/common.h> + +#include <cstdio> +#include <ctime> +#include <functional> +#include <string> +#include <chrono> +#include <thread> +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> #ifdef _WIN32 -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include <Windows.h> + +#ifndef NOMINMAX +#define NOMINMAX //prevent windows redefining min/max +#endif + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#include <process.h> // _get_pid support +#include <io.h> // _get_osfhandle support #ifdef __MINGW32__ #include <share.h> #endif -#elif __linux__ -#include <sys/syscall.h> //Use gettid() syscall under linux to get thread id +#else // unix + #include <unistd.h> -#else -#include <thread> +#include <fcntl.h> + +#ifdef __linux__ +#include <sys/syscall.h> //Use gettid() syscall under linux to get thread id + +#elif __FreeBSD__ +#include <sys/thr.h> //Use thr_self() syscall under FreeBSD to get thread id +#endif + +#endif //unix + +#ifndef __has_feature // Clang - feature checking macros. +#define __has_feature(x) 0 // Compatibility with non-clang compilers. #endif -#include "../common.h" namespace spdlog { @@ -63,6 +70,7 @@ inline spdlog::log_clock::time_point now() std::chrono::duration_cast<typename log_clock::duration>( std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec))); + #else return log_clock::now(); #endif @@ -122,77 +130,277 @@ inline bool operator!=(const std::tm& tm1, const std::tm& tm2) return !(tm1 == tm2); } +// eol definition +#if !defined (SPDLOG_EOL) #ifdef _WIN32 -inline const char* eol() -{ - return "\r\n"; -} +#define SPDLOG_EOL "\r\n" #else -constexpr inline const char* eol() -{ - return "\n"; -} +#define SPDLOG_EOL "\n" +#endif #endif -#ifdef _WIN32 -inline unsigned short eol_size() +SPDLOG_CONSTEXPR static const char* eol = SPDLOG_EOL; +SPDLOG_CONSTEXPR static int eol_size = sizeof(SPDLOG_EOL) - 1; + +inline void prevent_child_fd(FILE *f) { - return 2; +#ifdef _WIN32 + auto file_handle = (HANDLE)_get_osfhandle(_fileno(f)); + if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0)) + throw spdlog_ex("SetHandleInformation failed", errno); +#else + auto fd = fileno(f); + if(fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + throw spdlog_ex("fcntl with FD_CLOEXEC failed", errno); +#endif } + + +//fopen_s on non windows for writing +inline int fopen_s(FILE** fp, const filename_t& filename, const filename_t& mode) +{ +#ifdef _WIN32 +#ifdef SPDLOG_WCHAR_FILENAMES + *fp = _wfsopen((filename.c_str()), mode.c_str(), _SH_DENYWR); #else -constexpr inline unsigned short eol_size() + *fp = _fsopen((filename.c_str()), mode.c_str(), _SH_DENYWR); +#endif +#else //unix + *fp = fopen((filename.c_str()), mode.c_str()); +#endif + +#ifdef SPDLOG_PREVENT_CHILD_FD + if(*fp != nullptr) + prevent_child_fd(*fp); +#endif + return *fp == nullptr; +} + + +inline int remove(const filename_t &filename) { - return 1; +#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) + return _wremove(filename.c_str()); +#else + return std::remove(filename.c_str()); +#endif } + +inline int rename(const filename_t& filename1, const filename_t& filename2) +{ +#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) + return _wrename(filename1.c_str(), filename2.c_str()); +#else + return std::rename(filename1.c_str(), filename2.c_str()); #endif +} -//fopen_s on non windows for writing -inline int fopen_s(FILE** fp, const std::string& filename, const char* mode) + +//Return if file exists +inline bool file_exists(const filename_t& filename) { #ifdef _WIN32 - *fp = _fsopen((filename.c_str()), mode, _SH_DENYWR); - return *fp == nullptr; +#ifdef SPDLOG_WCHAR_FILENAMES + auto attribs = GetFileAttributesW(filename.c_str()); #else - *fp = fopen((filename.c_str()), mode); - return *fp == nullptr; + auto attribs = GetFileAttributesA(filename.c_str()); +#endif + return (attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY)); +#else //common linux/unix all have the stat system call + struct stat buffer; + return (stat (filename.c_str(), &buffer) == 0); #endif +} + + +//Return file size according to open FILE* object +inline size_t filesize(FILE *f) +{ + if (f == nullptr) + throw spdlog_ex("Failed getting file size. fd is null"); +#ifdef _WIN32 + int fd = _fileno(f); +#if _WIN64 //64 bits + struct _stat64 st; + if (_fstat64(fd, &st) == 0) + return st.st_size; + +#else //windows 32 bits + long ret = _filelength(fd); + if (ret >= 0) + return static_cast<size_t>(ret); +#endif + +#else // unix + int fd = fileno(f); + //64 bits(but not in osx, where fstat64 is deprecated) +#if !defined(__FreeBSD__) && !defined(__APPLE__) && (defined(__x86_64__) || defined(__ppc64__)) + struct stat64 st; + if (fstat64(fd, &st) == 0) + return static_cast<size_t>(st.st_size); +#else // unix 32 bits or osx + struct stat st; + if (fstat(fd, &st) == 0) + return static_cast<size_t>(st.st_size); +#endif +#endif + throw spdlog_ex("Failed getting file size from fd", errno); } -//Return utc offset in minutes or -1 on failure + + + +//Return utc offset in minutes or throw spdlog_ex on failure inline int utc_minutes_offset(const std::tm& tm = details::os::localtime()) { #ifdef _WIN32 - (void)tm; // avoid unused param warning +#if _WIN32_WINNT < _WIN32_WINNT_WS08 + TIME_ZONE_INFORMATION tzinfo; + auto rv = GetTimeZoneInformation(&tzinfo); +#else DYNAMIC_TIME_ZONE_INFORMATION tzinfo; auto rv = GetDynamicTimeZoneInformation(&tzinfo); - if (!rv) - return -1; - return -1 * (tzinfo.Bias + tzinfo.DaylightBias); +#endif + if (rv == TIME_ZONE_ID_INVALID) + throw spdlog::spdlog_ex("Failed getting timezone info. ", errno); + + int offset = -tzinfo.Bias; + if (tm.tm_isdst) + offset -= tzinfo.DaylightBias; + else + offset -= tzinfo.StandardBias; + return offset; +#else + +#if defined(sun) || defined(__sun) + // 'tm_gmtoff' field is BSD extension and it's missing on SunOS/Solaris + struct helper + { + static long int calculate_gmt_offset(const std::tm & localtm = details::os::localtime(), const std::tm & gmtm = details::os::gmtime()) + { + int local_year = localtm.tm_year + (1900 - 1); + int gmt_year = gmtm.tm_year + (1900 - 1); + + long int days = ( + // difference in day of year + localtm.tm_yday - gmtm.tm_yday + + // + intervening leap days + + ((local_year >> 2) - (gmt_year >> 2)) + - (local_year / 100 - gmt_year / 100) + + ((local_year / 100 >> 2) - (gmt_year / 100 >> 2)) + + // + difference in years * 365 */ + + (long int)(local_year - gmt_year) * 365 + ); + + long int hours = (24 * days) + (localtm.tm_hour - gmtm.tm_hour); + long int mins = (60 * hours) + (localtm.tm_min - gmtm.tm_min); + long int secs = (60 * mins) + (localtm.tm_sec - gmtm.tm_sec); + + return secs; + } + }; + + long int offset_seconds = helper::calculate_gmt_offset(tm); #else - return static_cast<int>(tm.tm_gmtoff / 60); + long int offset_seconds = tm.tm_gmtoff; +#endif + + return static_cast<int>(offset_seconds / 60); #endif } //Return current thread id as size_t //It exists because the std::this_thread::get_id() is much slower(espcially under VS 2013) -inline size_t thread_id() +inline size_t _thread_id() { #ifdef _WIN32 return static_cast<size_t>(::GetCurrentThreadId()); #elif __linux__ +# if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21) +# define SYS_gettid __NR_gettid +# endif return static_cast<size_t>(syscall(SYS_gettid)); +#elif __FreeBSD__ + long tid; + thr_self(&tid); + return static_cast<size_t>(tid); #else //Default to standard C++11 (OSX and other Unix) return static_cast<size_t>(std::hash<std::thread::id>()(std::this_thread::get_id())); #endif +} +//Return current thread id as size_t (from thread local storage) +inline size_t thread_id() +{ +#if defined(_MSC_VER) && (_MSC_VER < 1900) || defined(__clang__) && !__has_feature(cxx_thread_local) + return _thread_id(); +#else + static thread_local const size_t tid = _thread_id(); + return tid; +#endif } -} //os -} //details -} //spdlog +// wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined) +#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) +#define SPDLOG_FILENAME_T(s) L ## s +inline std::string filename_to_str(const filename_t& filename) +{ + std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> c; + return c.to_bytes(filename); +} +#else +#define SPDLOG_FILENAME_T(s) s +inline std::string filename_to_str(const filename_t& filename) +{ + return filename; +} +#endif + + +// Return errno string (thread safe) +inline std::string errno_str(int err_num) +{ + char buf[256]; + SPDLOG_CONSTEXPR auto buf_size = sizeof(buf); + +#ifdef _WIN32 + if(strerror_s(buf, buf_size, err_num) == 0) + return std::string(buf); + else + return "Unkown error"; + +#elif defined(__FreeBSD__) || defined(__APPLE__) || defined(ANDROID) || defined(__SUNPRO_CC) || \ + ((_POSIX_C_SOURCE >= 200112L) && ! defined(_GNU_SOURCE)) // posix version + + if (strerror_r(err_num, buf, buf_size) == 0) + return std::string(buf); + else + return "Unkown error"; + +#else // gnu version (might not use the given buf, so its retval pointer must be used) + return std::string(strerror_r(err_num, buf, buf_size)); +#endif +} + +inline int pid() +{ + +#ifdef _WIN32 + return ::_getpid(); +#else + return static_cast<int>(::getpid()); +#endif + +} + +} //os +} //details +} //spdlog http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/939751c1/include/spdlog/details/pattern_formatter_impl.h ---------------------------------------------------------------------- diff --git a/include/spdlog/details/pattern_formatter_impl.h b/include/spdlog/details/pattern_formatter_impl.h index a5b2d21..2fefaa3 100644 --- a/include/spdlog/details/pattern_formatter_impl.h +++ b/include/spdlog/details/pattern_formatter_impl.h @@ -1,39 +1,24 @@ -/*************************************************************************/ -/* spdlog - an extremely fast and easy to use c++11 logging library. */ -/* Copyright (c) 2014 Gabi Melman. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +// +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// #pragma once -#include <string> +#include <spdlog/formatter.h> +#include <spdlog/details/log_msg.h> +#include <spdlog/details/os.h> +#include <spdlog/fmt/fmt.h> + #include <chrono> +#include <ctime> #include <memory> -#include <vector> +#include <mutex> +#include <string> #include <thread> - - -#include "../formatter.h" -#include "./log_msg.h" -#include "./os.h" +#include <utility> +#include <vector> +#include <array> namespace spdlog { @@ -42,7 +27,8 @@ namespace details class flag_formatter { public: - virtual ~flag_formatter() {} + virtual ~flag_formatter() + {} virtual void format(details::log_msg& msg, const std::tm& tm_time) = 0; }; @@ -51,17 +37,17 @@ public: /////////////////////////////////////////////////////////////////////// namespace { -class name_formatter :public flag_formatter +class name_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { - msg.formatted << msg.logger_name; + msg.formatted << *msg.logger_name; } }; } // log level appender -class level_formatter :public flag_formatter +class level_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -70,7 +56,7 @@ class level_formatter :public flag_formatter }; // short log level appender -class short_level_formatter :public flag_formatter +class short_level_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -93,42 +79,60 @@ static int to12h(const tm& t) } //Abbreviated weekday name -static const std::string days[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; -class a_formatter :public flag_formatter +using days_array = std::array<std::string, 7>; +static const days_array& days() +{ + static const days_array arr{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; + return arr; +} +class a_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { - msg.formatted << days[tm_time.tm_wday]; + msg.formatted << days()[tm_time.tm_wday]; } }; //Full weekday name -static const std::string full_days[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; -class A_formatter :public flag_formatter +static const days_array& full_days() +{ + static const days_array arr{ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; + return arr; +} +class A_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { - msg.formatted << full_days[tm_time.tm_wday]; + msg.formatted << full_days()[tm_time.tm_wday]; } }; //Abbreviated month -static const std::string months[] { "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec" }; -class b_formatter :public flag_formatter +using months_array = std::array<std::string, 12>; +static const months_array& months() +{ + static const months_array arr{ "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec" }; + return arr; +} +class b_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { - msg.formatted<< months[tm_time.tm_mon]; + msg.formatted << months()[tm_time.tm_mon]; } }; //Full month name -static const std::string full_months[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; -class B_formatter :public flag_formatter +static const months_array& full_months() +{ + static const months_array arr{ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + return arr; +} +class B_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { - msg.formatted << full_months[tm_time.tm_mon]; + msg.formatted << full_months()[tm_time.tm_mon]; } }; @@ -149,18 +153,18 @@ static fmt::MemoryWriter& pad_n_join(fmt::MemoryWriter& w, int v1, int v2, int v //Date and time representation (Thu Aug 23 15:35:46 2014) -class c_formatter :public flag_formatter +class c_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { - msg.formatted << days[tm_time.tm_wday] << ' ' << months[tm_time.tm_mon] << ' ' << tm_time.tm_mday << ' '; + msg.formatted << days()[tm_time.tm_wday] << ' ' << months()[tm_time.tm_mon] << ' ' << tm_time.tm_mday << ' '; pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, ':') << ' ' << tm_time.tm_year + 1900; } }; // year - 2 digit -class C_formatter :public flag_formatter +class C_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -171,7 +175,7 @@ class C_formatter :public flag_formatter // Short MM/DD/YY date, equivalent to %m/%d/%y 08/23/01 -class D_formatter :public flag_formatter +class D_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -181,7 +185,7 @@ class D_formatter :public flag_formatter // year - 4 digit -class Y_formatter :public flag_formatter +class Y_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -190,7 +194,7 @@ class Y_formatter :public flag_formatter }; // month 1-12 -class m_formatter :public flag_formatter +class m_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -199,7 +203,7 @@ class m_formatter :public flag_formatter }; // day of month 1-31 -class d_formatter :public flag_formatter +class d_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -208,7 +212,7 @@ class d_formatter :public flag_formatter }; // hours in 24 format 0-23 -class H_formatter :public flag_formatter +class H_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -217,7 +221,7 @@ class H_formatter :public flag_formatter }; // hours in 12 format 1-12 -class I_formatter :public flag_formatter +class I_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -225,8 +229,8 @@ class I_formatter :public flag_formatter } }; -// ninutes 0-59 -class M_formatter :public flag_formatter +// minutes 0-59 +class M_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -235,7 +239,7 @@ class M_formatter :public flag_formatter }; // seconds 0-59 -class S_formatter :public flag_formatter +class S_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -244,7 +248,7 @@ class S_formatter :public flag_formatter }; // milliseconds -class e_formatter :public flag_formatter +class e_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -255,7 +259,7 @@ class e_formatter :public flag_formatter }; // microseconds -class f_formatter :public flag_formatter +class f_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -265,8 +269,19 @@ class f_formatter :public flag_formatter } }; +// nanoseconds +class F_formatter:public flag_formatter +{ + void format(details::log_msg& msg, const std::tm&) override + { + auto duration = msg.time.time_since_epoch(); + auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count() % 1000000000; + msg.formatted << fmt::pad(static_cast<int>(ns), 9, '0'); + } +}; + // AM/PM -class p_formatter :public flag_formatter +class p_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -276,7 +291,7 @@ class p_formatter :public flag_formatter // 12 hour clock 02:55:02 pm -class r_formatter :public flag_formatter +class r_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -285,7 +300,7 @@ class r_formatter :public flag_formatter }; // 24-hour HH:MM time, equivalent to %H:%M -class R_formatter :public flag_formatter +class R_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -294,7 +309,7 @@ class R_formatter :public flag_formatter }; // ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S -class T_formatter :public flag_formatter +class T_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -304,12 +319,13 @@ class T_formatter :public flag_formatter // ISO 8601 offset from UTC in timezone (+-HH:MM) -class z_formatter :public flag_formatter +class z_formatter:public flag_formatter { public: const std::chrono::seconds cache_refresh = std::chrono::seconds(5); - z_formatter() :_last_update(std::chrono::seconds(0)) {} + z_formatter():_last_update(std::chrono::seconds(0)) + {} z_formatter(const z_formatter&) = delete; z_formatter& operator=(const z_formatter&) = delete; @@ -322,10 +338,20 @@ public: // it is very fast (already stored in tm.tm_gmtoff) int total_minutes = os::utc_minutes_offset(tm_time); #endif + bool is_negative = total_minutes < 0; + char sign; + if (is_negative) + { + total_minutes = -total_minutes; + sign = '-'; + } + else + { + sign = '+'; + } int h = total_minutes / 60; int m = total_minutes % 60; - char sign = h >= 0 ? '+' : '-'; msg.formatted << sign; pad_n_join(msg.formatted, h, m, ':'); } @@ -349,8 +375,8 @@ private: -//Thread id -class t_formatter :public flag_formatter +// Thread id +class t_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -358,8 +384,17 @@ class t_formatter :public flag_formatter } }; +// Current pid +class pid_formatter:public flag_formatter +{ + void format(details::log_msg& msg, const std::tm&) override + { + msg.formatted << details::os::pid(); + } +}; + -class v_formatter :public flag_formatter +class v_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -367,10 +402,10 @@ class v_formatter :public flag_formatter } }; -class ch_formatter :public flag_formatter +class ch_formatter:public flag_formatter { public: - explicit ch_formatter(char ch) : _ch(ch) + explicit ch_formatter(char ch): _ch(ch) {} void format(details::log_msg& msg, const std::tm&) override { @@ -382,7 +417,7 @@ private: //aggregate user chars to display as is -class aggregate_formatter :public flag_formatter +class aggregate_formatter:public flag_formatter { public: aggregate_formatter() @@ -401,7 +436,7 @@ private: // Full info formatter // pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v -class full_formatter :public flag_formatter +class full_formatter:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -432,13 +467,13 @@ class full_formatter :public flag_formatter << fmt::pad(static_cast<unsigned int>(tm_time.tm_sec), 2, '0') << '.' << fmt::pad(static_cast<unsigned int>(millis), 3, '0') << "] "; -//no datetime needed + //no datetime needed #else (void)tm_time; #endif #ifndef SPDLOG_NO_NAME - msg.formatted << '[' << msg.logger_name << "] "; + msg.formatted << '[' << *msg.logger_name << "] "; #endif msg.formatted << '[' << level::to_str(msg.level) << "] "; @@ -446,6 +481,8 @@ class full_formatter :public flag_formatter } }; + + } } /////////////////////////////////////////////////////////////////////////////// @@ -502,98 +539,101 @@ inline void spdlog::pattern_formatter::handle_flag(char flag) _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::short_level_formatter())); break; - case('t') : + case('t'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::t_formatter())); break; - case('v') : + case('v'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::v_formatter())); break; - case('a') : + case('a'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::a_formatter())); break; - case('A') : + case('A'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::A_formatter())); break; - case('b') : - case('h') : + case('b'): + case('h'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::b_formatter())); break; - case('B') : + case('B'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::B_formatter())); break; - case('c') : + case('c'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::c_formatter())); break; - case('C') : + case('C'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::C_formatter())); break; - case('Y') : + case('Y'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::Y_formatter())); break; - case('D') : - case('x') : + case('D'): + case('x'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::D_formatter())); break; - case('m') : + case('m'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::m_formatter())); break; - case('d') : + case('d'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::d_formatter())); break; - case('H') : + case('H'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::H_formatter())); break; - case('I') : + case('I'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::I_formatter())); break; - case('M') : + case('M'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::M_formatter())); break; - case('S') : + case('S'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::S_formatter())); break; - case('e') : + case('e'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::e_formatter())); break; - case('f') : + case('f'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::f_formatter())); break; + case('F'): + _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::F_formatter())); + break; - case('p') : + case('p'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::p_formatter())); break; - case('r') : + case('r'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::r_formatter())); break; - case('R') : + case('R'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::R_formatter())); break; - case('T') : - case('X') : + case('T'): + case('X'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::T_formatter())); break; - case('z') : + case('z'): _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::z_formatter())); break; @@ -601,6 +641,10 @@ inline void spdlog::pattern_formatter::handle_flag(char flag) _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::full_formatter())); break; + case ('P'): + _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::pid_formatter())); + break; + default: //Unkown flag appears as is _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::ch_formatter('%'))); _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::ch_formatter(flag))); @@ -611,18 +655,16 @@ inline void spdlog::pattern_formatter::handle_flag(char flag) inline void spdlog::pattern_formatter::format(details::log_msg& msg) { - try - { - auto tm_time = details::os::localtime(log_clock::to_time_t(msg.time)); - for (auto &f : _formatters) - { - f->format(msg, tm_time); - } - //write eol - msg.formatted << details::os::eol(); - } - catch(const fmt::FormatError& e) + +#ifndef SPDLOG_NO_DATETIME + auto tm_time = details::os::localtime(log_clock::to_time_t(msg.time)); +#else + std::tm tm_time; +#endif + for (auto &f : _formatters) { - throw spdlog_ex(fmt::format("formatting error while processing format string: {}", e.what())); + f->format(msg, tm_time); } + //write eol + msg.formatted.write(details::os::eol, details::os::eol_size); } http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/939751c1/include/spdlog/details/registry.h ---------------------------------------------------------------------- diff --git a/include/spdlog/details/registry.h b/include/spdlog/details/registry.h index fd8e4be..ee14adf 100644 --- a/include/spdlog/details/registry.h +++ b/include/spdlog/details/registry.h @@ -1,42 +1,26 @@ -/*************************************************************************/ -/* spdlog - an extremely fast and easy to use c++11 logging library. */ -/* Copyright (c) 2014 Gabi Melman. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +// +// 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 alreasy existing name will be ignored +// 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 <string> +#include <spdlog/details/null_mutex.h> +#include <spdlog/logger.h> +#include <spdlog/async_logger.h> +#include <spdlog/common.h> + +#include <chrono> +#include <functional> +#include <memory> #include <mutex> +#include <string> #include <unordered_map> -#include <functional> - -#include "./null_mutex.h" -#include "../logger.h" -#include "../async_logger.h" -#include "../common.h" namespace spdlog { @@ -49,7 +33,9 @@ public: void register_logger(std::shared_ptr<logger> logger) { std::lock_guard<Mutex> lock(_mutex); - register_logger_impl(logger); + auto logger_name = logger->name(); + throw_if_exists(logger_name); + _loggers[logger_name] = logger; } @@ -63,25 +49,35 @@ public: template<class It> std::shared_ptr<logger> create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) { - - std::shared_ptr<logger> new_logger; - std::lock_guard<Mutex> lock(_mutex); - - + 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); + 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); - register_logger_impl(new_logger); + + + //Add to registry + _loggers[logger_name] = new_logger; return new_logger; } + void apply_all(std::function<void(std::shared_ptr<logger>)> fun) + { + std::lock_guard<Mutex> lock(_mutex); + for (auto &l : _loggers) + fun(l.second); + } + void drop(const std::string& logger_name) { std::lock_guard<Mutex> lock(_mutex); @@ -128,7 +124,14 @@ public: _level = log_level; } - 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) + void set_error_handler(log_err_handler handler) + { + for (auto& l : _loggers) + l.second->set_error_handler(handler); + _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) { std::lock_guard<Mutex> lock(_mutex); _async_mode = true; @@ -136,6 +139,7 @@ public: _overflow_policy = overflow_policy; _worker_warmup_cb = worker_warmup_cb; _flush_interval_ms = flush_interval_ms; + _worker_teardown_cb = worker_teardown_cb; } void set_sync_mode() @@ -151,25 +155,26 @@ public: } private: - void register_logger_impl(std::shared_ptr<logger> logger) - { - auto logger_name = logger->name(); - if (_loggers.find(logger_name) != std::end(_loggers)) - throw spdlog_ex("logger with name " + logger_name + " already exists"); - _loggers[logger->name()] = logger; - } - registry_t<Mutex>(){} + registry_t<Mutex>() {} registry_t<Mutex>(const registry_t<Mutex>&) = delete; registry_t<Mutex>& operator=(const registry_t<Mutex>&) = delete; + + void 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"); + } Mutex _mutex; std::unordered_map <std::string, std::shared_ptr<logger>> _loggers; formatter_ptr _formatter; level::level_enum _level = level::info; + 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 = nullptr; std::chrono::milliseconds _flush_interval_ms; + std::function<void()> _worker_teardown_cb = nullptr; }; #ifdef SPDLOG_NO_REGISTRY_MUTEX typedef registry_t<spdlog::details::null_mutex> registry; http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/939751c1/include/spdlog/details/spdlog_impl.h ---------------------------------------------------------------------- diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index cfd6f82..a8011db 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -1,36 +1,36 @@ -/*************************************************************************/ -/* spdlog - an extremely fast and easy to use c++11 logging library. */ -/* Copyright (c) 2014 Gabi Melman. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +// +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// #pragma once // // Global registry functions // -#include "registry.h" -#include "../sinks/file_sinks.h" -#include "../sinks/stdout_sinks.h" -#include "../sinks/syslog_sink.h" +#include <spdlog/spdlog.h> +#include <spdlog/details/registry.h> +#include <spdlog/sinks/file_sinks.h> +#include <spdlog/sinks/stdout_sinks.h> +#ifdef SPDLOG_ENABLE_SYSLOG +#include <spdlog/sinks/syslog_sink.h> +#endif + +#ifdef _WIN32 +#include <spdlog/sinks/wincolor_sink.h> +#else +#include <spdlog/sinks/ansicolor_sink.h> +#endif + + +#ifdef __ANDROID__ +#include <spdlog/sinks/android_sink.h> +#endif + +#include <chrono> +#include <functional> +#include <memory> +#include <string> inline void spdlog::register_logger(std::shared_ptr<logger> logger) { @@ -47,50 +47,120 @@ inline void spdlog::drop(const std::string &name) details::registry::instance().drop(name); } +// Create multi/single threaded simple file logger +inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_mt(const std::string& logger_name, const filename_t& filename, bool truncate) +{ + return create<spdlog::sinks::simple_file_sink_mt>(logger_name, filename, truncate); +} + +inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_st(const std::string& logger_name, const filename_t& filename, bool truncate) +{ + return create<spdlog::sinks::simple_file_sink_st>(logger_name, filename, truncate); +} + // Create multi/single threaded rotating file logger -inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_mt(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool force_flush) +inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_mt(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files) { - return create<spdlog::sinks::rotating_file_sink_mt>(logger_name, filename, "txt", max_file_size, max_files, force_flush); + return create<spdlog::sinks::rotating_file_sink_mt>(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files); } -inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_st(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool force_flush) +inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_st(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files) { - return create<spdlog::sinks::rotating_file_sink_st>(logger_name, filename, "txt", max_file_size, max_files, force_flush); + return create<spdlog::sinks::rotating_file_sink_st>(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files); } // Create file logger which creates new file at midnight): -inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_mt(const std::string& logger_name, const std::string& filename, int hour, int minute, bool force_flush) +inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_mt(const std::string& logger_name, const filename_t& filename, int hour, int minute) { - return create<spdlog::sinks::daily_file_sink_mt>(logger_name, filename, "txt", hour, minute, force_flush); + return create<spdlog::sinks::daily_file_sink_mt>(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute); } -inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_st(const std::string& logger_name, const std::string& filename, int hour, int minute, bool force_flush) + +inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_st(const std::string& logger_name, const filename_t& filename, int hour, int minute) { - return create<spdlog::sinks::daily_file_sink_st>(logger_name, filename, "txt", hour, minute, force_flush); + return create<spdlog::sinks::daily_file_sink_st>(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute); } -// Create stdout/stderr loggers +// +// stdout/stderr loggers +// inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt(const std::string& logger_name) { - return details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_mt::instance()); + return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_mt::instance()); } inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st(const std::string& logger_name) { - return details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_st::instance()); + return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_st::instance()); } inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt(const std::string& logger_name) { - return details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_mt::instance()); + return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_mt::instance()); } inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::string& logger_name) { - return details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_st::instance()); + return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_st::instance()); +} + +// +// stdout/stderr color loggers +// +#ifdef _WIN32 +inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string& logger_name) +{ + auto sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_mt>(); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_st(const std::string& logger_name) +{ + auto sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_st>(); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string& logger_name) +{ + auto sink = std::make_shared<spdlog::sinks::wincolor_stderr_sink_mt>(); + return spdlog::details::registry::instance().create(logger_name, sink); +} + + +inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string& logger_name) +{ + auto sink = std::make_shared<spdlog::sinks::wincolor_stderr_sink_st>(); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +#else //ansi terminal colors + +inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string& logger_name) +{ + auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stdout_sink_mt::instance()); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_st(const std::string& logger_name) +{ + auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stdout_sink_st::instance()); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string& logger_name) +{ + auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stderr_sink_mt::instance()); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string& logger_name) +{ + auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stderr_sink_st::instance()); + return spdlog::details::registry::instance().create(logger_name, sink); } +#endif -#ifdef __linux__ +#ifdef SPDLOG_ENABLE_SYSLOG // Create syslog logger inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option) { @@ -98,6 +168,18 @@ inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string& } #endif +#ifdef __ANDROID__ +inline std::shared_ptr<spdlog::logger> spdlog::android_logger(const std::string& logger_name, const std::string& tag) +{ + return create<spdlog::sinks::android_sink>(logger_name, tag); +} +#endif + +// Create and register a logger a single sink +inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const spdlog::sink_ptr& sink) +{ + return details::registry::instance().create(logger_name, sink); +} //Create logger with multiple sinks @@ -108,7 +190,7 @@ inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_ template <typename Sink, typename... Args> -inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const Args&... args) +inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, Args... args) { sink_ptr sink = std::make_shared<Sink>(args...); return details::registry::instance().create(logger_name, { sink }); @@ -136,10 +218,15 @@ inline void spdlog::set_level(level::level_enum log_level) return details::registry::instance().set_level(log_level); } +inline void spdlog::set_error_handler(log_err_handler handler) +{ + return details::registry::instance().set_error_handler(handler); +} -inline void spdlog::set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms) + +inline void spdlog::set_async_mode(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) { - details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms); + details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb); } inline void spdlog::set_sync_mode() @@ -147,8 +234,12 @@ inline void spdlog::set_sync_mode() details::registry::instance().set_sync_mode(); } +inline void spdlog::apply_all(std::function<void(std::shared_ptr<logger>)> fun) +{ + details::registry::instance().apply_all(fun); +} + inline void spdlog::drop_all() { details::registry::instance().drop_all(); } -
