/* -*- c++ -*- */ /* * Copyright 2012-2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * * GNU Radio is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * GNU Radio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Radio; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ /******************************************************************************* * Author: Mark Plett * Description: * The gr::logger module wraps the log4cpp library for logging in gnuradio *******************************************************************************/ #ifndef INCLUDED_GR_LOGGER_H #define INCLUDED_GR_LOGGER_H /*! * \ingroup logging * \brief GNU Radio logging wrapper for log4cpp library (C++ port of log4j) * */ #ifndef ENABLE_GR_LOG #cmakedefine ENABLE_GR_LOG #endif #ifndef HAVE_LOG4CPP #cmakedefine HAVE_LOG4CPP #endif #ifdef _MSC_VER typedef unsigned short mode_t; #endif #include #include #include #include #include #include #include #ifdef ENABLE_GR_LOG // We have three configurations... first logging to stdout/stderr #ifndef HAVE_LOG4CPP namespace gr { //#warning GR logging Enabled and using std::cout typedef std::string logger_ptr; } /* namespace gr */ #define GR_LOG_DECLARE_LOGPTR(logger) #define GR_LOG_ASSIGN_LOGPTR(logger,name) #define GR_CONFIG_LOGGER(config) #define GR_CONFIG_AND_WATCH_LOGGER(config,period) #define GR_LOG_GETLOGGER(logger, name) #define GR_SET_LEVEL(name, level) #define GR_LOG_SET_LEVEL(logger, level) #define GR_GET_LEVEL(name, level) #define GR_LOG_GET_LEVEL(logger, level) #define GR_ADD_APPENDER(name,appender) #define GR_LOG_ADD_APPENDER(logger,appender) #define GR_ADD_CONSOLE_APPENDER(logger,target,pattern) #define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern) #define GR_ADD_FILE_APPENDER(name,filename,append,pattern) #define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern) #define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern) #define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern) #define GR_GET_LOGGER_NAMES(names) #define GR_RESET_CONFIGURATION() #define GR_DEBUG(name, msg) std::cout<<"DEBUG: "< #include #include #include #include #include namespace gr { /*! * \brief GR_LOG macros * \ingroup logging * * These macros wrap the standard LOG4CPP_LEVEL macros. The availablie macros * are: * LOG_DEBUG * LOG_INFO * LOG_WARN * LOG_TRACE * LOG_ERROR * LOG_ALERT * LOG_CRIT * LOG_FATAL * LOG_EMERG */ typedef log4cpp::Category* logger_ptr; } /* namespace gr */ /* Macros for Programmatic Configuration */ #define GR_LOG_DECLARE_LOGPTR(logger) \ gr::logger_ptr logger; #define GR_LOG_ASSIGN_LOGPTR(logger,name) \ logger = gr::logger_get_logger(name); #define GR_CONFIG_LOGGER(config) \ gr::logger_config::load_config(config) #define GR_CONFIG_AND_WATCH_LOGGER(config,period) \ gr::logger_config::load_config(config,period) #define GR_LOG_GETLOGGER(logger, name) \ gr::logger_ptr logger = gr::logger_get_logger(name); #define GR_SET_LEVEL(name, level) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ gr::logger_set_level(logger,level);} #define GR_LOG_SET_LEVEL(logger, level) \ gr::logger_set_level(logger, level); #define GR_GET_LEVEL(name, level) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ gr::logger_get_level(logger,level);} #define GR_LOG_GET_LEVEL(logger, level) \ gr::logger_get_level(logger,level); #define GR_ADD_APPENDER(name, appender) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ gr::logger_add_appender(logger,appender);} #define GR_LOG_ADD_APPENDER(logger, appender) { \ gr::logger_add_appender(logger, appender);} #define GR_ADD_CONSOLE_APPENDER(name, target, pattern) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ gr::logger_add_console_appender(logger,target,pattern);} #define GR_LOG_ADD_CONSOLE_APPENDER(logger, target, pattern) { \ gr::logger_add_console_appender(logger,target,pattern);} #define GR_ADD_FILE_APPENDER(name, filename, append, pattern) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ gr::logger_add_file_appender(logger,filename,append,pattern);} #define GR_LOG_ADD_FILE_APPENDER(logger, filename, append, pattern) { \ gr::logger_add_file_appender(logger,filename,append,pattern);} #define GR_ADD_ROLLINGFILE_APPENDER(name, filename, filesize, bkup_index, append, mode, pattern) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ gr::logger_add_rollingfile_appender(logger,filename,filesize,bkup_index,append,mode,pattern);} #define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger, filename, filesize, bkup_index, append, mode, pattern) { \ gr::logger_add_rollingfile_appender(logger,filename,filesize,bkup_index,append,mode,pattern);} #define GR_GET_LOGGER_NAMES(names) { \ names = gr::logger_get_logger_names();} #define GR_RESET_CONFIGURATION() \ gr::logger_config::reset_config(); /* Logger name referenced macros */ #define GR_DEBUG(name, msg) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger<< log4cpp::Priority::DEBUG << msg << log4cpp::eol;} #define GR_INFO(name, msg) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger<< log4cpp::Priority::INFO << msg << log4cpp::eol;} #define GR_NOTICE(name, msg) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger << log4cpp::Priority::NOTICE << msg;} #define GR_WARN(name, msg) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger<< log4cpp::Priority::WARN << msg << log4cpp::eol;} #define GR_ERROR(name, msg) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} #define GR_CRIT(name, msg) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger<< log4cpp::Priority::CRIT << msg << log4cpp::eol;} #define GR_ALERT(name, msg) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger<< log4cpp::Priority::ALERT << msg << log4cpp::eol;} #define GR_FATAL(name, msg) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger<< log4cpp::Priority::FATAL << msg << log4cpp::eol;} #define GR_EMERG(name, msg) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;} #define GR_ERRORIF(name, cond, msg) { \ if((cond)) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} \ } #define GR_ASSERT(name, cond, msg) { \ if(!(cond)) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ *logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;} \ assert(0); \ } /* LoggerPtr Referenced Macros */ #define GR_LOG_DEBUG(logger, msg) { \ *logger << log4cpp::Priority::DEBUG << msg << log4cpp::eol;} #define GR_LOG_INFO(logger, msg) { \ *logger << log4cpp::Priority::INFO << msg << log4cpp::eol;} #define GR_LOG_NOTICE(logger, msg) { \ *logger << log4cpp::Priority::NOTICE << msg << log4cpp::eol;} #define GR_LOG_WARN(logger, msg) { \ *logger << log4cpp::Priority::WARN << msg << log4cpp::eol;} #define GR_LOG_ERROR(logger, msg) { \ *logger << log4cpp::Priority::ERROR << msg << log4cpp::eol;} #define GR_LOG_CRIT(logger, msg) { \ *logger << log4cpp::Priority::CRIT << msg << log4cpp::eol;} #define GR_LOG_ALERT(logger, msg) { \ *logger << log4cpp::Priority::ALERT << msg << log4cpp::eol;} #define GR_LOG_FATAL(logger, msg) { \ *logger << log4cpp::Priority::FATAL << msg << log4cpp::eol;} #define GR_LOG_EMERG(logger, msg) { \ *logger << log4cpp::Priority::EMERG << msg << log4cpp::eol;} #define GR_LOG_ERRORIF(logger,cond, msg) { \ if((cond)) { \ *logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} \ } #define GR_LOG_ASSERT(logger, cond, msg) { \ if(!(cond)) { \ *logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol; \ assert(0);} \ } namespace gr { /*! * \brief Class to control configuration of logger. * This is a singleton that cna launch a thread to wathc a config file for changes * \ingroup logging */ class logger_config { private: /*! \brief filename of logger config file */ std::string filename; /*! \brief Period (seconds) over which watcher thread checks config file for changes */ unsigned int watch_period; /*! \brief Pointer to watch thread for config file changes */ boost::thread *watch_thread; /*! \brief Watcher thread method * /param filename Name of configuration file * /param watch_period Seconds between checks for changes in config file */ static void watch_file(std::string filename,unsigned int watch_period); static bool logger_configured; logger_config() { } //!< Constructor /* rpcbasic_register_get rpc_get_filename; rpcbasic_register_get rpc_get_watchperiod; rpcbasic_register_get rpc_get_config; rpcbasic_register_set rpc_set_config; */ logger_config(logger_config const&); //! logger_get_logger_names(void); } /* namespace gr */ #endif /* HAVE_LOG4CPP */ // If Logger disable do nothing #else /* ENABLE_GR_LOG */ namespace gr { typedef void* logger_ptr; } /* namespace gr */ #define GR_LOG_DECLARE_LOGPTR(logger) #define GR_LOG_ASSIGN_LOGPTR(logger,name) #define GR_CONFIG_LOGGER(config) #define GR_CONFIG_AND_WATCH_LOGGER(config,period) #define GR_LOG_GETLOGGER(logger, name) #define GR_SET_LEVEL(name, level) #define GR_LOG_SET_LEVEL(logger, level) #define GR_GET_LEVEL(name, level) #define GR_LOG_GET_LEVEL(logger, level) #define GR_ADD_APPENDER(name,appender) #define GR_LOG_ADD_APPENDER(logger,appender) #define GR_ADD_CONSOLE_APPENDER(logger,target,pattern) #define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern) #define GR_ADD_FILE_APPENDER(name,filename,append,pattern) #define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern) #define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern) #define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern) #define GR_GET_LOGGER_NAMES(names) #define GR_RESET_CONFIGURATION() #define GR_DEBUG(name, msg) #define GR_INFO(name, msg) #define GR_NOTICE(name, msg) #define GR_WARN(name, msg) #define GR_ERROR(name, msg) #define GR_ALERT(name, msg) #define GR_CRIT(name, msg) #define GR_FATAL(name, msg) #define GR_EMERG(name, msg) #define GR_ERRORIF(name, cond, msg) #define GR_ASSERT(name, cond, msg) #define GR_LOG_DEBUG(logger, msg) #define GR_LOG_INFO(logger, msg) #define GR_LOG_NOTICE(logger, msg) #define GR_LOG_WARN(logger, msg) #define GR_LOG_ERROR(logger, msg) #define GR_LOG_ALERT(logger, msg) #define GR_LOG_CRIT(logger, msg) #define GR_LOG_FATAL(logger, msg) #define GR_LOG_EMERG(logger, msg) #define GR_LOG_ERRORIF(logger, cond, msg) #define GR_LOG_ASSERT(logger, cond, msg) #endif /* ENABLE_GR_LOG */ namespace gr { // Even if logger is disabled we'll need for methods below to exist in python. // The macros these call will be disabled if ENABLE_GR_LOG is undefined /********************* Start Classes and Methods for Python ******************/ /*! * \brief Logger class for referencing loggers in python. Not * needed in C++ (use macros) Wraps and manipulates loggers for * python as python has no macros * \ingroup logging * */ class logger { private: /*! \brief logger pointer to logger associated wiith this wrapper class */ logger_ptr d_logger; public: /*! * \brief contructor Provide name of logger to associate with this class * \param logger_name Name of logger associated with class */ logger(std::string logger_name) { GR_LOG_ASSIGN_LOGPTR(d_logger,logger_name); }; /*! \brief Destructor */ ~logger(){;} // Wrappers for logging macros /*! \brief inline function, wrapper to set the logger level */ void set_level(std::string level){GR_LOG_SET_LEVEL(d_logger,level);} /*! \brief inline function, wrapper to get the logger level */ void get_level(std::string &level){GR_LOG_GET_LEVEL(d_logger,level);} /*! \brief inline function, wrapper for LOG4CPP_DEBUG for DEBUG message */ void debug(std::string msg){GR_LOG_DEBUG(d_logger,msg);}; /*! \brief inline function, wrapper for LOG4CPP_INFO for INFO message */ void info(std::string msg){GR_LOG_INFO(d_logger,msg);} /*! \brief inline function, wrapper for NOTICE message */ void notice(std::string msg){GR_LOG_NOTICE(d_logger,msg);} /*! \brief inline function, wrapper for LOG4CPP_WARN for WARN message */ void warn(std::string msg){GR_LOG_WARN(d_logger,msg);} /*! \brief inline function, wrapper for LOG4CPP_ERROR for ERROR message */ void error(std::string msg){GR_LOG_ERROR(d_logger,msg);} /*! \brief inline function, wrapper for NOTICE message */ void crit(std::string msg){GR_LOG_CRIT(d_logger,msg);} /*! \brief inline function, wrapper for ALERT message */ void alert(std::string msg){GR_LOG_ALERT(d_logger,msg);} /*! \brief inline function, wrapper for FATAL message */ void fatal(std::string msg){GR_LOG_FATAL(d_logger,msg);} /*! \brief inline function, wrapper for EMERG message */ void emerg(std::string msg){GR_LOG_EMERG(d_logger,msg);} /*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */ void errorIF(bool cond,std::string msg){GR_LOG_ERRORIF(d_logger,cond,msg);} /*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */ void log_assert(bool cond,std::string msg){GR_LOG_ASSERT(d_logger,cond,msg);} /*! \brief inline function, Method to add appender to logger by name (define appender in conf file) */ void add_appender(std::string appender) { GR_LOG_ADD_APPENDER(d_logger, appender); } /*! \brief inline function, Method to add console appender to logger */ void add_console_appender(std::string target,std::string pattern) { GR_LOG_ADD_CONSOLE_APPENDER(d_logger, target, pattern); } /*! \brief inline function, Method to add file appender to logger */ void add_file_appender(std::string filename, bool append, std::string pattern) { GR_LOG_ADD_FILE_APPENDER(d_logger, filename, append, pattern); } /*! \brief inline function, Method to add rolling file appender to logger */ void add_rollingfile_appender(std::string filename, size_t filesize, int bkup_index, bool append, mode_t mode, std::string pattern) { GR_LOG_ADD_ROLLINGFILE_APPENDER(d_logger,filename,filesize, bkup_index,append,mode,pattern); } }; } /* namespace gr */ /**************** Start Configuration Class and Methods for Python ************/ /*! * \brief Function to call configuration macro from python. * Note: Configuration is only updated if filename or watch_period has changed. * \param config_filename Name of configuration file * \param watch_period Seconds to wait between checking for changes in conf file. * Watch_period defaults to 0 in which case the file is not watched for changes */ GR_RUNTIME_API void gr_logger_config(const std::string config_filename, unsigned int watch_period = 0); /*! * \brief Function to return logger names to python * \return Vector of name strings * */ GR_RUNTIME_API std::vector gr_logger_get_logger_names(void); /*! * \brief Function to reset logger configuration from python * */ GR_RUNTIME_API void gr_logger_reset_config(void); #endif /* INCLUDED_GR_LOGGER_H */