mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 13:10:19 -04:00 
			
		
		
		
	Parse errors revert to default logging to wsjtx_syslog.log with a suitable error message therein.
		
			
				
	
	
		
			186 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #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>
 | |
| #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>
 | |
| #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>
 | |
| #include <boost/filesystem/fstream.hpp>
 | |
| #include <string>
 | |
| 
 | |
| namespace fs = boost::filesystem;
 | |
| namespace logging = boost::log;
 | |
| namespace srcs = logging::sources;
 | |
| namespace sinks = logging::sinks;
 | |
| namespace keywords = logging::keywords;
 | |
| namespace expr = logging::expressions;
 | |
| namespace attrs = logging::attributes;
 | |
| namespace ptime = boost::posix_time;
 | |
| 
 | |
| 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"));
 | |
| 
 | |
| 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
 | |
|       : public logging::basic_formatter_factory<char, ptime::ptime>
 | |
|     {
 | |
|     public:
 | |
|       formatter_type create_formatter (logging::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<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
 | |
|       : public logging::basic_formatter_factory<char, ptime::time_duration>
 | |
|     {
 | |
|     public:
 | |
|       formatter_type create_formatter (logging::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<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 ()
 | |
|       {
 | |
|         // Add attributes: LineID, TimeStamp, ProcessID, ThreadID, and Uptime
 | |
|         auto core = logging::core::get ();
 | |
|         core->add_global_attribute ("LineID", attrs::counter<unsigned int> (1));
 | |
|         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 ());
 | |
|         core->add_global_attribute ("Uptime", attrs::timer ());
 | |
| 
 | |
|         // Allows %Severity% to be used in ini config file for property Filter.
 | |
|         logging::register_simple_filter_factory<logging::trivial::severity_level, char> ("Severity");
 | |
|         // Allows %Severity% to be used in ini config file for property Format.
 | |
|         logging::register_simple_formatter_factory<logging::trivial::severity_level, char> ("Severity");
 | |
|         // Allows %TimeStamp(format=\"%Y.%m.%d %H:%M:%S.%f\")% to be used in ini config file for property Format.
 | |
|         logging::register_formatter_factory ("TimeStamp", boost::make_shared<TimeStampFormatterFactory> ());
 | |
|         // Allows %Uptime(format=\"%O:%M:%S.%f\")% to be used in ini config file for property Format.
 | |
|         logging::register_formatter_factory ("Uptime", boost::make_shared<UptimeFormatterFactory> ());
 | |
|       }
 | |
|       ~CommonInitialization ()
 | |
|       {
 | |
|       }
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   void init ()
 | |
|   {
 | |
|     CommonInitialization ci;
 | |
|   }
 | |
| 
 | |
|   void init_from_config (std::wistream& stream)
 | |
|   {
 | |
|     CommonInitialization ci;
 | |
|     try
 | |
|       {
 | |
|         // Still can throw even with the exception suppressor above.
 | |
|         logging::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;
 | |
|         LOG_ERROR (err);
 | |
|         throw;
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   void disable ()
 | |
|   {
 | |
|     logging::core::get ()->set_logging_enabled (false);
 | |
|   }
 | |
| 
 | |
|   void add_datafile_log (std::wstring const& log_file_name)
 | |
|   {
 | |
|     // Create a text file sink
 | |
|     boost::shared_ptr<sinks::wtext_ostream_backend> backend
 | |
|       (
 | |
|        new sinks::wtext_ostream_backend()
 | |
|        );
 | |
|     backend->add_stream (boost::shared_ptr<std::wostream> (new fs::wofstream (log_file_name)));
 | |
|      
 | |
|     // Flush after each log record
 | |
|     backend->auto_flush (true);
 | |
|      
 | |
|     // Create a sink for the backend
 | |
|     typedef sinks::synchronous_sink<sinks::wtext_ostream_backend> sink_t;
 | |
|     boost::shared_ptr<sink_t> sink (new sink_t (backend));
 | |
|      
 | |
|     // The log output formatter
 | |
|     sink->set_formatter (expr::format (L"[%1%][%2%] %3%")
 | |
|                          % expr::attr<ptime::ptime> ("TimeStamp")
 | |
|                          % logging::trivial::severity
 | |
|                          % expr::message
 | |
|                          );
 | |
|      
 | |
|     // Filter by severity and by DATALOG channel
 | |
|     sink->set_filter (logging::trivial::severity >= logging::trivial::info &&
 | |
|                       expr::attr<std::string> ("Channel") == "DATALOG");
 | |
|      
 | |
|     // Add it to the core
 | |
|     logging::core::get ()->add_sink (sink);
 | |
|   }
 | |
| }
 |