TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/common/utils/Formatter.cpp
Go to the documentation of this file.
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 }