| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  | #include "Logger.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/algorithm/string/predicate.hpp>
 | 
					
						
							|  |  |  | #include <boost/date_time/posix_time/posix_time.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/core.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/common.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/sinks.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/expressions.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/expressions/keyword.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/attributes.hpp>
 | 
					
						
							| 
									
										
										
										
											2020-10-10 14:38:54 +01:00
										 |  |  | #include <boost/log/attributes/clock.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/attributes/counter.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/attributes/current_process_id.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/attributes/current_thread_id.hpp>
 | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  | #include <boost/log/utility/setup/console.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/utility/setup/filter_parser.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/utility/setup/from_stream.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/utility/setup/settings.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/sinks/sync_frontend.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/sinks/text_ostream_backend.hpp>
 | 
					
						
							|  |  |  | #include <boost/log/support/date_time.hpp>
 | 
					
						
							|  |  |  | #include <boost/shared_ptr.hpp>
 | 
					
						
							|  |  |  | #include <boost/make_shared.hpp>
 | 
					
						
							| 
									
										
										
										
											2020-12-04 19:01:05 +00:00
										 |  |  | #include <boost/filesystem/fstream.hpp>
 | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  | #include <string>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 19:01:05 +00:00
										 |  |  | namespace fs = boost::filesystem; | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  | namespace logging = boost::log; | 
					
						
							|  |  |  | namespace srcs = logging::sources; | 
					
						
							|  |  |  | namespace sinks = logging::sinks; | 
					
						
							|  |  |  | namespace keywords = logging::keywords; | 
					
						
							|  |  |  | namespace expr = logging::expressions; | 
					
						
							|  |  |  | namespace attrs = logging::attributes; | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  | namespace ptime = boost::posix_time; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 22:24:34 +00:00
										 |  |  | BOOST_LOG_GLOBAL_LOGGER_CTOR_ARGS (sys, | 
					
						
							|  |  |  |                                    srcs::severity_channel_logger_mt<logging::trivial::severity_level>, | 
					
						
							|  |  |  |                                    (keywords::channel = "SYSLOG")); | 
					
						
							|  |  |  | BOOST_LOG_GLOBAL_LOGGER_CTOR_ARGS (data, | 
					
						
							|  |  |  |                                    srcs::severity_channel_logger_mt<logging::trivial::severity_level>, | 
					
						
							|  |  |  |                                    (keywords::channel = "DATALOG")); | 
					
						
							| 
									
										
										
										
											2020-10-01 23:32:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  | namespace Logger | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   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 | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |       : public logging::basic_formatter_factory<char, ptime::ptime> | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |       formatter_type create_formatter (logging::attribute_name const& name, args_map const& args) | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |       { | 
					
						
							|  |  |  |         args_map::const_iterator it = args.find ("format"); | 
					
						
							|  |  |  |         if (it != args.end ()) | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             return expr::stream  | 
					
						
							|  |  |  |               << expr::format_date_time<ptime::ptime> | 
					
						
							|  |  |  |               ( | 
					
						
							|  |  |  |                expr::attr<ptime::ptime> (name), it->second | 
					
						
							|  |  |  |                ); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             return expr::stream  | 
					
						
							|  |  |  |               << expr::attr<ptime::ptime> (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 | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |       : public logging::basic_formatter_factory<char, ptime::time_duration> | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |       formatter_type create_formatter (logging::attribute_name const& name, args_map const& args) | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |       { | 
					
						
							|  |  |  |         args_map::const_iterator it = args.find ("format"); | 
					
						
							|  |  |  |         if (it != args.end ()) | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             return expr::stream | 
					
						
							|  |  |  |               << expr::format_date_time<ptime::time_duration> | 
					
						
							|  |  |  |               ( | 
					
						
							|  |  |  |                expr::attr<ptime::time_duration> (name), it->second | 
					
						
							|  |  |  |                ); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             return expr::stream | 
					
						
							|  |  |  |               << expr::attr<ptime::time_duration> (name); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class CommonInitialization | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |       CommonInitialization () | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2020-10-10 14:38:54 +01:00
										 |  |  |         // Add attributes: LineID, TimeStamp, ProcessID, ThreadID, and Uptime
 | 
					
						
							|  |  |  |         auto core = logging::core::get (); | 
					
						
							|  |  |  |         core->add_global_attribute ("LineID", attrs::counter<unsigned int> (1)); | 
					
						
							| 
									
										
										
										
											2020-10-10 15:15:10 +01:00
										 |  |  |         core->add_global_attribute ("TimeStamp", attrs::utc_clock ()); | 
					
						
							|  |  |  |         core->add_global_attribute ("ProcessID", attrs::current_process_id ()); | 
					
						
							|  |  |  |         core->add_global_attribute ("ThreadID", attrs::current_thread_id ()); | 
					
						
							| 
									
										
										
										
											2020-10-10 14:38:54 +01:00
										 |  |  |         core->add_global_attribute ("Uptime", attrs::timer ()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |         // Allows %Severity% to be used in ini config file for property Filter.
 | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |         logging::register_simple_filter_factory<logging::trivial::severity_level, char> ("Severity"); | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |         // Allows %Severity% to be used in ini config file for property Format.
 | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |         logging::register_simple_formatter_factory<logging::trivial::severity_level, char> ("Severity"); | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |         // Allows %TimeStamp(format=\"%Y.%m.%d %H:%M:%S.%f\")% to be used in ini config file for property Format.
 | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |         logging::register_formatter_factory ("TimeStamp", boost::make_shared<TimeStampFormatterFactory> ()); | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |         // Allows %Uptime(format=\"%O:%M:%S.%f\")% to be used in ini config file for property Format.
 | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |         logging::register_formatter_factory ("Uptime", boost::make_shared<UptimeFormatterFactory> ()); | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |       ~CommonInitialization () | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void init () | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     CommonInitialization ci; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 19:01:05 +00:00
										 |  |  |   void init_from_config (std::wistream& stream) | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |     CommonInitialization ci; | 
					
						
							|  |  |  |     try | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         // Still can throw even with the exception suppressor above.
 | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |         logging::init_from_stream (stream); | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |     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 () | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |     logging::core::get ()->set_logging_enabled (false); | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 19:01:05 +00:00
										 |  |  |   void add_datafile_log (std::wstring const& log_file_name) | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |     // Create a text file sink
 | 
					
						
							| 
									
										
										
										
											2020-12-04 19:01:05 +00:00
										 |  |  |     boost::shared_ptr<sinks::wtext_ostream_backend> backend | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |       ( | 
					
						
							| 
									
										
										
										
											2020-12-04 19:01:05 +00:00
										 |  |  |        new sinks::wtext_ostream_backend() | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |        ); | 
					
						
							| 
									
										
										
										
											2020-12-04 19:01:05 +00:00
										 |  |  |     backend->add_stream (boost::shared_ptr<std::wostream> (new fs::wofstream (log_file_name))); | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |       | 
					
						
							|  |  |  |     // Flush after each log record
 | 
					
						
							|  |  |  |     backend->auto_flush (true); | 
					
						
							|  |  |  |       | 
					
						
							|  |  |  |     // Create a sink for the backend
 | 
					
						
							| 
									
										
										
										
											2020-12-04 19:01:05 +00:00
										 |  |  |     typedef sinks::synchronous_sink<sinks::wtext_ostream_backend> sink_t; | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |     boost::shared_ptr<sink_t> sink (new sink_t (backend)); | 
					
						
							|  |  |  |       | 
					
						
							|  |  |  |     // The log output formatter
 | 
					
						
							| 
									
										
										
										
											2020-12-04 19:01:05 +00:00
										 |  |  |     sink->set_formatter (expr::format (L"[%1%][%2%] %3%") | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |                          % expr::attr<ptime::ptime> ("TimeStamp") | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |                          % logging::trivial::severity | 
					
						
							| 
									
										
										
										
											2020-09-26 14:15:44 +01:00
										 |  |  |                          % expr::message | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |                          ); | 
					
						
							|  |  |  |       | 
					
						
							|  |  |  |     // Filter by severity and by DATALOG channel
 | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |     sink->set_filter (logging::trivial::severity >= logging::trivial::info && | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |                       expr::attr<std::string> ("Channel") == "DATALOG"); | 
					
						
							|  |  |  |       | 
					
						
							|  |  |  |     // Add it to the core
 | 
					
						
							| 
									
										
										
										
											2020-09-24 18:55:00 +01:00
										 |  |  |     logging::core::get ()->add_sink (sink); | 
					
						
							| 
									
										
										
										
											2020-09-18 21:12:53 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | } |