libmoost
|
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