diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2016-06-17 14:25:14 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2016-06-17 14:25:14 +0200 |
commit | 0a89de68defe14fb166a0a24b59ef495113a8b9d (patch) | |
tree | df74fa69fc7e4cd0e5d4e4ad7b4b35de5ee65f27 | |
parent | 5950cd21ae4ad1b9ddc98a6f1c8716e1627ebbd2 (diff) | |
download | dabmod-0a89de68defe14fb166a0a24b59ef495113a8b9d.tar.gz dabmod-0a89de68defe14fb166a0a24b59ef495113a8b9d.tar.bz2 dabmod-0a89de68defe14fb166a0a24b59ef495113a8b9d.zip |
Move logging writes to separate thread
-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) { |