TuttleOFX
1
|
00001 #include "Formatter.hpp" 00002 00003 #include <tuttle/common/utils/global.hpp> 00004 #include <tuttle/common/exceptions.hpp> 00005 00006 #include <boost/assign/list_of.hpp> 00007 #include <boost/algorithm/string/case_conv.hpp> 00008 #include <boost/lexical_cast.hpp> 00009 00010 00011 namespace tuttle { 00012 namespace common { 00013 00014 boost::shared_ptr<Formatter> Formatter::get() 00015 { 00016 if( _formatter.get() == NULL ) 00017 _formatter.reset( new Formatter() ); 00018 return _formatter; 00019 } 00020 00021 boost::shared_ptr<Formatter> Formatter::_formatter; 00022 00023 00024 Formatter::Formatter() 00025 { 00026 init_logging(); 00027 00028 const char* envLevel = std::getenv("TUTTLE_LOG_LEVEL"); 00029 if( envLevel == NULL ) 00030 { 00031 setLogLevel( boost::log::trivial::warning ); 00032 } 00033 else 00034 { 00035 setLogLevel_string( envLevel ); 00036 } 00037 } 00038 00039 void Formatter::init_logging() 00040 { 00041 #ifndef WITHOUT_BOOST_LOG 00042 namespace sinks = boost::log::sinks; 00043 00044 // Create a backend and attach a stream to it 00045 boost::shared_ptr< sinks::text_ostream_backend > backend = boost::make_shared< sinks::text_ostream_backend >(); 00046 backend->add_stream( boost::shared_ptr< std::ostream >( &std::clog, boost::empty_deleter() ) ); 00047 //backend->add_stream( boost::shared_ptr< std::ostream >( new std::ofstream("sample.log") ) ); 00048 00049 // Enable auto-flushing after each log record written 00050 backend->auto_flush(true); 00051 00052 // Wrap it into the frontend and register in the core. 00053 _sink = boost::make_shared< sink_t >( backend ); 00054 00055 // Specify format of the log records 00056 displayLogLevel( false ); 00057 00058 // Register the sink in the logging core 00059 boost::log::core::get()->add_sink( _sink ); 00060 #endif 00061 } 00062 00063 void Formatter::setLogLevel_int( const int level ) 00064 { 00065 switch( level ) 00066 { 00067 case 0: setLogLevel( boost::log::trivial::trace ); break; 00068 case 1: setLogLevel( boost::log::trivial::debug ); break; 00069 case 2: setLogLevel( boost::log::trivial::info ); break; 00070 case 3: setLogLevel( boost::log::trivial::warning ); break; 00071 case 4: setLogLevel( boost::log::trivial::error ); break; 00072 case 5: setLogLevel( boost::log::trivial::fatal ); break; 00073 default: 00074 setLogLevel( boost::log::trivial::warning ); 00075 TUTTLE_LOG_WARNING( "Unrecognized log level " << level << ", fallback to \"warning\" (3)." ); 00076 break; 00077 } 00078 } 00079 00080 int logLevel_stringToInt( const std::string& level ) 00081 { 00082 static const std::vector<std::string> m = boost::assign::list_of 00083 ("trace") 00084 ("debug") 00085 ("info") 00086 ("warning") 00087 ("error") 00088 ("fatal"); 00089 std::string lowerStrLevel = level; 00090 boost::algorithm::to_lower(lowerStrLevel); 00091 00092 std::vector<std::string>::const_iterator v = std::find(m.begin(), m.end(), lowerStrLevel); 00093 00094 if( v == m.end() ) 00095 { 00096 TUTTLE_LOG_WARNING( "Unrecognized log level " << quotes(level) << ", fallback to \"warning\" (3)." ); 00097 return 3; 00098 } 00099 return std::distance(m.begin(), v); 00100 } 00101 00102 void Formatter::setLogLevel_string( const std::string& level ) 00103 { 00104 int levelInt = 0; 00105 try 00106 { 00107 // level is a string containing an integer 00108 levelInt = boost::lexical_cast<int>(level); 00109 setLogLevel_int( levelInt ); 00110 } 00111 catch(const boost::bad_lexical_cast &) 00112 { 00113 // level is a string containing an level like "warning" 00114 levelInt = logLevel_stringToInt(level); 00115 } 00116 setLogLevel_int( levelInt ); 00117 } 00118 00119 void Formatter::setLogLevel( const boost::log::trivial::severity_level level ) 00120 { 00121 #ifndef WITHOUT_BOOST_LOG 00122 boost::log::core::get()->set_filter( boost::log::trivial::severity >= level ); 00123 #endif 00124 } 00125 00126 void Formatter::displayLogLevel( bool display ) 00127 { 00128 #ifndef WITHOUT_BOOST_LOG 00129 namespace expr = boost::log::expressions; 00130 _sink->reset_formatter(); 00131 if( display ) 00132 { 00133 _sink->set_formatter( 00134 expr::stream 00135 //<< Color::get()->_yellow << "[" + logging::trivial::severity + "]" << Color::get()->_std << " " 00136 << "["<< boost::log::trivial::severity << "]" << " " 00137 << expr::smessage 00138 ); 00139 } 00140 else 00141 { 00142 _sink->set_formatter ( expr::stream << expr::smessage ); 00143 } 00144 #endif 00145 } 00146 00147 } 00148 }