diff options
Diffstat (limited to 'gnuradio-core/src/lib/runtime/gr_logger.cc')
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_logger.cc | 173 |
1 files changed, 130 insertions, 43 deletions
diff --git a/gnuradio-core/src/lib/runtime/gr_logger.cc b/gnuradio-core/src/lib/runtime/gr_logger.cc index 530c66f964..7e0116d036 100644 --- a/gnuradio-core/src/lib/runtime/gr_logger.cc +++ b/gnuradio-core/src/lib/runtime/gr_logger.cc @@ -26,10 +26,6 @@ * The gr_log module wraps the log4cpp library for logging in gnuradio. *******************************************************************************/ -//#ifdef HAVE_CONFIG_H -//#include "config.h" -//#endif - #include <gr_logger.h> #include <stdexcept> #include <algorithm> @@ -37,33 +33,118 @@ #ifdef ENABLE_GR_LOG #ifdef HAVE_LOG4CPP -bool gr_logger_configured(false); +/**************************** BEGIN LOG4CPP HELPERS ***************************/ +/* Logger config class. This is a singleton that controls how log4cpp is configured + * If watch_period>0 a thread is started to watch teh config file for changes. + */ -void -logger_load_config(const std::string &config_filename) -{ - if(!gr_logger_configured){ - gr_logger_configured = true; - if(config_filename.size() != 0) { - try - { - log4cpp::PropertyConfigurator::configure(config_filename); - } - catch( log4cpp::ConfigureFailure &e ) - { - std::cout << "Logger config failed :" << e.what() << std::endl; - } - }; +// Getters of logger_config +logger_config& +logger_config::get_instance(void){ + static logger_config instance; + return instance; +}; + +std::string +logger_config::get_filename(){ + logger_config& in=get_instance(); + return in.filename; +}; + +unsigned int +logger_config::get_watch_period(){ + logger_config& in=get_instance(); + return in.watch_period; +}; + +// Method to watch config file for changes +void logger_config::watch_file(std::string filename,unsigned int watch_period){ + std::time_t last_write(boost::filesystem::last_write_time(filename)); + std::time_t current_time(0); + while(true){ + try{ + current_time = boost::filesystem::last_write_time(filename); + if(current_time>last_write){ + std::cout<<"GNURadio Reloading logger configuration:"<<filename<<std::endl; + last_write = current_time; +// Should we wipe out all old configuration or just add the new? Just adding... +// logger_reset_config(); + logger_load_config(filename); + }; + boost::this_thread::sleep(boost::posix_time::time_duration(0,0,watch_period,0)); + } + catch(const boost::thread_interrupted&){ + std::cout<<"GNURadio leaving logger config file watch."<<std::endl; + break; + }; + }; +}; + +// Method to load the confifuration. It only loads if the filename or watch has changed +void logger_config::load_config(std::string filename,unsigned int watch_period){ + logger_config& instance = get_instance(); +// Only reconfigure if filename or watch has changed + if(instance.filename!=filename || watch_period!=instance.watch_period){ + instance.filename = filename; + instance.watch_period = watch_period; +// Stop any file watching thread + if(instance.watch_thread!=NULL) stop_watch(); +// Load configuration + std::cout<<"GNURadio Loading logger configuration:"<<instance.filename<<std::endl; + logger_load_config(instance.filename); +// Start watch if required + if(instance.watch_period>0){ + instance.watch_thread = new boost::thread(watch_file,instance.filename,instance.watch_period); + } }; +}; + +// Method to stop the watcher thread +void logger_config::stop_watch(){ + logger_config& instance = get_instance(); + if(instance.watch_thread){ + instance.watch_thread->interrupt(); + instance.watch_thread->join(); + delete(instance.watch_thread); + instance.watch_thread=NULL; + }; +}; + +// Method to reset logger configuration +void +logger_config::reset_config(void){ + logger_config& instance = get_instance(); + stop_watch(); + std::vector<log4cpp::Category*> *loggers = log4cpp::Category::getCurrentCategories(); + std::vector<log4cpp::Category*>::iterator logger = loggers->begin(); +// We can't destroy categories but we can neuter them by removing all appenders. + for (;logger!=loggers->end();logger++){ + (*logger)->removeAllAppenders(); + }; + instance.filename=std::string(""); + instance.watch_period=0; } +/***************** Functions to call log4cpp methods *************************/ + +gr_logger_ptr +logger_get_logger(std::string name) +{ + if(log4cpp::Category::exists(name)){ + gr_logger_ptr logger = &log4cpp::Category::getInstance(name); + return logger; + } + else + { + gr_logger_ptr logger = &log4cpp::Category::getInstance(name); + logger->setPriority(log4cpp::Priority::NOTSET); + return logger; + }; +}; + void -logger_load_config_and_watch(const std::string &config_filename, - unsigned int watch_period) +logger_load_config(const std::string &config_filename) { -// NOTE:: NEEDS CODE TO WATCH FILE HERE - if(!gr_logger_configured){ - gr_logger_configured = true; if(config_filename.size() != 0) { try { @@ -74,17 +155,6 @@ logger_load_config_and_watch(const std::string &config_filename, std::cout << "Logger config failed :" << e.what() << std::endl; } }; - }; -} - -void -logger_reset_config(void){ - std::vector<log4cpp::Category*> *loggers = log4cpp::Category::getCurrentCategories(); - std::vector<log4cpp::Category*>::iterator logger = loggers->begin(); -// We can't destroy categories but we can neuter them by removing all appenders. - for (;logger!=loggers->end();logger++){ - (*logger)->removeAllAppenders(); - }; } void @@ -95,7 +165,7 @@ logger_set_level(gr_logger_ptr logger, const std::string &level) if(nocase == "off" || nocase == "notset") logger_set_level(logger, log4cpp::Priority::NOTSET); - else if(nocase == "debug") + else if(nocase == "all" || nocase == "debug") logger_set_level(logger, log4cpp::Priority::DEBUG); else if(nocase == "info") logger_set_level(logger, log4cpp::Priority::INFO); @@ -111,7 +181,7 @@ logger_set_level(gr_logger_ptr logger, const std::string &level) logger_set_level(logger, log4cpp::Priority::ALERT); else if(nocase=="fatal") logger_set_level(logger, log4cpp::Priority::FATAL); - else if(nocase == "all" || nocase == "emerg") + else if(nocase == "emerg") logger_set_level(logger, log4cpp::Priority::EMERG); else throw std::runtime_error("logger_set_level: Bad level type.\n"); @@ -151,7 +221,7 @@ logger_add_console_appender(gr_logger_ptr logger,std::string target,std::string log4cpp::PatternLayout* layout = new log4cpp::PatternLayout(); log4cpp::Appender* app; - if(target=="cout") + if(target=="stdout") app = new log4cpp::OstreamAppender("ConsoleAppender::",&std::cout); else app = new log4cpp::OstreamAppender("ConsoleAppender::",&std::cerr); @@ -188,17 +258,34 @@ logger_add_rollingfile_appender(gr_logger_ptr logger,std::string filename, logger->setAppender(app); } -void -logger_get_logger_names(std::vector<std::string>& names){ +std::vector<std::string> +logger_get_logger_names(void){ + std::vector<std::string> names; std::vector<log4cpp::Category*> *loggers = log4cpp::Category::getCurrentCategories(); std::vector<log4cpp::Category*>::iterator logger = loggers->begin(); - names.clear(); for (;logger!=loggers->end();logger++){ names.push_back((*logger)->getName()); }; - + return names; + } #endif /* HAVE_LOG4CPP */ + +/****** Start Methods to provide Python the capabilities of the macros ********/ +void gr_logger_config(const std::string config_filename, unsigned int watch_period){ + GR_CONFIG_AND_WATCH_LOGGER(config_filename,watch_period); +}; +std::vector<std::string> gr_logger_get_logger_names(void){ + std::vector<std::string> names; + GR_GET_LOGGER_NAMES(names); + return names; +}; +void gr_logger_reset_config(void){ + GR_RESET_CONFIGURATION(); +}; + +// Remaining capability provided by gr_logger class in gr_logger.h + #endif /* ENABLE_GR_LOGGER */ |