#include "Logger.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace logger = boost::log; namespace srcs = logger::sources; namespace sinks = logger::sinks; namespace keywords = logger::keywords; namespace expr = logger::expressions; namespace attrs = logger::attributes; namespace ptime = boost::posix_time; namespace Logger { BOOST_LOG_GLOBAL_LOGGER_CTOR_ARGS (sys, srcs::severity_channel_logger_mt, (keywords::channel = "SYSLOG")); BOOST_LOG_GLOBAL_LOGGER_CTOR_ARGS (data, srcs::severity_channel_logger_mt, (keywords::channel = "DATALOG")); namespace { // Custom formatter factory to add TimeStamp format support in config ini file. // Allows %TimeStamp(format=\"%Y.%m.%d %H:%M:%S.%f\")% to be used in ini config file for property Format. class TimeStampFormatterFactory : public logger::basic_formatter_factory { public: formatter_type create_formatter (logger::attribute_name const& name, args_map const& args) { args_map::const_iterator it = args.find ("format"); if (it != args.end ()) { return expr::stream << expr::format_date_time ( expr::attr (name), it->second ); } else { return expr::stream << expr::attr (name); } } }; // Custom formatter factory to add Uptime format support in config ini file. // Allows %Uptime(format=\"%O:%M:%S.%f\")% to be used in ini config file for property Format. // attrs::timer value type is ptime::time_duration class UptimeFormatterFactory : public logger::basic_formatter_factory { public: formatter_type create_formatter (logger::attribute_name const& name, args_map const& args) { args_map::const_iterator it = args.find ("format"); if (it != args.end ()) { return expr::stream << expr::format_date_time ( expr::attr (name), it->second ); } else { return expr::stream << expr::attr (name); } } }; class CommonInitialization { public: CommonInitialization () { // Disable all exceptions logger::core::get ()->set_exception_handler (logger::make_exception_suppressor ()); // Add common attributes: LineID, TimeStamp, ProcessID, ThreadID logger::add_common_attributes (); // Add boost log timer as global attribute Uptime logger::core::get ()->add_global_attribute ("Uptime", attrs::timer ()); // Allows %Severity% to be used in ini config file for property Filter. logger::register_simple_filter_factory ("Severity"); // Allows %Severity% to be used in ini config file for property Format. logger::register_simple_formatter_factory ("Severity"); // Allows %TimeStamp(format=\"%Y.%m.%d %H:%M:%S.%f\")% to be used in ini config file for property Format. logger::register_formatter_factory ("TimeStamp", boost::make_shared ()); // Allows %Uptime(format=\"%O:%M:%S.%f\")% to be used in ini config file for property Format. logger::register_formatter_factory ("Uptime", boost::make_shared ()); } ~CommonInitialization () { // Indicate start of logging LOG_INFO ("Log Start"); } }; } void init () { CommonInitialization ci; // auto sink = boost::make_shared> (); // sink->set_filter (expr::is_debugger_present ()); // logger::core::get ()->add_sink (sink); } void init_from_config (std::istream& stream) { CommonInitialization ci; try { // Still can throw even with the exception suppressor above. logger::init_from_stream (stream); } catch (std::exception& e) { std::string err = "Caught exception initializing boost logging: "; err += e.what (); // Since we cannot be sure of boost log state, output to cerr and cout. std::cerr << "ERROR: " << err << std::endl; std::cout << "ERROR: " << err << std::endl; LOG_ERROR (err); } } void disable () { logger::core::get ()->set_logging_enabled (false); } void add_datafile_log (std::string const& log_file_name) { // Create a text file sink boost::shared_ptr backend ( new sinks::text_ostream_backend() ); backend->add_stream (boost::shared_ptr (new std::ofstream (log_file_name))); // Flush after each log record backend->auto_flush (true); // Create a sink for the backend typedef sinks::synchronous_sink sink_t; boost::shared_ptr sink (new sink_t (backend)); // The log output formatter sink->set_formatter (expr::format ("[%1%][%2%] %3%") % expr::attr ("TimeStamp") % logger::trivial::severity % expr::smessage ); // Filter by severity and by DATALOG channel sink->set_filter (logger::trivial::severity >= logger::trivial::info && expr::attr ("Channel") == "DATALOG"); // Add it to the core logger::core::get ()->add_sink (sink); } }