Commit 69dbbdae authored by Alberto Miranda's avatar Alberto Miranda ♨️
Browse files

Bump spdlog to 0.13.0

parent 6d5e9b09
Loading
Loading
Loading
Loading
+126 −36
Original line number Diff line number Diff line
//
// Copyright (C) 2017 Barcelona Supercomputing Center
//                    Centro Nacional de Supercomputacion
//
// This file is part of the Data Scheduler, a daemon for tracking and managing
// requests for asynchronous data transfer in a hierarchical storage environment.
//
// See AUTHORS file in the top level directory for information
// regarding developers and contributors.
//
// The Data Scheduler is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Data Scheduler is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Data Scheduler.  If not, see <http://www.gnu.org/licenses/>.
//
//
/*************************************************************************
 * Copyright (C) 2017-2018 Barcelona Supercomputing Center               *
 *                         Centro Nacional de Supercomputacion           *
 *                                                                       *
 * This file is part of the Data Scheduler, a daemon for tracking and    *
 * managing requests for asynchronous data transfer in a hierarchical    *
 * storage environment.                                                  *
 *                                                                       *
 * See AUTHORS file in the top level directory for information           *
 * regarding developers and contributors.                                *
 *                                                                       *
 * The Data Scheduler is free software: you can redistribute it and/or   *
 * modify it under the terms of the GNU Lesser General Public License    *
 * as published by the Free Software Foundation, either version 3 of     *
 * the License, or (at your option) any later version.                   *
 *                                                                       *
 * The Data Scheduler is distributed in the hope that it will be useful, *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 * Lesser General Public License for more details.                       *
 *                                                                       *
 * You should have received a copy of the GNU Lesser General             *
 * Public License along with Data Scheduler.  If not, see                *
 * <http://www.gnu.org/licenses/>.                                       *
 *                                                                       *
 *************************************************************************/


#ifndef __LOGGER_HPP__
#define __LOGGER_HPP__

#include <spdlog/spdlog.h>
#include <spdlog/fmt/ostr.h>
#include <sstream>

class logger {

    static const int32_t queue_size = 8192; // must be a power of 2

public:
    logger(const std::string& ident, const std::string& type) {
    logger(const std::string& ident, const std::string& type, const std::string& logfile="") {

        try {

            if(type == "stdout") {
            if(type == "console") {
                spdlog::set_async_mode(queue_size);
                m_internal_logger = spdlog::stdout_logger_mt(ident);
            }
            else if(type == "stdout color") {
            else if(type == "console color") {
                spdlog::set_async_mode(queue_size);
                m_internal_logger = spdlog::stdout_color_mt(ident);
            }
@@ -50,32 +55,96 @@ public:
                m_internal_logger = spdlog::syslog_logger("syslog", ident, LOG_PID);
            }
#endif
            else if(type == "file") {
                 m_internal_logger = spdlog::basic_logger_mt(ident, logfile);
            }
            else {
                // FIXME: add custom exceptions here!
                std::cerr << "Unknown logger type: '" << type << "'\n";
                abort();
                throw std::invalid_argument("Unknown logger type: '" + type + "'");
            }

            assert(m_internal_logger != nullptr);

            // %Y - Year in 4 digits
            // %m - month 1-12
            // %d - day 1-31
            // %T - ISO 8601 time format (HH:MM:SS)
            // %f - microsecond part of the current second
            // %E - epoch (microseconds precision)
            // %n - logger's name
            // %t - thread id
            // %l - log level
            // %v - message
            //m_internal_logger->set_pattern("[%Y-%m-%d %T.%f] [%E] [%n] [%t] [%l] %v");
            m_internal_logger->set_pattern("[%Y-%m-%d %T.%f] [%n] [%t] [%l] %v");

            spdlog::drop_all();

            // globally register the logger so that it can be accessed 
            // using spdlog::get(logger_name)
            spdlog::register_logger(m_internal_logger);
            //spdlog::register_logger(m_internal_logger);
        }
        catch(const spdlog::spdlog_ex& ex) {
            // FIXME: add custom exceptions here!
            std::cerr << "spdlog initialization failed!: " << ex.what() << std::endl;
            abort();
            throw std::runtime_error("logger initialization failed: " + std::string(ex.what()));
        }
    }

    logger(const logger& rhs) = delete;
    logger& operator=(const logger& rhs) = delete;
    logger(logger&& other) = default;
    logger& operator=(logger&& other) = default;

    ~logger(){
//        std::cerr << "XXXXXXXXXX called!\n";
        spdlog::drop_all();
    }

    // the following static functions can be used to interact 
    // with a globally registered logger instance

    template <typename... Args>
    static inline void create_global_logger(Args&&... args) {
        global_logger() = std::make_shared<logger>(args...);
    }

    static inline void register_global_logger(logger&& lg) {
        global_logger() = std::make_shared<logger>(std::move(lg));
    }

    static inline std::shared_ptr<logger>& get_global_logger() {
        return global_logger();
    }

    // some macros to make it more convenient to use the global logger

#define LOGGER_INFO(...) \
    efsng::logger::get_global_logger()->info(__VA_ARGS__)

#ifdef __LOGGER_ENABLE_DEBUG__
#define LOGGER_DEBUG(...) \
    efsng::logger::get_global_logger()->debug(__VA_ARGS__)
#else
#define LOGGER_DEBUG(...) \
    do {} while(0)
#endif

#define LOGGER_WARN(...) \
    efsng::logger::get_global_logger()->warn(__VA_ARGS__)

#define LOGGER_ERROR(...) \
    efsng::logger::get_global_logger()->error(__VA_ARGS__)

#define LOGGER_CRITICAL(...) \
    efsng::logger::get_global_logger()->critical(__VA_ARGS__)

    // the following member functions can be used to interact 
    // with a specific logger instance
    inline void enable_debug() const {
        m_internal_logger->set_level(spdlog::level::debug);
    }

    inline void flush() {
        m_internal_logger->flush();
    }

    template <typename... Args>
    inline void info(const char* fmt, const Args&... args) {
        m_internal_logger->info(fmt, args...);
@@ -126,10 +195,31 @@ public:
        m_internal_logger->critical(msg);
    }

    template <typename... Args>
    static inline std::string build_message(Args&&... args) {

        // see:
        // 1. https://stackoverflow.com/questions/27375089/what-is-the-easiest-way-to-print-a-variadic-parameter-pack-using-stdostream
        // 2. https://stackoverflow.com/questions/25680461/variadic-template-pack-expansion/25683817#25683817

        std::stringstream ss;

        using expander = int[];
        (void) expander{0, (void(ss << std::forward<Args>(args)),0)...};

        return ss.str();
    }

private:

    static std::shared_ptr<logger>& global_logger() {
        static std::shared_ptr<logger> s_global_logger;
        return s_global_logger;
    }

private:
    std::shared_ptr<spdlog::logger> m_internal_logger;
    std::string                     m_type;
};

#endif /* __LOGGER_HPP__ */
+5 −0
Original line number Diff line number Diff line
@@ -63,6 +63,11 @@ public:
    //Wait for the queue to be empty, and flush synchronously
    //Warning: this can potentialy last forever as we wait it to complete
    void flush() override;

    // Error handler
    virtual void set_error_handler(log_err_handler) override;
    virtual log_err_handler error_handler() override;

protected:
    void _sink_it(details::log_msg& msg) override;
    void _set_formatter(spdlog::formatter_ptr msg_formatter) override;
+32 −19
Original line number Diff line number Diff line
@@ -135,6 +135,7 @@ public:

    void flush(bool wait_for_q);

    void set_error_handler(spdlog::log_err_handler err_handler);

private:
    formatter_ptr _formatter;
@@ -221,7 +222,8 @@ inline spdlog::details::async_log_helper::~async_log_helper()
        _worker_thread.join();
    }
    catch (...) // don't crash in destructor
    {}
    {
    }
}


@@ -255,14 +257,16 @@ inline void spdlog::details::async_log_helper::flush(bool wait_for_q)
}

inline void spdlog::details::async_log_helper::worker_loop()
{
    try
{
    if (_worker_warmup_cb) _worker_warmup_cb();
    auto last_pop = details::os::now();
    auto last_flush = last_pop;
        while(process_next_msg(last_pop, last_flush));
        if (_worker_teardown_cb) _worker_teardown_cb();
    auto active = true;
    while (active)
    {
        try
        {
            active = process_next_msg(last_pop, last_flush);
        }
        catch (const std::exception &ex)
        {
@@ -273,6 +277,10 @@ inline void spdlog::details::async_log_helper::worker_loop()
            _err_handler("Unknown exception");
        }
    }
    if (_worker_teardown_cb) _worker_teardown_cb();


}

// process next message in the queue
// return true if this thread should still be active (while no terminate msg was received)
@@ -374,5 +382,10 @@ inline void spdlog::details::async_log_helper::wait_empty_q()
    }
}

inline void spdlog::details::async_log_helper::set_error_handler(spdlog::log_err_handler err_handler)
{
    _err_handler = err_handler;
}


+13 −0
Original line number Diff line number Diff line
@@ -57,6 +57,19 @@ inline void spdlog::async_logger::flush()
    _async_log_helper->flush(true);
}

// Error handler
inline void spdlog::async_logger::set_error_handler(spdlog::log_err_handler err_handler)
{
    _err_handler = err_handler;
    _async_log_helper->set_error_handler(err_handler);

}
inline spdlog::log_err_handler spdlog::async_logger::error_handler()
{
    return _err_handler;
}


inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_formatter)
{
    _formatter = msg_formatter;
+18 −20
Original line number Diff line number Diff line
@@ -121,44 +121,42 @@ inline void spdlog::logger::log(level::level_enum lvl, const T& msg)
}


template <typename... Args>
inline void spdlog::logger::trace(const char* fmt, const Args&... args)
template <typename Arg1, typename... Args>
inline void spdlog::logger::trace(const char* fmt, const Arg1 &arg1, const Args&... args)
{
    log(level::trace, fmt, args...);
    log(level::trace, fmt, arg1, args...);
}

template <typename... Args>
inline void spdlog::logger::debug(const char* fmt, const Args&... args)
template <typename Arg1, typename... Args>
inline void spdlog::logger::debug(const char* fmt, const Arg1 &arg1, const Args&... args)
{
    log(level::debug, fmt, args...);
    log(level::debug, fmt, arg1, args...);
}

template <typename... Args>
inline void spdlog::logger::info(const char* fmt, const Args&... args)
template <typename Arg1, typename... Args>
inline void spdlog::logger::info(const char* fmt, const Arg1 &arg1, const Args&... args)
{
    log(level::info, fmt, args...);
    log(level::info, fmt, arg1, args...);
}


template <typename... Args>
inline void spdlog::logger::warn(const char* fmt, const Args&... args)
template <typename Arg1, typename... Args>
inline void spdlog::logger::warn(const char* fmt, const Arg1 &arg1, const Args&... args)
{
    log(level::warn, fmt, args...);
    log(level::warn, fmt, arg1, args...);
}

template <typename... Args>
inline void spdlog::logger::error(const char* fmt, const Args&... args)
template <typename Arg1, typename... Args>
inline void spdlog::logger::error(const char* fmt, const Arg1 &arg1, const Args&... args)
{
    log(level::err, fmt, args...);
    log(level::err, fmt, arg1, args...);
}

template <typename... Args>
inline void spdlog::logger::critical(const char* fmt, const Args&... args)
template <typename Arg1, typename... Args>
inline void spdlog::logger::critical(const char* fmt, const Arg1 &arg1, const Args&... args)
{
    log(level::critical, fmt, args...);
    log(level::critical, fmt, arg1, args...);
}


template<typename T>
inline void spdlog::logger::trace(const T& msg)
{
Loading