libmoost
/home/mhx/git/github/libmoost/include/moost/logging/standard_console.hpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #ifndef MOOST_LOGGING_LEVELS_HPP
00029 #define MOOST_LOGGING_LEVELS_HPP
00030 
00031 #include <stdexcept>
00032 #include <iostream>
00033 
00034 #include <boost/thread/shared_mutex.hpp>
00035 #include "../terminal_format.hpp"
00036 
00037 #if defined(_MSC_VER)
00038 #pragma warning (push)
00039 #pragma warning ( disable: 4231 4251 4275 4786 )
00040 #endif
00041 
00042 #include <log4cxx/level.h>
00043 
00044 #include <log4cxx/helpers/transcoder.h>
00045 #include <log4cxx/basicconfigurator.h>
00046 #include <log4cxx/patternlayout.h>
00047 #include <log4cxx/consoleappender.h>
00048 #include <log4cxx/logmanager.h>
00049 #include <log4cxx/logger.h>
00050 
00051 #include "detail/custompatternlayout.hpp"
00052 
00053 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
00054 
00055 namespace moost { namespace logging {
00056 
00073 class standard_console
00074 {
00075 public:
00076 
00081    standard_console(log4cxx::LevelPtr threshold = log4cxx::Level::getError(), std::string sLayout = "")
00082       : m_invalidLevel(new log4cxx::Level(-1, LOG4CXX_STR("INVALID"), 7 ))
00083    {
00084       using namespace log4cxx;
00085 
00086       if ( sLayout.empty() )
00087       {
00088          sLayout = std::string("[%d{yyyy-MMM-dd HH:mm:ss}|") +
00089                    moost::terminal_format::color("%c", moost::C_CYAN) +
00090                    std::string("](%p) %m%n");
00091       }
00092 
00093       LogManager::getLoggerRepository()->setConfigured(true);
00094       log4cxx::LoggerPtr root = Logger::getRootLogger();
00095 
00096       // The pattern. For details see
00097       // http://logging.apache.org/log4cxx/apidocs/classlog4cxx_1_1_pattern_layout.html
00098       //
00099       // "[%d{yyyy-MMM-dd HH:mm:ss}|%c]" // [date|"name"]
00100       // "(%p)" // level of the logging event
00101       // "%m"   // the message
00102       // "%n"   // new line
00103       static LogString lsLayout; // TTCC_CONVERSION_PATTERN(LOG4CXX_STR( layout ));
00104       helpers::Transcoder::decode(sLayout, lsLayout);
00105 
00106       //LayoutPtr layout(new CustomPatternLayout(lsLayout));
00107       LayoutPtr layout(new CustomPatternLayout(lsLayout));
00108       m_pAppender = new ConsoleAppender(layout);
00109 
00110       m_pAppender->setThreshold( threshold );
00111       root->addAppender(m_pAppender);
00112    }
00113 
00114    virtual ~standard_console()
00115    {}
00116 
00117    void enable()
00118    {
00119       log4cxx::Logger::getRootLogger()->addAppender(m_pAppender);
00120    }
00121 
00122    void disable()
00123    {
00124       log4cxx::Logger::getRootLogger()->removeAppender(m_pAppender);
00125    }
00126 
00142    bool setThreshold(int val)
00143    {
00144       //log4cxx::Level invalidLevel(-1);
00145       boost::unique_lock<boost::shared_mutex> lock(m_mutex);
00146 
00147       log4cxx::LevelPtr newLevel = log4cxx::Level::toLevel(val, m_invalidLevel);
00148       if ( newLevel == m_invalidLevel )
00149          return false;
00150       else
00151       {
00152          m_pAppender->setThreshold(newLevel);
00153          return true;
00154       }
00155    }
00156 
00157    bool setThreshold(const log4cxx::LevelPtr& level)
00158    {
00159       boost::unique_lock<boost::shared_mutex> lock(m_mutex);
00160       m_pAppender->setThreshold(level);
00161       return true;
00162    }
00163 
00164    bool setSmallThreshold(int val)
00165    {
00166       using namespace log4cxx;
00167 
00168       switch (val)
00169       {
00170       case 0:
00171          return setThreshold(Level::FATAL_INT);
00172          break;
00173       case 1:
00174          return setThreshold(Level::ERROR_INT);
00175          break;
00176       case 2:
00177          return setThreshold(Level::WARN_INT);
00178          break;
00179       case 3:
00180          return setThreshold(Level::INFO_INT);
00181          break;
00182       case 4:
00183          return setThreshold(Level::DEBUG_INT);
00184          break;
00185       case 5:
00186          return setThreshold(Level::TRACE_INT);
00187          break;
00188       case 6:
00189          return setThreshold(Level::ALL_INT);
00190          break;
00191       default:
00192          if ( val > 5 )
00193             return setThreshold(Level::ALL_INT);
00194 
00195          return false;
00196       }
00197       return true;
00198    }
00199 
00200    bool setThreshold(const std::string& str)
00201    {
00202       if ( isAllDigits(str) )
00203       {
00204          int val = atoi(str.c_str());
00205          if ( val < log4cxx::Level::TRACE_INT )
00206             return setSmallThreshold(val);
00207          else
00208          {
00209             return setThreshold(val);
00210          }
00211       }
00212       else
00213       {
00214          log4cxx::LevelPtr newLevel = log4cxx::Level::toLevel(str, m_invalidLevel);
00215          if ( newLevel == m_invalidLevel )
00216             return false;
00217          else
00218          {
00219             boost::unique_lock<boost::shared_mutex> lock(m_mutex);
00220             m_pAppender->setThreshold(newLevel);
00221             return true;
00222          }
00223       }
00224    }
00225 
00226    int getSmallThreshold()
00227    {
00228       using namespace log4cxx;
00229 
00230       int lint = 0;
00231       {
00232          boost::shared_lock<boost::shared_mutex> lock(m_mutex);
00233          lint = m_pAppender->getThreshold()->toInt();
00234       }
00235 
00236       switch (lint) {
00237          case Level::ALL_INT:
00238             return 6;
00239 
00240          case Level::TRACE_INT:
00241             return 5;
00242 
00243          case Level::DEBUG_INT:
00244             return 4;
00245 
00246          case Level::INFO_INT:
00247             return 3;
00248 
00249          case Level::WARN_INT:
00250             return 2;
00251 
00252          case Level::ERROR_INT:
00253             return 1;
00254 
00255          case Level::FATAL_INT:
00256             return 0;
00257 
00258          default:
00259             return -1;
00260       }
00261    }
00262 
00263    int getThreshold()
00264    {
00265       boost::shared_lock<boost::shared_mutex> lock(m_mutex);
00266       return m_pAppender->getThreshold()->toInt();
00267    }
00268 
00269    void getThreshold(std::string& level)
00270    {
00271       boost::shared_lock<boost::shared_mutex> lock(m_mutex);
00272       m_pAppender->getThreshold()->toString(level);
00273    }
00274 
00275 private:
00276 
00277    bool isAllDigits(const std::string& str)
00278    {
00279       for (std::string::const_iterator it = str.begin(); it != str.end(); ++it )
00280       {
00281          if ( std::isspace(*it) )
00282             continue;
00283          else if ( !std::isdigit(*it) )
00284             return false;
00285       }
00286 
00287       return true;
00288    }
00289 
00290 private:
00291 
00292    boost::shared_mutex m_mutex;
00293    log4cxx::ConsoleAppenderPtr m_pAppender;
00294    log4cxx::LevelPtr m_invalidLevel;
00295 };
00296 
00297 }}
00298 
00299 #if defined(_MSC_VER)
00300 #pragma warning ( pop )
00301 #endif
00302 
00303 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
00304 
00305 #endif // MOOST_LOGGING_LEVELS_HPP