-
Notifications
You must be signed in to change notification settings - Fork 6
/
logger.cxx
161 lines (142 loc) · 6.29 KB
/
logger.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// logger.cxx
#include "logger.hxx"
#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/utility/exception_handler.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/filter_parser.hpp>
#include <boost/log/utility/setup/formatter_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 <fstream>
#include <string>
BOOST_LOG_GLOBAL_LOGGER_CTOR_ARGS(sysLogger,
boost::log::sources::severity_channel_logger_mt<boost::log::trivial::severity_level>,
(boost::log::keywords::channel = "SYSLF"));
BOOST_LOG_GLOBAL_LOGGER_CTOR_ARGS(dataLogger,
boost::log::sources::severity_channel_logger_mt<boost::log::trivial::severity_level>,
(boost::log::keywords::channel = "DATALF"));
// 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 boost::log::basic_formatter_factory<char, boost::posix_time::ptime>
{
public:
formatter_type create_formatter(const boost::log::attribute_name& name, const args_map& args) {
args_map::const_iterator it = args.find("format");
if (it != args.end()) {
return boost::log::expressions::stream
<< boost::log::expressions::format_date_time<boost::posix_time::ptime>(
boost::log::expressions::attr<boost::posix_time::ptime>(name), it->second);
} else {
return boost::log::expressions::stream
<< boost::log::expressions::attr<boost::posix_time::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.
// boost::log::attributes::timer value type is boost::posix_time::time_duration
class UptimeFormatterFactory :
public boost::log::basic_formatter_factory<char, boost::posix_time::time_duration>
{
public:
formatter_type create_formatter(const boost::log::attribute_name& name, const args_map& args)
{
args_map::const_iterator it = args.find("format");
if (it != args.end()) {
return boost::log::expressions::stream
<< boost::log::expressions::format_date_time<boost::posix_time::time_duration>(
boost::log::expressions::attr<boost::posix_time::time_duration>(name), it->second);
} else {
return boost::log::expressions::stream
<< boost::log::expressions::attr<boost::posix_time::time_duration>(name);
}
}
};
void
Logger::init() {
initFromConfig("");
}
void
Logger::initFromConfig(const std::string& configFileName) {
// Disable all exceptions
boost::log::core::get()->set_exception_handler(boost::log::make_exception_suppressor());
// Add common attributes: LineID, TimeStamp, ProcessID, ThreadID
boost::log::add_common_attributes();
// Add boost log timer as global attribute Uptime
boost::log::core::get()->add_global_attribute("Uptime", boost::log::attributes::timer());
// Allows %Severity% to be used in ini config file for property Filter.
boost::log::register_simple_filter_factory<boost::log::trivial::severity_level, char>("Severity");
// Allows %Severity% to be used in ini config file for property Format.
boost::log::register_simple_formatter_factory<boost::log::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.
boost::log::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.
boost::log::register_formatter_factory("Uptime", boost::make_shared<UptimeFormatterFactory>());
if (configFileName.empty()) {
// Make sure we log to console if nothing specified.
// Severity logger logs to console by default.
} else {
std::ifstream ifs(configFileName);
if (!ifs.is_open()) {
// We can log this because console is setup by default
LOG_WARN("Unable to open logging config file: " << configFileName);
} else {
try {
// Still can throw even with the exception suppressor above.
boost::log::init_from_stream(ifs);
} 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);
}
}
}
// Indicate start of logging
LOG_INFO("Log Start");
}
void
Logger::disable() {
boost::log::core::get()->set_logging_enabled(false);
}
void
Logger::addDataFileLog(const std::string& logFileName) {
// Create a text file sink
boost::shared_ptr<boost::log::sinks::text_ostream_backend> backend(
new boost::log::sinks::text_ostream_backend());
backend->add_stream(boost::shared_ptr<std::ostream>(new std::ofstream(logFileName)));
// Flush after each log record
backend->auto_flush(true);
// Create a sink for the backend
typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend> sink_t;
boost::shared_ptr<sink_t> sink(new sink_t(backend));
// The log output formatter
sink->set_formatter(
boost::log::expressions::format("[%1%][%2%] %3%")
% boost::log::expressions::attr<boost::posix_time::ptime>("TimeStamp")
% boost::log::trivial::severity
% boost::log::expressions::smessage
);
// Filter by severity and by DATALF channel
sink->set_filter(
boost::log::trivial::severity >= boost::log::trivial::info &&
boost::log::expressions::attr<std::string>("Channel") == "DATALF");
// Add it to the core
boost::log::core::get()->add_sink(sink);
}