CodeCompass
146 строк · 3.6 Кб
1#include <util/logutil.h>
2
3#include <boost/filesystem.hpp>
4#include <boost/log/utility/setup.hpp>
5#include <boost/log/expressions.hpp>
6#include <boost/log/attributes.hpp>
7#include <boost/date_time/posix_time/posix_time.hpp>
8
9namespace fs = boost::filesystem;
10
11namespace cc
12{
13namespace util
14{
15
16namespace
17{
18
19BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime)
20
21std::string getFormattedTime(boost::posix_time::ptime ptime_)
22{
23std::stringstream stream;
24boost::posix_time::time_facet* facet = new boost::posix_time::time_facet();
25facet->format("%Y-%m-%d %H:%M:%S");
26stream.imbue(std::locale(std::locale::classic(), facet));
27
28stream << ptime_;
29
30return stream.str();
31}
32
33void consoleLogFormatter(
34const boost::log::record_view& rec, boost::log::formatting_ostream& strm)
35{
36auto severity = rec[boost::log::trivial::severity];
37
38if (severity)
39{
40// Set the color
41switch (severity.get())
42{
43case boost::log::trivial::debug:
44strm << "\033[32m";
45break;
46case boost::log::trivial::warning:
47strm << "\033[33m";
48break;
49case boost::log::trivial::error:
50case boost::log::trivial::fatal:
51strm << "\033[31m";
52break;
53default:
54break;
55}
56}
57
58std::string sLevel = boost::log::trivial::to_string(severity.get());
59std::transform(sLevel.begin(), sLevel.end(), sLevel.begin(), ::toupper);
60
61std::string timeString = getFormattedTime(rec[timestamp].get());
62
63strm << timeString << " [" << sLevel << "] " << rec[boost::log::expressions::smessage];
64
65// Restore the default color
66if (severity)
67{
68strm << "\033[0m";
69}
70}
71
72void fileLogFormatter(
73const boost::log::record_view& rec, boost::log::formatting_ostream& strm)
74{
75auto severity = rec[boost::log::trivial::severity];
76
77std::string sLevel = boost::log::trivial::to_string(severity.get());
78std::transform(sLevel.begin(), sLevel.end(), sLevel.begin(), ::toupper);
79
80std::string timeString = getFormattedTime(rec[timestamp].get());
81
82strm << timeString << " [" << sLevel << "] " << rec[boost::log::expressions::smessage];
83}
84
85} // namespace
86
87boost::log::trivial::severity_level getSeverityLevel()
88{
89return boost::log::attribute_cast<
90boost::log::attributes::mutable_constant<boost::log::trivial::severity_level>>(
91boost::log::core::get()->get_global_attributes()["Severity"]).get();
92}
93
94void initConsoleLogger()
95{
96boost::log::add_common_attributes();
97auto fsSink = boost::log::add_console_log(
98std::cout,
99boost::log::keywords::auto_flush = true);
100
101fsSink->set_formatter(&consoleLogFormatter);
102}
103
104std::string getLoggingBase(const std::string& path_, const std::string& name_)
105{
106if (path_.find('~') != std::string::npos)
107{
108throw std::invalid_argument("The path should not contain a \'~\' character. \
109Please provide an absolute path");
110}
111
112boost::system::error_code ec;
113fs::create_directory(path_, ec);
114if (ec)
115{
116throw std::invalid_argument("Permission denied to create " + path_);
117}
118
119const std::string fullpath = canonical(absolute(fs::path(path_))).string();
120
121return fullpath + (fullpath.back() == '/' ? "" : "/") + name_ + '_';
122}
123
124bool initFileLogger(const std::string& path_)
125{
126auto fsSink = boost::log::add_file_log(
127boost::log::keywords::file_name = path_,
128boost::log::keywords::auto_flush = true
129);
130fsSink->set_formatter(&fileLogFormatter);
131try
132{
133// check if logging to file is possible
134LOG(info) << "Start logging in file: " << path_;
135}
136catch(...)
137{
138boost::log::core::get()->remove_sink(fsSink);
139LOG(warning) << "Could not open file for logging: " << path_;
140return false;
141}
142return true;
143}
144
145} // util
146} // cc
147
148
149
150