static lib wip
This commit is contained in:
		@@ -14,8 +14,9 @@ spdlog::logger *get_logger();
 | 
			
		||||
int main(int, char *[])
 | 
			
		||||
{    
 | 
			
		||||
    auto *l = get_logger();
 | 
			
		||||
    l->info("HELLO  {}", "GA");    	
 | 
			
		||||
    l->error("Some {}", "error");
 | 
			
		||||
    l->info("HE LO ", "GA");    	
 | 
			
		||||
	l->error("Some {} {} {}", "er or");
 | 
			
		||||
    l->error("Some {} {} {}", "er or");
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -9,22 +9,16 @@
 | 
			
		||||
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <initializer_list>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <type_traits>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
 | 
			
		||||
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
 | 
			
		||||
#include <codecvt>
 | 
			
		||||
#include <locale>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "spdlog/details/null_mutex.h"
 | 
			
		||||
 | 
			
		||||
#include "spdlog/fmt/fmt.h"
 | 
			
		||||
 | 
			
		||||
#ifdef SPDLOG_HEADER_ONLY
 | 
			
		||||
@@ -75,6 +69,17 @@
 | 
			
		||||
#define SPDLOG_FUNCTION __FUNCTION__
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
 | 
			
		||||
#define SPDLOG_FILENAME_T(s) L##s
 | 
			
		||||
SPDLOG_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
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace spdlog {
 | 
			
		||||
 | 
			
		||||
class formatter;
 | 
			
		||||
@@ -86,7 +91,6 @@ class sink;
 | 
			
		||||
using log_clock = std::chrono::system_clock;
 | 
			
		||||
using sink_ptr = std::shared_ptr<sinks::sink>;
 | 
			
		||||
using sinks_init_list = std::initializer_list<sink_ptr>;
 | 
			
		||||
using log_err_handler = std::function<void(const std::string &err_msg)>;
 | 
			
		||||
 | 
			
		||||
// string_view type - either std::string_view or fmt::string_view (pre c++17)
 | 
			
		||||
#if defined(FMT_USE_STD_STRING_VIEW)
 | 
			
		||||
 
 | 
			
		||||
@@ -38,9 +38,6 @@ inline spdlog::async_logger::async_logger(
 | 
			
		||||
// send the log message to the thread pool
 | 
			
		||||
inline void spdlog::async_logger::sink_it_(details::log_msg &msg)
 | 
			
		||||
{
 | 
			
		||||
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
 | 
			
		||||
    incr_msg_counter_(msg);
 | 
			
		||||
#endif
 | 
			
		||||
    if (auto pool_ptr = thread_pool_.lock())
 | 
			
		||||
    {
 | 
			
		||||
        pool_ptr->post_log(shared_from_this(), msg, overflow_policy_);
 | 
			
		||||
@@ -119,6 +116,6 @@ inline std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::string n
 | 
			
		||||
 | 
			
		||||
    cloned->set_level(this->level());
 | 
			
		||||
    cloned->flush_on(this->flush_level());
 | 
			
		||||
    cloned->set_error_handler(this->error_handler());
 | 
			
		||||
    cloned->set_error_handler(this->custom_err_handler_);
 | 
			
		||||
    return std::move(cloned);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -154,7 +154,7 @@ public:
 | 
			
		||||
        periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_error_handler(log_err_handler handler)
 | 
			
		||||
    void set_error_handler(void (*handler)(const std::string &msg))
 | 
			
		||||
    {
 | 
			
		||||
        std::lock_guard<std::mutex> lock(logger_map_mutex_);
 | 
			
		||||
        for (auto &l : loggers_)
 | 
			
		||||
@@ -275,7 +275,7 @@ private:
 | 
			
		||||
    std::unique_ptr<formatter> formatter_;
 | 
			
		||||
    level::level_enum level_ = spdlog::logger::default_level();
 | 
			
		||||
    level::level_enum flush_level_ = level::off;
 | 
			
		||||
    log_err_handler err_handler_;
 | 
			
		||||
    void (*err_handler_)(const std::string &msg);
 | 
			
		||||
    std::shared_ptr<thread_pool> tp_;
 | 
			
		||||
    std::unique_ptr<periodic_worker> periodic_flusher_;
 | 
			
		||||
    std::shared_ptr<logger> default_logger_;
 | 
			
		||||
 
 | 
			
		||||
@@ -17,22 +17,17 @@
 | 
			
		||||
// The use of private formatter per sink provides the opportunity to cache some
 | 
			
		||||
// formatted data, and support for different format per sink.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "spdlog/common.h"
 | 
			
		||||
#include "spdlog/details/log_msg.h"
 | 
			
		||||
 | 
			
		||||
//#include "spdlog/formatter.h"
 | 
			
		||||
//#include "spdlog/sinks/sink.h"
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
namespace spdlog
 | 
			
		||||
namespace spdlog {
 | 
			
		||||
class logger
 | 
			
		||||
{
 | 
			
		||||
    class logger
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
public:
 | 
			
		||||
        template<typename It>
 | 
			
		||||
        logger(std::string name, It begin, It end)
 | 
			
		||||
            : name_(std::move(name))
 | 
			
		||||
@@ -57,32 +52,32 @@ namespace spdlog
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void log(source_loc loc, level::level_enum lvl, const char *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            if (!should_log(lvl))
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        if (!should_log(lvl))
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {                
 | 
			
		||||
                fmt::memory_buffer buf;
 | 
			
		||||
                fmt::format_to(buf, fmt, args...);
 | 
			
		||||
                details::log_msg log_msg(loc, &name_, lvl, string_view_t(buf.data(), buf.size()));
 | 
			
		||||
                sink_it_(log_msg);
 | 
			
		||||
            }
 | 
			
		||||
            catch (const std::exception &ex)
 | 
			
		||||
            {
 | 
			
		||||
                err_handler_(ex.what());
 | 
			
		||||
            }
 | 
			
		||||
            catch (...)
 | 
			
		||||
            {
 | 
			
		||||
                err_handler_("Unknown exception in logger");
 | 
			
		||||
            }
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            fmt::memory_buffer buf;
 | 
			
		||||
            fmt::format_to(buf, fmt, args...);
 | 
			
		||||
            details::log_msg log_msg(loc, &name_, lvl, string_view_t(buf.data(), buf.size()));
 | 
			
		||||
            sink_it_(log_msg);
 | 
			
		||||
        }
 | 
			
		||||
        catch (const std::exception &ex)
 | 
			
		||||
        {
 | 
			
		||||
            err_handler_(ex.what());
 | 
			
		||||
        }
 | 
			
		||||
        catch (...)
 | 
			
		||||
        {
 | 
			
		||||
            err_handler_("Unknown exception in logger");
 | 
			
		||||
        }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void log(level::level_enum lvl, const char *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(source_loc{}, lvl, fmt, args...);
 | 
			
		||||
        log(source_loc{}, lvl, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
        void log(source_loc loc, level::level_enum lvl, const char *msg);
 | 
			
		||||
        void log(level::level_enum lvl, const char *msg);
 | 
			
		||||
@@ -90,37 +85,37 @@ namespace spdlog
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void trace(const char *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::trace, fmt, args...);
 | 
			
		||||
        log(level::trace, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void debug(const char *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::debug, fmt, args...);
 | 
			
		||||
        log(level::debug, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void info(const char *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::info, fmt, args...);
 | 
			
		||||
        log(level::info, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void warn(const char *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::warn, fmt, args...);
 | 
			
		||||
        log(level::warn, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void error(const char *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::err, fmt, args...);
 | 
			
		||||
        log(level::err, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void critical(const char *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::critical, fmt, args...);
 | 
			
		||||
        log(level::critical, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
 | 
			
		||||
@@ -129,87 +124,87 @@ namespace spdlog
 | 
			
		||||
#else
 | 
			
		||||
        inline void wbuf_to_utf8buf(const fmt::wmemory_buffer &wbuf, fmt::memory_buffer &target)
 | 
			
		||||
        {
 | 
			
		||||
            int wbuf_size = static_cast<int>(wbuf.size());
 | 
			
		||||
            if (wbuf_size == 0)
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        int wbuf_size = static_cast<int>(wbuf.size());
 | 
			
		||||
        if (wbuf_size == 0)
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            auto result_size = ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, NULL, 0, NULL, NULL);
 | 
			
		||||
        auto result_size = ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, NULL, 0, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
            if (result_size > 0)
 | 
			
		||||
            {
 | 
			
		||||
                target.resize(result_size);
 | 
			
		||||
                ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, &target.data()[0], result_size, NULL, NULL);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                throw spdlog::spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()));
 | 
			
		||||
            }
 | 
			
		||||
        if (result_size > 0)
 | 
			
		||||
        {
 | 
			
		||||
            target.resize(result_size);
 | 
			
		||||
            ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, &target.data()[0], result_size, NULL, NULL);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw spdlog::spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()));
 | 
			
		||||
        }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void log(source_loc source, level::level_enum lvl, const wchar_t *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            if (!should_log(lvl))
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        if (!should_log(lvl))
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                // format to wmemory_buffer and convert to utf8
 | 
			
		||||
                using details::fmt_helper::to_string_view;
 | 
			
		||||
                fmt::wmemory_buffer wbuf;
 | 
			
		||||
                fmt::format_to(wbuf, fmt, args...);
 | 
			
		||||
                fmt::memory_buffer buf;
 | 
			
		||||
                wbuf_to_utf8buf(wbuf, buf);
 | 
			
		||||
                details::log_msg log_msg(source, &name_, lvl, to_string_view(buf));
 | 
			
		||||
                sink_it_(log_msg);
 | 
			
		||||
            }
 | 
			
		||||
            SPDLOG_CATCH_AND_HANDLE
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // format to wmemory_buffer and convert to utf8
 | 
			
		||||
            using details::fmt_helper::to_string_view;
 | 
			
		||||
            fmt::wmemory_buffer wbuf;
 | 
			
		||||
            fmt::format_to(wbuf, fmt, args...);
 | 
			
		||||
            fmt::memory_buffer buf;
 | 
			
		||||
            wbuf_to_utf8buf(wbuf, buf);
 | 
			
		||||
            details::log_msg log_msg(source, &name_, lvl, to_string_view(buf));
 | 
			
		||||
            sink_it_(log_msg);
 | 
			
		||||
        }
 | 
			
		||||
        SPDLOG_CATCH_AND_HANDLE
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void log(level::level_enum lvl, const wchar_t *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(source_loc{}, lvl, fmt, args...);
 | 
			
		||||
        log(source_loc{}, lvl, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void trace(const wchar_t *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::trace, fmt, args...);
 | 
			
		||||
        log(level::trace, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void debug(const wchar_t *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::debug, fmt, args...);
 | 
			
		||||
        log(level::debug, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void info(const wchar_t *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::info, fmt, args...);
 | 
			
		||||
        log(level::info, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void warn(const wchar_t *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::warn, fmt, args...);
 | 
			
		||||
        log(level::warn, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void error(const wchar_t *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::err, fmt, args...);
 | 
			
		||||
        log(level::err, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename... Args>
 | 
			
		||||
        void critical(const wchar_t *fmt, const Args &... args)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::critical, fmt, args...);
 | 
			
		||||
        log(level::critical, fmt, args...);
 | 
			
		||||
        }
 | 
			
		||||
#endif // _WIN32
 | 
			
		||||
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
 | 
			
		||||
@@ -217,92 +212,92 @@ namespace spdlog
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        void log(level::level_enum lvl, const T &msg)
 | 
			
		||||
        {
 | 
			
		||||
            log(source_loc{}, lvl, msg);
 | 
			
		||||
        log(source_loc{}, lvl, msg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // T can be statically converted to string_view
 | 
			
		||||
        template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr>
 | 
			
		||||
        void log(source_loc loc, level::level_enum lvl, const T &msg)
 | 
			
		||||
        {
 | 
			
		||||
            if (!should_log(lvl))
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                details::log_msg log_msg(loc, &name_, lvl, msg);
 | 
			
		||||
                sink_it_(log_msg);
 | 
			
		||||
            }
 | 
			
		||||
            catch (const std::exception &ex)
 | 
			
		||||
            {
 | 
			
		||||
                err_handler_(ex.what());
 | 
			
		||||
            }
 | 
			
		||||
            catch (...)
 | 
			
		||||
            {
 | 
			
		||||
                err_handler_("Unknown exception in logger");
 | 
			
		||||
            }
 | 
			
		||||
        if (!should_log(lvl))
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            details::log_msg log_msg(loc, &name_, lvl, msg);
 | 
			
		||||
            sink_it_(log_msg);
 | 
			
		||||
        }
 | 
			
		||||
        catch (const std::exception &ex)
 | 
			
		||||
        {
 | 
			
		||||
            err_handler_(ex.what());
 | 
			
		||||
        }
 | 
			
		||||
        catch (...)
 | 
			
		||||
        {
 | 
			
		||||
            err_handler_("Unknown exception in logger");
 | 
			
		||||
        }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // T cannot be statically converted to string_view
 | 
			
		||||
        template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr>
 | 
			
		||||
        void log(source_loc loc, level::level_enum lvl, const T &msg)
 | 
			
		||||
        {
 | 
			
		||||
            if (!should_log(lvl))
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                using details::fmt_helper::to_string_view;
 | 
			
		||||
                fmt::memory_buffer buf;
 | 
			
		||||
                fmt::format_to(buf, "{}", msg);
 | 
			
		||||
                details::log_msg log_msg(loc, &name_, lvl, to_string_view(buf));
 | 
			
		||||
                sink_it_(log_msg);
 | 
			
		||||
            }
 | 
			
		||||
            catch (const std::exception &ex)
 | 
			
		||||
            {
 | 
			
		||||
                err_handler_(ex.what());
 | 
			
		||||
            }
 | 
			
		||||
            catch (...)
 | 
			
		||||
            {
 | 
			
		||||
                err_handler_("Unknown exception in logger");
 | 
			
		||||
            }
 | 
			
		||||
        if (!should_log(lvl))
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            using details::fmt_helper::to_string_view;
 | 
			
		||||
            fmt::memory_buffer buf;
 | 
			
		||||
            fmt::format_to(buf, "{}", msg);
 | 
			
		||||
            details::log_msg log_msg(loc, &name_, lvl, to_string_view(buf));
 | 
			
		||||
            sink_it_(log_msg);
 | 
			
		||||
        }
 | 
			
		||||
        catch (const std::exception &ex)
 | 
			
		||||
        {
 | 
			
		||||
            err_handler_(ex.what());
 | 
			
		||||
        }
 | 
			
		||||
        catch (...)
 | 
			
		||||
        {
 | 
			
		||||
            err_handler_("Unknown exception in logger");
 | 
			
		||||
        }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        void trace(const T &msg)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::trace, msg);
 | 
			
		||||
        log(level::trace, msg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        void debug(const T &msg)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::debug, msg);
 | 
			
		||||
        log(level::debug, msg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        void info(const T &msg)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::info, msg);
 | 
			
		||||
        log(level::info, msg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        void warn(const T &msg)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::warn, msg);
 | 
			
		||||
        log(level::warn, msg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        void error(const T &msg)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::err, msg);
 | 
			
		||||
        log(level::err, msg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        void critical(const T &msg)
 | 
			
		||||
        {
 | 
			
		||||
            log(level::critical, msg);
 | 
			
		||||
        log(level::critical, msg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool should_log(level::level_enum msg_level) const;
 | 
			
		||||
@@ -332,9 +327,7 @@ namespace spdlog
 | 
			
		||||
        std::vector<sink_ptr> &sinks();
 | 
			
		||||
 | 
			
		||||
        // error handler
 | 
			
		||||
        void set_error_handler(log_err_handler err_handler);
 | 
			
		||||
 | 
			
		||||
        log_err_handler error_handler() const;
 | 
			
		||||
        void set_error_handler(void (*handler)(const std::string& msg));
 | 
			
		||||
        
 | 
			
		||||
        // create new logger with same sinks and configuration.
 | 
			
		||||
        virtual std::shared_ptr<logger> clone(std::string logger_name);
 | 
			
		||||
@@ -347,7 +340,7 @@ namespace spdlog
 | 
			
		||||
 | 
			
		||||
        // default error handler.
 | 
			
		||||
        // print the error to stderr with the max rate of 1 message/minute.
 | 
			
		||||
        void default_err_handler_(const std::string &msg);
 | 
			
		||||
        void err_handler_(const std::string &msg);
 | 
			
		||||
 | 
			
		||||
        // increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER))
 | 
			
		||||
        void incr_msg_counter_(details::log_msg &msg);
 | 
			
		||||
@@ -356,10 +349,8 @@ namespace spdlog
 | 
			
		||||
        std::vector<sink_ptr> sinks_;
 | 
			
		||||
        spdlog::level_t level_{spdlog::logger::default_level()};
 | 
			
		||||
        spdlog::level_t flush_level_{level::off};
 | 
			
		||||
        log_err_handler err_handler_{[this](const std::string &msg) { this->default_err_handler_(msg); }};
 | 
			
		||||
        std::atomic<time_t> last_err_time_{0};
 | 
			
		||||
        std::atomic<size_t> msg_counter_{1};
 | 
			
		||||
    };
 | 
			
		||||
        void (*custom_err_handler_)(const std::string &msg) {nullptr};                        
 | 
			
		||||
};
 | 
			
		||||
} // namespace spdlog
 | 
			
		||||
 | 
			
		||||
#ifdef SPDLOG_HEADER_ONLY
 | 
			
		||||
 
 | 
			
		||||
@@ -103,9 +103,9 @@ inline void flush_every(std::chrono::seconds interval)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set global error handler
 | 
			
		||||
inline void set_error_handler(log_err_handler handler)
 | 
			
		||||
inline void set_error_handler(void (*handler)(const std::string &msg))
 | 
			
		||||
{
 | 
			
		||||
    details::registry::instance().set_error_handler(std::move(handler));
 | 
			
		||||
    details::registry::instance().set_error_handler(handler);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register the given logger with the given name
 | 
			
		||||
 
 | 
			
		||||
@@ -107,13 +107,6 @@
 | 
			
		||||
// #define SPDLOG_PREVENT_CHILD_FD
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Uncomment to enable message counting feature.
 | 
			
		||||
// Use the %i in the logger pattern to display log message sequence id.
 | 
			
		||||
//
 | 
			
		||||
// #define SPDLOG_ENABLE_MESSAGE_COUNTER
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Uncomment to customize level names (e.g. "MT TRACE")
 | 
			
		||||
//
 | 
			
		||||
 
 | 
			
		||||
@@ -113,14 +113,9 @@ SPDLOG_INLINE std::vector<spdlog::sink_ptr> &spdlog::logger::sinks()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// error handler
 | 
			
		||||
SPDLOG_INLINE void spdlog::logger::set_error_handler(spdlog::log_err_handler err_handler)
 | 
			
		||||
SPDLOG_INLINE void spdlog::logger::set_error_handler(void (*handler)(const std::string &msg))
 | 
			
		||||
{
 | 
			
		||||
    err_handler_ = std::move(err_handler);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SPDLOG_INLINE spdlog::log_err_handler spdlog::logger::error_handler() const
 | 
			
		||||
{
 | 
			
		||||
    return err_handler_;
 | 
			
		||||
    custom_err_handler_ = handler;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// create new logger with same sinks and configuration.
 | 
			
		||||
@@ -129,16 +124,13 @@ SPDLOG_INLINE std::shared_ptr<spdlog::logger> spdlog::logger::clone(std::string
 | 
			
		||||
    auto cloned = std::make_shared<spdlog::logger>(std::move(logger_name), sinks_.begin(), sinks_.end());
 | 
			
		||||
    cloned->set_level(this->level());
 | 
			
		||||
    cloned->flush_on(this->flush_level());
 | 
			
		||||
    cloned->set_error_handler(this->error_handler());
 | 
			
		||||
    cloned->set_error_handler(this->custom_err_handler_);
 | 
			
		||||
    return cloned;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// protected methods
 | 
			
		||||
SPDLOG_INLINE void spdlog::logger::sink_it_(spdlog::details::log_msg &msg)
 | 
			
		||||
{
 | 
			
		||||
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
 | 
			
		||||
    incr_msg_counter_(msg);
 | 
			
		||||
#endif
 | 
			
		||||
    for (auto &sink : sinks_)
 | 
			
		||||
    {
 | 
			
		||||
        if (sink->should_log(msg.level))
 | 
			
		||||
@@ -167,21 +159,17 @@ SPDLOG_INLINE bool spdlog::logger::should_flush_(const spdlog::details::log_msg
 | 
			
		||||
    return (msg.level >= flush_level) && (msg.level != level::off);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SPDLOG_INLINE void spdlog::logger::default_err_handler_(const std::string &msg)
 | 
			
		||||
void spdlog::logger::err_handler_(const std::string &msg)
 | 
			
		||||
{    
 | 
			
		||||
    auto now = time(nullptr);
 | 
			
		||||
    if (now - last_err_time_ < 60)
 | 
			
		||||
	if (custom_err_handler_)
 | 
			
		||||
	{
 | 
			
		||||
		custom_err_handler_(msg);
 | 
			
		||||
	}
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return;
 | 
			
		||||
        auto tm_time = spdlog::details::os::localtime();
 | 
			
		||||
        char date_buf[64];
 | 
			
		||||
        std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
 | 
			
		||||
        fmt::print(stderr, "[*** LOG ERROR ***] [{}] [{}] {}\n", date_buf, name(), msg);
 | 
			
		||||
    }
 | 
			
		||||
    last_err_time_ = now;
 | 
			
		||||
    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);
 | 
			
		||||
    fmt::print(stderr, "[*** LOG ERROR ***] [{}] [{}] {}\n", date_buf, name(), msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SPDLOG_INLINE void spdlog::logger::incr_msg_counter_(spdlog::details::log_msg &msg)
 | 
			
		||||
{
 | 
			
		||||
    msg.msg_id = msg_counter_.fetch_add(1, std::memory_order_relaxed);
 | 
			
		||||
}
 | 
			
		||||
@@ -344,14 +344,12 @@ SPDLOG_INLINE void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
SPDLOG_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
 | 
			
		||||
SPDLOG_INLINE std::string filename_to_str(const filename_t &filename)
 | 
			
		||||
{
 | 
			
		||||
    return filename;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1266
									
								
								src/pattern_formatter.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1266
									
								
								src/pattern_formatter.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -11,7 +11,6 @@
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
 | 
			
		||||
#define SPDLOG_ENABLE_MESSAGE_COUNTER
 | 
			
		||||
 | 
			
		||||
#include "spdlog/spdlog.h"
 | 
			
		||||
#include "spdlog/async.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -41,13 +41,18 @@ TEST_CASE("default_error_handler", "[errors]]")
 | 
			
		||||
struct custom_ex
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void custom_handler(const std::string &msg)
 | 
			
		||||
{
 | 
			
		||||
    throw custom_ex();
 | 
			
		||||
}
 | 
			
		||||
TEST_CASE("custom_error_handler", "[errors]]")
 | 
			
		||||
{
 | 
			
		||||
    prepare_logdir();
 | 
			
		||||
    std::string filename = "logs/simple_log.txt";
 | 
			
		||||
    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
 | 
			
		||||
    logger->flush_on(spdlog::level::info);
 | 
			
		||||
    logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
 | 
			
		||||
    logger->set_error_handler(custom_handler);
 | 
			
		||||
    logger->info("Good message #1");
 | 
			
		||||
 | 
			
		||||
    REQUIRE_THROWS_AS(logger->info("Bad format msg {} {}", "xxx"), custom_ex);
 | 
			
		||||
@@ -59,7 +64,7 @@ TEST_CASE("default_error_handler2", "[errors]]")
 | 
			
		||||
{
 | 
			
		||||
    spdlog::drop_all();
 | 
			
		||||
    auto logger = spdlog::create<failing_sink>("failed_logger");
 | 
			
		||||
    logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
 | 
			
		||||
    logger->set_error_handler(custom_handler);
 | 
			
		||||
    REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -67,26 +72,26 @@ TEST_CASE("flush_error_handler", "[errors]]")
 | 
			
		||||
{
 | 
			
		||||
    spdlog::drop_all();
 | 
			
		||||
    auto logger = spdlog::create<failing_sink>("failed_logger");
 | 
			
		||||
    logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
 | 
			
		||||
    logger->set_error_handler(custom_handler);
 | 
			
		||||
    REQUIRE_THROWS_AS(logger->flush(), custom_ex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE("async_error_handler", "[errors]]")
 | 
			
		||||
{
 | 
			
		||||
    prepare_logdir();
 | 
			
		||||
    std::string err_msg("log failed with some msg");
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    std::string filename = "logs/simple_async_log.txt";
 | 
			
		||||
    {
 | 
			
		||||
        spdlog::init_thread_pool(128, 1);
 | 
			
		||||
        auto logger = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
 | 
			
		||||
        logger->set_error_handler([=](const std::string &) {
 | 
			
		||||
        logger->set_error_handler([](const std::string &) {
 | 
			
		||||
            std::ofstream ofs("logs/custom_err.txt");
 | 
			
		||||
            if (!ofs)
 | 
			
		||||
            {
 | 
			
		||||
                throw std::runtime_error("Failed open logs/custom_err.txt");
 | 
			
		||||
            }
 | 
			
		||||
            ofs << err_msg;
 | 
			
		||||
            ofs << "log failed with some msg";
 | 
			
		||||
        });
 | 
			
		||||
        logger->info("Good message #1");
 | 
			
		||||
        logger->info("Bad format msg {} {}", "xxx");
 | 
			
		||||
@@ -95,27 +100,26 @@ TEST_CASE("async_error_handler", "[errors]]")
 | 
			
		||||
    }
 | 
			
		||||
    spdlog::init_thread_pool(128, 1);
 | 
			
		||||
    REQUIRE(count_lines(filename) == 2);
 | 
			
		||||
    REQUIRE(file_contents("logs/custom_err.txt") == err_msg);
 | 
			
		||||
    REQUIRE(file_contents("logs/custom_err.txt") == "log failed with some msg");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Make sure async error handler is executed
 | 
			
		||||
TEST_CASE("async_error_handler2", "[errors]]")
 | 
			
		||||
{
 | 
			
		||||
    prepare_logdir();    
 | 
			
		||||
    std::string err_msg("This is async handler error message");
 | 
			
		||||
    {
 | 
			
		||||
        spdlog::init_thread_pool(128, 1);
 | 
			
		||||
        auto logger = spdlog::create_async<failing_sink>("failed_logger");
 | 
			
		||||
        logger->set_error_handler([=](const std::string &) {
 | 
			
		||||
        logger->set_error_handler([](const std::string &) {
 | 
			
		||||
            std::ofstream ofs("logs/custom_err2.txt");
 | 
			
		||||
            if (!ofs)
 | 
			
		||||
                throw std::runtime_error("Failed open logs/custom_err2.txt");
 | 
			
		||||
            ofs << err_msg;
 | 
			
		||||
            ofs << "handler error message";
 | 
			
		||||
        });
 | 
			
		||||
        logger->info("Hello failure");
 | 
			
		||||
        spdlog::drop("failed_logger"); // force logger to drain the queue and shutdown
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    spdlog::init_thread_pool(128, 1);
 | 
			
		||||
    REQUIRE(file_contents("logs/custom_err2.txt") == err_msg);
 | 
			
		||||
    REQUIRE(file_contents("logs/custom_err2.txt") == "handler error message");
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,6 @@ TEST_CASE("clone-logger", "[clone]")
 | 
			
		||||
    cloned->info("Some message 2");
 | 
			
		||||
 | 
			
		||||
    auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(cloned->sinks()[0]);
 | 
			
		||||
    REQUIRE(test_sink->msg_counter() == 2);
 | 
			
		||||
    
 | 
			
		||||
    spdlog::drop_all();
 | 
			
		||||
}
 | 
			
		||||
@@ -130,7 +129,6 @@ TEST_CASE("clone async", "[clone]")
 | 
			
		||||
    spdlog::details::os::sleep_for_millis(10);
 | 
			
		||||
 | 
			
		||||
    auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(cloned->sinks()[0]);    
 | 
			
		||||
    REQUIRE(test_sink->msg_counter() == 2);
 | 
			
		||||
 | 
			
		||||
    spdlog::drop_all();
 | 
			
		||||
}
 | 
			
		||||
@@ -176,22 +174,6 @@ TEST_CASE("to_hex_no_delimiter", "[to_hex]")
 | 
			
		||||
    REQUIRE(ends_with(output, "0000: 090A0B0CFFFF" + std::string(spdlog::details::os::default_eol)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE("message_counter", "[message_counter]")
 | 
			
		||||
{
 | 
			
		||||
    std::ostringstream oss;
 | 
			
		||||
    auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss);
 | 
			
		||||
    spdlog::logger oss_logger("oss", oss_sink);
 | 
			
		||||
    oss_logger.set_pattern("%i %v");
 | 
			
		||||
 | 
			
		||||
    oss_logger.info("Hello");
 | 
			
		||||
    REQUIRE(oss.str() == "000001 Hello" + std::string(spdlog::details::os::default_eol));
 | 
			
		||||
 | 
			
		||||
    oss.str("");
 | 
			
		||||
    oss_logger.info("Hello again");
 | 
			
		||||
 | 
			
		||||
    REQUIRE(oss.str() == "000002 Hello again" + std::string(spdlog::details::os::default_eol));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE("default logger API", "[default logger]")
 | 
			
		||||
{
 | 
			
		||||
    std::ostringstream oss;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user