diff options
Diffstat (limited to 'host')
-rw-r--r-- | host/include/uhd/utils/log.hpp | 24 | ||||
-rw-r--r-- | host/lib/utils/log.cpp | 95 |
2 files changed, 65 insertions, 54 deletions
diff --git a/host/include/uhd/utils/log.hpp b/host/include/uhd/utils/log.hpp index a7814342c..a27a536b1 100644 --- a/host/include/uhd/utils/log.hpp +++ b/host/include/uhd/utils/log.hpp @@ -111,7 +111,7 @@ namespace uhd { * Either numeric value or string can be used to define loglevel in * CMake and environment variables */ - enum UHD_API severity_level { + enum severity_level { trace = 0, /**< displays every available log message */ debug = 1, /**< displays most log messages necessary for debugging internals */ info = 2, /**< informational messages about setup and what is going on*/ @@ -127,7 +127,8 @@ namespace uhd { * logging_info structure. */ struct UHD_API logging_info { - logging_info(){}; + logging_info() + : verbosity(uhd::log::off) {} logging_info( const boost::posix_time::ptime &time_, const uhd::log::severity_level &verbosity_, @@ -194,25 +195,6 @@ namespace uhd { * \param logger_fn function which actually logs messages to this backend */ UHD_API void add_logger(const std::string &key, log_fn_t logger_fn); - - // The operator is used when putting the severity level to log - template <typename CharT, typename TraitsT> - inline std::basic_ostream<CharT, TraitsT>& - operator<<(std::basic_ostream<CharT, TraitsT>& strm, severity_level level) - { - static const char* strings[] = {"TRACE", "DEBUG", "INFO", - "WARNING", "ERROR", "FATAL" - }; - - if (static_cast<std::size_t>(level) < sizeof(strings) / sizeof(*strings)) { - strm << strings[level]; - } else { - strm << static_cast<int>(level); - } - - return strm; - } - } } diff --git a/host/lib/utils/log.cpp b/host/lib/utils/log.cpp index 2b6da2297..c77e082ef 100644 --- a/host/lib/utils/log.cpp +++ b/host/lib/utils/log.cpp @@ -18,30 +18,31 @@ #include <uhd/utils/log.hpp> #include <uhd/utils/static.hpp> #include <uhd/utils/paths.hpp> -#include <uhd/utils/tasks.hpp> #include <uhd/transport/bounded_buffer.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/make_shared.hpp> -#include <boost/thread/locks.hpp> -#include <boost/thread/mutex.hpp> #include <fstream> #include <cctype> #include <atomic> +#include <mutex> +#include <memory> +#include <thread> namespace pt = boost::posix_time; -static const std::string PURPLE = "\033[35;1m"; // purple -static const std::string BLUE = "\033[34;1m"; // blue -static const std::string GREEN = "\033[32;1m"; // green -static const std::string YELLOW = "\033[33;1m"; // yellow -static const std::string RED = "\033[31;0m"; // red -static const std::string BRED = "\033[31;1m"; // bright red -static const std::string RESET_COLORS = "\033[39;0m"; // reset colors +// Don't make these static const std::string -- we need their lifetime guaranteed! +#define PURPLE "\033[35;1m" // purple +#define BLUE "\033[34;1m" // blue +#define GREEN "\033[32;1m" // green +#define YELLOW "\033[33;1m" // yellow +#define RED "\033[31;0m" // red +#define BRED "\033[31;1m" // bright red +#define RESET_COLORS "\033[39;0m" // reset colors /*********************************************************************** * Helpers **********************************************************************/ -static const std::string verbosity_color(const uhd::log::severity_level &level){ +static std::string verbosity_color(const uhd::log::severity_level &level){ switch(level){ case (uhd::log::trace): return PURPLE; @@ -60,6 +61,26 @@ static const std::string verbosity_color(const uhd::log::severity_level &level){ } } +static std::string verbosity_name(const uhd::log::severity_level &level){ + switch(level){ + case (uhd::log::trace): + return "TRACE"; + case(uhd::log::debug): + return "DEBUG"; + case(uhd::log::info): + return "INFO"; + case(uhd::log::warning): + return "WARNING"; + case(uhd::log::error): + return "ERROR"; + case(uhd::log::fatal): + return "FATAL"; + default: + return "-"; + } + return ""; +} + //! get the relative file path from the host directory inline std::string path_to_filename(std::string path) { @@ -69,32 +90,31 @@ inline std::string path_to_filename(std::string path) /*********************************************************************** * Logger backends **********************************************************************/ - - void console_log( const uhd::log::logging_info &log_info ) { - std::clog + + std::clog #ifdef UHD_LOG_CONSOLE_COLOR - << verbosity_color(log_info.verbosity) + << verbosity_color(log_info.verbosity) #endif #ifdef UHD_LOG_CONSOLE_TIME - << "[" << pt::to_simple_string(log_info.time) << "] " + << "[" << pt::to_simple_string(log_info.time) << "] " #endif #ifdef UHD_LOG_CONSOLE_THREAD - << "[0x" << log_info.thread_id << "] " + << "[0x" << log_info.thread_id << "] " #endif #ifdef UHD_LOG_CONSOLE_SRC - << "[" << path_to_filename(log_info.file) << ":" << log_info.line << "] " + << "[" << path_to_filename(log_info.file) << ":" << log_info.line << "] " #endif - << "[" << log_info.verbosity << "] " - << "[" << log_info.component << "] " + << "[" << verbosity_name(log_info.verbosity) << "] " + << "[" << log_info.component << "] " #ifdef UHD_LOG_CONSOLE_COLOR - << RESET_COLORS + << RESET_COLORS #endif - << log_info.message - << std::endl - ; + << log_info.message + << std::endl + ; } /*! Helper class to implement file logging @@ -115,7 +135,6 @@ public: std::cerr << "Error opening log file: " << fail.what() << std::endl; } } - } void log(const uhd::log::logging_info &log_info) @@ -211,13 +230,16 @@ public: } // Launch log message consumer - _pop_task = uhd::task::make([this](){this->pop_task();}); - + _pop_task = std::make_shared<std::thread>(std::thread([this](){this->pop_task();})); } ~log_resource(void){ _exit = true; - _pop_task.reset(); + _pop_task->join(); + { + std::lock_guard<std::mutex> l(_logmap_mutex); + _loggers.clear(); + } } void push(const uhd::log::logging_info& log_info) @@ -227,9 +249,12 @@ public: void pop_task() { + uhd::log::logging_info log_info; + log_info.message = ""; + while (!_exit) { - uhd::log::logging_info log_info; if (_log_queue.pop_with_timed_wait(log_info, 1)){ + std::lock_guard<std::mutex> l(_logmap_mutex); for (const auto &logger : _loggers) { auto level = logger_level.find(logger.first); if(level != logger_level.end() && log_info.verbosity < level->second){ @@ -241,8 +266,8 @@ public: } // Exit procedure: Clear the queue - uhd::log::logging_info log_info; while (_log_queue.pop_with_haste(log_info)) { + std::lock_guard<std::mutex> l(_logmap_mutex); for (const auto &logger : _loggers) { auto level = logger_level.find(logger.first); if (level != logger_level.end() && log_info.verbosity < level->second){ @@ -255,11 +280,12 @@ public: void add_logger(const std::string &key, uhd::log::log_fn_t logger_fn) { + std::lock_guard<std::mutex> l(_logmap_mutex); _loggers[key] = logger_fn; } private: - uhd::task::sptr _pop_task; + std::shared_ptr<std::thread> _pop_task; uhd::log::severity_level _get_log_level(const std::string &log_level_str, const uhd::log::severity_level &previous_level){ if (std::isdigit(log_level_str[0])) { @@ -286,9 +312,10 @@ private: return previous_level; } + std::mutex _logmap_mutex; std::atomic<bool> _exit; std::map<std::string, uhd::log::log_fn_t> _loggers; - uhd::transport::bounded_buffer<uhd::log::logging_info> _log_queue; // Init auf size 10 oder so + uhd::transport::bounded_buffer<uhd::log::logging_info> _log_queue; }; UHD_SINGLETON_FCN(log_resource, log_rs); @@ -296,7 +323,6 @@ UHD_SINGLETON_FCN(log_resource, log_rs); /*********************************************************************** * The logger object implementation **********************************************************************/ - uhd::_log::log::log( const uhd::log::severity_level verbosity, const std::string &file, @@ -326,6 +352,9 @@ uhd::_log::log::~log(void) } +/*********************************************************************** + * Public API calls + **********************************************************************/ void uhd::log::add_logger(const std::string &key, log_fn_t logger_fn) { |