1 | #include <iostream>
|
---|
2 | #include <iomanip>
|
---|
3 | #include <cstdlib>
|
---|
4 | #include <fstream>
|
---|
5 | #include <boost/log/core.hpp>
|
---|
6 | #include <boost/log/sources/global_logger_storage.hpp>
|
---|
7 | #include <boost/log/sources/severity_logger.hpp>
|
---|
8 | #include <boost/log/sources/record_ostream.hpp>
|
---|
9 | #include <boost/log/attributes/clock.hpp>
|
---|
10 | #include <boost/log/attributes/current_process_name.hpp>
|
---|
11 | #include <boost/log/attributes/current_process_id.hpp>
|
---|
12 | #include <boost/log/attributes/current_thread_id.hpp>
|
---|
13 | #include <boost/log/utility/setup/file.hpp>
|
---|
14 | #include <boost/log/utility/setup/from_stream.hpp>
|
---|
15 | #include <boost/log/utility/manipulators/to_log.hpp>
|
---|
16 | #include <boost/log/utility/formatting_ostream.hpp>
|
---|
17 |
|
---|
18 | using namespace std;
|
---|
19 |
|
---|
20 | namespace logging = boost::log;
|
---|
21 | namespace keywords = boost::log::keywords;
|
---|
22 | namespace expr = boost::log::expressions;
|
---|
23 | namespace attr = boost::log::attributes;
|
---|
24 | namespace src = boost::log::sources;
|
---|
25 |
|
---|
26 | #define LFC1_LOG(logger, level) BOOST_LOG_SEV(logger, level) << "(" << __FILE__ << ", " << __LINE__ << ") "
|
---|
27 |
|
---|
28 | #define LFC1_LOG_TRACE(logger) LFC1_LOG(logger, trace)
|
---|
29 | #define LFC1_LOG_DEBUG(logger) LFC1_LOG(logger, debug)
|
---|
30 | #define LFC1_LOG_INFO(logger) LFC1_LOG(logger, info)
|
---|
31 | #define LFC1_LOG_WARNING(logger) LFC1_LOG(logger, warning)
|
---|
32 | #define LFC1_LOG_ERROR(logger) LFC1_LOG(logger, error)
|
---|
33 |
|
---|
34 | static const auto RET_SUCCESS = 0;
|
---|
35 | static const auto RET_FAIL = 1;
|
---|
36 | static const auto LOGGING_ENVIRONMENT_NAME = "LOGGING_CONFIG_FILE_NAME";
|
---|
37 | static const auto DEFAULT_LOGGING_CONFIG_FILE_NAME = "config/LogSettings.txt";
|
---|
38 |
|
---|
39 | enum ESeverityLevel
|
---|
40 | {
|
---|
41 | trace,
|
---|
42 | debug,
|
---|
43 | info,
|
---|
44 | warning,
|
---|
45 | error
|
---|
46 | };
|
---|
47 |
|
---|
48 | BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", ESeverityLevel)
|
---|
49 |
|
---|
50 | ostream& operator<<(ostream& arStream, ESeverityLevel avLevel)
|
---|
51 | {
|
---|
52 | static const char* pStrings[] =
|
---|
53 | {
|
---|
54 | "trace",
|
---|
55 | "debug",
|
---|
56 | "info",
|
---|
57 | "warning",
|
---|
58 | "error"
|
---|
59 | };
|
---|
60 |
|
---|
61 | if (static_cast<size_t>(avLevel) < sizeof(pStrings) / sizeof(*pStrings))
|
---|
62 | {
|
---|
63 | arStream << pStrings[avLevel];
|
---|
64 | }
|
---|
65 | else
|
---|
66 | {
|
---|
67 | arStream << static_cast<int>(avLevel);
|
---|
68 | }
|
---|
69 |
|
---|
70 | return arStream;
|
---|
71 | }
|
---|
72 |
|
---|
73 | logging::formatting_ostream& operator<<
|
---|
74 | (
|
---|
75 | logging::formatting_ostream& arStream,
|
---|
76 | logging::to_log_manip<ESeverityLevel, tag::severity> const& arManip
|
---|
77 | )
|
---|
78 | {
|
---|
79 | static const char* pStrings[] =
|
---|
80 | {
|
---|
81 | "TRACE",
|
---|
82 | "DEBUG",
|
---|
83 | "INFO",
|
---|
84 | "WARNING",
|
---|
85 | "ERROR"
|
---|
86 | };
|
---|
87 |
|
---|
88 | ESeverityLevel vLevel = arManip.get();
|
---|
89 | if (static_cast<size_t>(vLevel) < sizeof(pStrings) / sizeof(*pStrings))
|
---|
90 | {
|
---|
91 | arStream << pStrings[vLevel];
|
---|
92 | }
|
---|
93 | else
|
---|
94 | {
|
---|
95 | arStream << static_cast<int>(vLevel);
|
---|
96 | }
|
---|
97 |
|
---|
98 | return arStream;
|
---|
99 | }
|
---|
100 |
|
---|
101 | BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(SLogger, src::severity_logger<ESeverityLevel>)
|
---|
102 |
|
---|
103 | static void gvLoggingInit(const char* apConfigFileName = nullptr)
|
---|
104 | {
|
---|
105 | // Obtain the name of the logging configuration file.
|
---|
106 | if (apConfigFileName == nullptr || apConfigFileName[0] == 0)
|
---|
107 | {
|
---|
108 | if ((apConfigFileName = getenv(LOGGING_ENVIRONMENT_NAME)) == 0 || apConfigFileName[0] == 0)
|
---|
109 | {
|
---|
110 | apConfigFileName = DEFAULT_LOGGING_CONFIG_FILE_NAME;
|
---|
111 | }
|
---|
112 | }
|
---|
113 |
|
---|
114 | // Open the logging configuration file.
|
---|
115 | ifstream vConfigFile(apConfigFileName);
|
---|
116 | if (!vConfigFile.is_open())
|
---|
117 | {
|
---|
118 | // TODO: throw an exception
|
---|
119 | }
|
---|
120 |
|
---|
121 | // Read the contents of the logging configuration file.
|
---|
122 | logging::init_from_stream(vConfigFile);
|
---|
123 |
|
---|
124 | // Add the logging attributes that we require.
|
---|
125 | auto pCore = logging::core::get();
|
---|
126 | pCore->add_global_attribute("TimeStamp", attr::local_clock());
|
---|
127 | pCore->add_global_attribute("Process", attr::current_process_name());
|
---|
128 | pCore->add_global_attribute("ProcessID", attr::current_process_id());
|
---|
129 | pCore->add_global_attribute("ThreadID", attr::current_thread_id());
|
---|
130 | pCore->set_filter(severity >= info);
|
---|
131 | }
|
---|
132 |
|
---|
133 | int main()
|
---|
134 | {
|
---|
135 | auto vRetVal = RET_SUCCESS;
|
---|
136 |
|
---|
137 | try
|
---|
138 | {
|
---|
139 | gvLoggingInit();
|
---|
140 |
|
---|
141 | auto& vLogger = SLogger::get();
|
---|
142 |
|
---|
143 | LFC1_LOG_TRACE(vLogger) << "A trace severity message";
|
---|
144 | LFC1_LOG_DEBUG(vLogger) << "A debug severity message";
|
---|
145 | LFC1_LOG_INFO(vLogger) << "An informational severity message";
|
---|
146 | LFC1_LOG_WARNING(vLogger) << "A warning severity message";
|
---|
147 | LFC1_LOG_ERROR(vLogger) << "An error severity message";
|
---|
148 | }
|
---|
149 | catch (exception& crException)
|
---|
150 | {
|
---|
151 | cerr << crException.what() << endl;
|
---|
152 | vRetVal = RET_FAIL;
|
---|
153 | }
|
---|
154 | catch (...)
|
---|
155 | {
|
---|
156 | cerr << "Unknown exception" << endl;
|
---|
157 | vRetVal = RET_FAIL;
|
---|
158 | }
|
---|
159 |
|
---|
160 | return vRetVal;
|
---|
161 | }
|
---|