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();
 }
-

Reply via email to