libmoost
/home/mhx/git/github/libmoost/include/moost/logging/global.hpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00035 #ifndef MOOST_LOGGING_GLOBAL_HPP__
00036 #define MOOST_LOGGING_GLOBAL_HPP__
00037 
00038 #include <iostream>
00039 #include <boost/filesystem.hpp>
00040 
00041 #include <log4cxx/logger.h>
00042 #include <log4cxx/basicconfigurator.h>
00043 #include <log4cxx/logmanager.h>
00044 #include <log4cxx/propertyconfigurator.h>
00045 
00046 #include "../utils/singleton.hpp"
00047 #include "pseudo_ostream.hpp"
00048 #include "../compiler/attributes.hpp"
00049 
00055 #define MLOG_INIT() \
00056    moost::logging::global_singleton::instance().enable(std::string(*argv))
00057 
00063 #define MLOG_IS_INITIALISED() \
00064    moost::logging::global_singleton::instance().is_configured() && \
00065    moost::logging::global_singleton::instance().is_enabled()
00066 
00067 namespace moost { namespace logging {
00068 
00084    class global
00085    {
00086    template <typename T> friend
00087       class moost::utils::singleton_default<T>::friend_type;
00088 
00089    private:
00090       global()
00091          : enabled_(false)
00092       {
00093          // Initially, logging shall be disabled
00094          disable();
00095       }
00096 
00097    public:
00098 
00107       bool is_enabled() const
00108       {
00109          return enabled_;
00110       }
00111 
00120       bool is_configured() const
00121       {
00122          return log4cxx::LogManager::getLoggerRepository()->isConfigured();
00123       }
00124 
00131       bool enable()
00132       {
00133          out_
00134             << "Enable logging using default basic config"
00135             << std::endl;
00136 
00137          log4cxx::BasicConfigurator::configure();
00138          log4cxx::Logger::getRootLogger()->setLevel(log4cxx::Level::getDebug());
00139          return set_enabled(is_configured());
00140       }
00141 
00155       bool enable(boost::filesystem::path const & filepath,
00156             bool use_default = false)
00157       {
00158          out_
00159             << "Enable logging using "
00160             << filepath
00161             << std::endl;
00162 
00163          log4cxx::LogManager::shutdown();
00164 
00165          if(boost::filesystem::exists(filepath))
00166          {
00167             log4cxx::PropertyConfigurator::configure(filepath.string());
00168          }
00169          else
00170          if(use_default)
00171          {
00172             return enable();
00173          }
00174 
00175          return set_enabled(is_configured());
00176       }
00177 
00195       bool enable(std::string const & filepath,
00196             bool use_default = false)
00197       {
00198          // whether name is a filename or a path this returns the leaf
00199          std::string s = boost::filesystem::path(filepath).leaf();
00200 
00201          s.append(".lcf");
00202          char const * search_path[] = {
00203             //-------------------------------------------------
00204             // you get these paths for free when building debug
00205 #ifndef NDEBUG
00206             "./",
00207             "./etc/",
00208             "./etc/mir/",
00209             "~/",
00210             "~/.mir/",
00211 #endif
00212             //-------------------------------------------------
00213             "/etc/",
00214             "/etc/mir/",
00215          };
00216 
00217          size_t const search_path_len =
00218             sizeof(search_path)/sizeof(search_path[0]);
00219          std::string cfgfile;
00220          bool found = false;
00221 
00222          out_
00223             << "Searching for logging config file..."
00224             << std::endl;
00225 
00226          for(size_t i = 0; i < search_path_len && !found; i++)
00227          {
00228             cfgfile = (boost::filesystem::path(search_path[i]) /= s).string();
00229 
00230             out_
00231                << "-  trying: "
00232                << cfgfile
00233                << std::endl;
00234 
00235             found = boost::filesystem::exists(cfgfile);
00236          }
00237 
00238          out_
00239             << "Logging config "
00240             << (found?"":"not ")
00241             << "found"
00242             << std::endl;
00243 
00244          if(found)
00245          {
00246             return enable(boost::filesystem::path(cfgfile), use_default);
00247          }
00248 
00249          return enable();
00250       }
00251 
00258       void disable()
00259       {
00260          log4cxx::LogManager::getLoggerRepository()->setConfigured(true);
00261          log4cxx::Logger::getRootLogger()->setLevel(log4cxx::Level::getOff());
00262          enabled_ = false;
00263 
00264          out_
00265             << "All logging has been disabled"
00266             << std::endl;
00267       }
00268 
00285       void attach_ostream(std::ostream & out)
00286       {
00287          out_.attach(out);
00288       }
00289 
00297       void detach_ostream()
00298       {
00299          out_.detach();
00300       }
00301 
00307       pseudo_ostream & get_ostream()
00308       {
00309          return out_;
00310       }
00311 
00312    private:
00313       bool set_enabled(bool enabled)
00314       {
00315          enabled_ = enabled;
00316 
00317           out_
00318              << "logging was "
00319              << (enabled_?"":"not ")
00320              << "successfully enabled"
00321              << std::endl;
00322 
00323           return enabled_;
00324       }
00325 
00326 
00327    private:
00328       bool enabled_;
00329       pseudo_ostream out_;
00330    };
00331 
00339    typedef moost::utils::singleton_default<global> global_singleton;
00340 
00345    constructor__(init_global_singleton)
00346    {
00347       global_singleton::instance().disable();
00348    }
00349 }}
00350 
00351 #endif