diff options
author | Josh Blum <josh@joshknows.com> | 2011-05-04 11:49:02 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-05-04 14:34:34 -0700 |
commit | 0ac4fe4e10093b1c7bd59af5c795b5a56d49e452 (patch) | |
tree | 2838d300ccea1130a4dc04c827fccf61bd8d5f05 /host | |
parent | 400a8542fba5f341485c2abfdb92ffbc1260d45d (diff) | |
download | uhd-0ac4fe4e10093b1c7bd59af5c795b5a56d49e452.tar.gz uhd-0ac4fe4e10093b1c7bd59af5c795b5a56d49e452.tar.bz2 uhd-0ac4fe4e10093b1c7bd59af5c795b5a56d49e452.zip |
uhd: added configurable default log level and thread safety
Diffstat (limited to 'host')
-rw-r--r-- | host/include/uhd/log.hpp | 31 | ||||
-rw-r--r-- | host/lib/log.cpp | 58 |
2 files changed, 80 insertions, 9 deletions
diff --git a/host/include/uhd/log.hpp b/host/include/uhd/log.hpp index 8c9f4cec6..ff9dfe239 100644 --- a/host/include/uhd/log.hpp +++ b/host/include/uhd/log.hpp @@ -23,11 +23,38 @@ #include <ostream> #include <string> -//! uhd logger macro with default verbosity +/*! + * The UHD logging facility. + * + * The logger enables UHD library code to easily log events into a file. + * Log entries are time-stamped and stored with file, line, and function. + * Each call to the UHD_LOG macros is synchronous and thread-safe. + * + * All log messages with verbosity greater than or equal to the log level + * are recorded into the log file. All other messages are sent to null. + * + * The default log level is "regular", but can be overridden: + * - at compile time by setting the pre-processor define UHD_LOG_LEVEL. + * - at runtime by setting the environment variable UHD_LOG_LEVEL. + * + * UHD_LOG_LEVEL can be the name of a verbosity enum or integer value: + * - Example pre-processor define: -DUHD_LOG_LEVEL=3 + * - Example pre-processor define: -DUHD_LOG_LEVEL=regularly + * - Example environment variable: export UHD_LOG_LEVEL=3 + * - Example environment variable: export UHD_LOG_LEVEL=regularly + */ + +/*! + * A UHD logger macro with default verbosity. + * Usage: UHD_LOG << "the log message" << std::endl; + */ #define UHD_LOG \ uhd::_log::log(uhd::_log::regularly, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) -//! uhd logger macro with configurable verbosity +/*! + * A UHD logger macro with configurable verbosity. + * Usage: UHD_LOGV(very_rarely) << "the log message" << std::endl; + */ #define UHD_LOGV(verbosity) \ uhd::_log::log(uhd::_log::verbosity, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) diff --git a/host/lib/log.cpp b/host/lib/log.cpp index fb68da39d..c0c51d9a6 100644 --- a/host/lib/log.cpp +++ b/host/lib/log.cpp @@ -28,6 +28,7 @@ #include <stdio.h> //P_tmpdir #include <cstdlib> //getenv #include <fstream> +#include <cctype> namespace fs = boost::filesystem; namespace pt = boost::posix_time; @@ -44,8 +45,8 @@ static fs::path get_temp_path(void){ //try the windows function if available #ifdef USE_GET_TEMP_PATH - LPTSTR lpBuffer[2048]; - if (GetTempPath(sizeof(lpBuffer)/sizeof(*lpBuffer), lpBuffer)) return lpBuffer; + char lpBuffer[2048]; + if (GetTempPath(sizeof(lpBuffer), lpBuffer)) return lpBuffer; #endif //try windows environment variables @@ -71,19 +72,38 @@ static fs::path get_temp_path(void){ /*********************************************************************** * The library's streamer resource (static initialization) **********************************************************************/ +class null_streambuf_class : public std::streambuf{ + int overflow(int c) { return c; } +}; +UHD_SINGLETON_FCN(null_streambuf_class, null_streambuf); + class uhd_logger_stream_resource_class{ public: - uhd_logger_stream_resource_class(void){ + uhd_logger_stream_resource_class(void) : _null_stream(&null_streambuf()){ const std::string log_path = (get_temp_path() / "uhd.log").string(); - _streamer.open(log_path.c_str(), std::fstream::out | std::fstream::app); + _file_stream.open(log_path.c_str(), std::fstream::out | std::fstream::app); + + //set the default log level + _log_level = uhd::_log::regularly; + + //allow override from macro definition + #ifdef UHD_LOG_LEVEL + _set_log_level(BOOST_STRINGIZE(UHD_LOG_LEVEL)); + #endif + + //allow override from environment variable + const char * log_level_env = std::getenv("UHD_LOG_LEVEL"); + if (log_level_env != NULL) _set_log_level(log_level_env); + } ~uhd_logger_stream_resource_class(void){ - _streamer.close(); + _file_stream.close(); } std::ostream &get(void){ - return _streamer; + if (_verbosity >= _log_level) return _file_stream; + return _null_stream; } void aquire(bool lock){ @@ -91,9 +111,30 @@ public: else _mutex.unlock(); } + void set_verbosity(uhd::_log::verbosity_t verbosity){ + _verbosity = verbosity; + } + private: - std::ofstream _streamer; + //! set the log level from a string that is either a digit or an enum name + void _set_log_level(const std::string &log_level_str){ + const uhd::_log::verbosity_t log_level = uhd::_log::verbosity_t(log_level_str[0]-'0'); + if (std::isdigit(log_level_str[0]) and log_level >= uhd::_log::always and log_level <= uhd::_log::very_rarely){ + _log_level = log_level; + } + #define if_lls_equal(name) else if(log_level_str == #name) _log_level = uhd::_log::name + if_lls_equal(always); + if_lls_equal(often); + if_lls_equal(regularly); + if_lls_equal(rarely); + if_lls_equal(very_rarely); + } + + std::ofstream _file_stream; + std::ostream _null_stream; boost::mutex _mutex; + uhd::_log::verbosity_t _verbosity; + uhd::_log::verbosity_t _log_level; }; UHD_SINGLETON_FCN(uhd_logger_stream_resource_class, uhd_logger_stream_resource); @@ -108,6 +149,7 @@ uhd::_log::log::log( const std::string &function ){ uhd_logger_stream_resource().aquire(true); + uhd_logger_stream_resource().set_verbosity(verbosity); const std::string time = pt::to_simple_string(pt::microsec_clock::local_time()); const std::string header = str(boost::format( "-- %s - lvl %d - %s @ %s:%u" @@ -130,4 +172,6 @@ std::ostream & uhd::_log::log::get(void){ UHD_STATIC_BLOCK(logger_begin){ UHD_LOG << "Logger has started" << std::endl; + UHD_LOGV(always) << "always" << std::endl; + UHD_LOGV(rarely) << "rarely" << std::endl; } |