diff options
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | src/Log.cpp | 50 | ||||
| -rw-r--r-- | src/Log.h | 37 | 
3 files changed, 73 insertions, 16 deletions
| diff --git a/configure.ac b/configure.ac index 60b1e4e..7bcb494 100644 --- a/configure.ac +++ b/configure.ac @@ -103,7 +103,7 @@ AS_IF([test "x$enable_output_uhd" = "xyes"],          [AC_DEFINE(HAVE_OUTPUT_UHD, [1], [Define if UHD output is enabled]) ,           AC_CHECK_LIB([uhd], [main], [], [AC_MSG_ERROR([library uhd is missing])])]) -AX_BOOST_BASE([1.41.0], [], AC_MSG_ERROR([BOOST 1.41 or later is required])) +AX_BOOST_BASE([1.55.0], [], AC_MSG_ERROR([BOOST 1.55 or later is required]))  AC_CHECK_LIB([boost_system], [main], [], [AC_MSG_ERROR([library boost_system is missing])])  AC_CHECK_LIB([boost_thread], [main], [], [AC_MSG_ERROR([library boost_thread is missing])]) diff --git a/src/Log.cpp b/src/Log.cpp index 55a4ebf..81f32a8 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -3,7 +3,7 @@     Her Majesty the Queen in Right of Canada (Communications Research     Center Canada) -   Copyright (C), 2014, Matthias P. Braendli, matthias.braendli@mpb.li +   Copyright (C), 2016, Matthias P. Braendli, matthias.braendli@mpb.li   */  /*     This file is part of ODR-DabMod. @@ -65,20 +65,44 @@ void Logger::log(log_level_t level, const char* fmt, ...)  void Logger::logstr(log_level_t level, std::string message)  { -    /* Remove a potential trailing newline. -     * It doesn't look good in syslog -     */ -    if (message[message.length()-1] == '\n') { -        message.resize(message.length()-1); -    } +    log_message_t m; +    m.level = level; +    m.message = message; -    for (auto &backend : backends) { -        backend->log(level, message); -    } +    m_message_queue.push(std::move(m)); +} -    if (level != log_level_t::trace) { -        std::lock_guard<std::mutex> guard(m_cerr_mutex); -        std::cerr << levels_as_str[level] << " " << message << std::endl; +void Logger::io_process() +{ +    set_thread_name("logger"); +    while (1) { +        log_message_t m; +        while (m_message_queue.pop(m) == false) { +            std::this_thread::sleep_for(std::chrono::milliseconds(10)); +        } + +        auto message = m.message; + +        if (m.level == debug and m.message.empty()) { +            // Special message to stop thread +            break; +        } + +        /* Remove a potential trailing newline. +         * It doesn't look good in syslog +         */ +        if (message[message.length()-1] == '\n') { +            message.resize(message.length()-1); +        } + +        for (auto &backend : backends) { +            backend->log(m.level, message); +        } + +        if (m.level != log_level_t::trace) { +            std::lock_guard<std::mutex> guard(m_cerr_mutex); +            std::cerr << levels_as_str[m.level] << " " << message << std::endl; +        }      }  } @@ -3,7 +3,7 @@     Her Majesty the Queen in Right of Canada (Communications Research     Center Canada) -   Copyright (C), 2014, Matthias P. Braendli, matthias.braendli@mpb.li +   Copyright (C), 2016, Matthias P. Braendli, matthias.braendli@mpb.li   */  /*     This file is part of ODR-DabMod. @@ -40,6 +40,8 @@  #include <string>  #include <map>  #include <mutex> +#include <thread> +#include <boost/lockfree/spsc_queue.hpp>  #define SYSLOG_IDENT "ODR-DabMod"  #define SYSLOG_FACILITY LOG_LOCAL0 @@ -148,9 +150,32 @@ class LogTracer : public LogBackend {  class LogLine; +struct log_message_t { +    log_message_t(log_level_t _level, std::string _message) : +        level(_level), +        message(_message) {} + +    log_message_t() {} + +    log_level_t level; +    std::string message; +}; +  class Logger {      public: -        Logger() {} +        Logger() { +            m_io_thread = std::thread(&Logger::io_process, this); +        } + +        Logger(const Logger& other) = delete; +        const Logger& operator=(const Logger& other) = delete; +        ~Logger() { +            // Special message to stop the thread +            log_message_t m(debug, ""); + +            m_message_queue.push(m); +            m_io_thread.join(); +        }          void register_backend(LogBackend* backend); @@ -159,6 +184,9 @@ class Logger {          void logstr(log_level_t level, std::string message); +        /* All logging IO is done in another thread */ +        void io_process(void); +          /* Return a LogLine for the given level           * so that you can write etiLog.level(info) << "stuff = " << 21 */          LogLine level(log_level_t level); @@ -166,6 +194,10 @@ class Logger {      private:          std::list<LogBackend*> backends; +        boost::lockfree::spsc_queue< +            log_message_t, +            boost::lockfree::capacity<80> > m_message_queue; +        std::thread m_io_thread;          std::mutex m_cerr_mutex;  }; @@ -176,6 +208,7 @@ extern Logger etiLog;  class LogLine {      public:          LogLine(const LogLine& logline); +        const LogLine& operator=(const LogLine& other) = delete;          LogLine(Logger* logger, log_level_t level) :              logger_(logger)          { | 
