dmplogger.cpp
6.0 KB
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/**************************************************************************
* file: dmplogger.cpp
* Author: wanzhongping
* Date: 2021-03-03 10:29:10
* Email: zhongpingw@chinadci.com
* copyright: 广州城市信息研究所有限公司
***************************************************************************/
#include "dmplogger.h"
#include <iostream>
#include <fstream>
#include <boost/core/ref.hpp>
#include <boost/bind/bind.hpp>
#include <boost/log/common.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/attributes/timer.hpp>
#include <boost/log/attributes/named_scope.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/from_stream.hpp>
#include <boost/log/utility/setup/filter_parser.hpp>
#include <boost/log/utility/setup/formatter_parser.hpp>
#include <boost/format.hpp>
#include "dmpapplication.h"
namespace logging = boost::log;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace sinks = boost::log::sinks;
namespace keywords = boost::log::keywords;
namespace attrs = boost::log::attributes;
static src::severity_logger< SeverityLevel > slg;
// static std::string sConfigName = DmpApplication::Instance()->libexecPath() + "log.config";
//static std::string sConfigName = "/usr/local/lib/dmap/log.config";
//! Formatting operator for severity levels
std::ostream& operator<< (std::ostream& strm, SeverityLevel level)
{
static const char* const str[] =
{
"debug",
"info",
"warning",
"error",
"critical"
};
if (static_cast< std::size_t >(level) < (sizeof(str) / sizeof(*str)))
strm << str[level];
else
strm << static_cast< int >(level);
return strm;
}
//! Parsing operator for severity levels
std::istream& operator>> (std::istream& strm, SeverityLevel& level)
{
if (strm.good())
{
std::string str;
strm >> str;
if (str == "debug")
level = debug_level;
else if (str == "info")
level = info_level;
else if (str == "warning")
level = warn_level;
else if (str == "error")
level = error_level;
else if (str == "critical")
level = critical_level;
else
strm.setstate(std::ios_base::failbit);
}
return strm;
}
//! Our custom formatter for the scope list
struct scope_list_formatter
{
typedef void result_type;
typedef attrs::named_scope::value_type scope_stack;
explicit scope_list_formatter(logging::attribute_name const& name) :
name_(name)
{
}
void operator()(logging::record_view const& rec, logging::formatting_ostream& strm) const
{
// We need to acquire the attribute value from the log record
logging::visit< scope_stack >
(
name_,
rec.attribute_values(),
boost::bind(&scope_list_formatter::format, boost::placeholders::_1, boost::ref(strm))
);
}
private:
//! This is where our custom formatting takes place
static void format(scope_stack const& scopes, logging::formatting_ostream& strm)
{
scope_stack::const_iterator it = scopes.begin(), end = scopes.end();
for (; it != end; ++it)
{
strm << it->scope_name << " (" << it->file_name << ":" << it->line << ")";
}
}
private:
logging::attribute_name name_;
};
class my_scopes_formatter_factory : public logging::formatter_factory< char >
{
public:
/*!
* This function creates a formatter for the MyScopes attribute.
* It effectively associates the attribute with the scope_list_formatter class
*/
formatter_type create_formatter(logging::attribute_name const& attr_name, args_map const& args)
{
return formatter_type(scope_list_formatter(attr_name));
}
};
DmpLogger::DmpLogger()
{
// Init();
}
DmpLogger::~DmpLogger()
{
}
void DmpLogger::Init(const std::string &path)
{
// First thing - register the custom formatter for MyScopes
logging::register_formatter_factory("Scope", boost::make_shared< my_scopes_formatter_factory >());
// Also register filter and formatter factories for our custom severity level enum. Since our operator<< and operator>> implement
// all required behavior, simple factories provided by Boost.Log will do.
logging::register_simple_filter_factory< SeverityLevel >("Severity");
logging::register_simple_formatter_factory< SeverityLevel, char >("Severity");
// Open the setting file
std::ifstream settings(path);
boost::format fmt = boost::format("Could not open %s file!") % path;
if (!settings.is_open())
// throw std::runtime_error("Could not open log.config file!");
throw std::runtime_error(fmt.str());
logging::init_from_stream(settings);
// Also let's add some commonly used attributes, like timestamp and record counter.
logging::add_common_attributes();
logging::core::get()->add_thread_attribute("Scope", attrs::named_scope());
slg.add_attribute("Uptime", attrs::timer());
}
void DmpLogger::Debug(const std::string &msg)
{
BOOST_LOG_SEV(slg, debug_level) << msg;
}
void DmpLogger::Info(const std::string &msg)
{
BOOST_LOG_SEV(slg, info_level) << msg;
}
void DmpLogger::Warn(const std::string &msg)
{
BOOST_LOG_SEV(slg, warn_level) << msg;
}
void DmpLogger::Error(const std::string &msg)
{
BOOST_LOG_SEV(slg, error_level) << msg;
}
void DmpLogger::Critical(const std::string &msg)
{
BOOST_LOG_SEV(slg, critical_level) << msg;
}
void DmpLogger::SetLevel(SeverityLevel level)
{
logging::core::get()->set_filter(expr::attr< SeverityLevel >("Severity") >= level);
}
DmpLogger *DmpLogger::Instance()
{
static DmpLogger logger;
return &logger;
}