rtop
rtop_logger.h
Go to the documentation of this file.
1 /*
2  * Copyright Andrey Semashev 2007 - 2015.
3  * Distributed under the Boost Software License, Version 1.0.
4  * (See accompanying file LICENSE_1_0.txt or copy at
5  * http://www.boost.org/LICENSE_1_0.txt)
6  */
7 
8 #include <string>
9 #include <map>
10 #include <fstream>
11 #include <thread>
12 #include <mutex>
13 #include <boost/log/core.hpp>
14 #include <boost/log/trivial.hpp>
15 #include <boost/log/expressions.hpp>
16 #include <boost/log/sinks/text_file_backend.hpp>
17 #include <boost/log/utility/setup/file.hpp>
18 #include <boost/log/utility/setup/common_attributes.hpp>
19 #include <boost/log/sources/severity_logger.hpp>
20 #include <boost/log/sources/record_ostream.hpp>
21 #include <boost/log/attributes/attribute.hpp>
22 #include <boost/log/attributes/attribute.hpp>
23 #include <boost/log/attributes/attribute_cast.hpp>
24 #include <boost/log/attributes/attribute_value.hpp>
25 #include <boost/lambda/lambda.hpp>
26 #include <boost/date_time/posix_time/posix_time.hpp>
27 #include <boost/log/common.hpp>
28 #include <boost/log/expressions.hpp>
29 #include <boost/date_time/posix_time/posix_time_types.hpp>
30 #include <boost/log/support/date_time.hpp>
31 
32 #ifndef _LOGGER_H_
33 #define _LOGGER_H_
34 namespace logging = boost::log;
35 namespace src = boost::log::sources;
36 namespace sinks = boost::log::sinks;
37 namespace keywords = boost::log::keywords;
38 namespace attrs = boost::log::attributes;
39 namespace expr = boost::log::expressions;
40 
42 void init_logging(std::string sev_level)
43 {
44  // set log filtering level, fatal > error > warning > info > debug
45  boost::shared_ptr< logging::core > core = logging::core::get();
46  if (sev_level == "debug")
47  {
48  core->set_filter
49  (
50  logging::trivial::severity >= logging::trivial::debug
51  );
52  }
53  if (sev_level == "info")
54  {
55  core->set_filter
56  (
57  logging::trivial::severity >= logging::trivial::info
58  );
59  }
60  if (sev_level == "warning")
61  {
62  core->set_filter
63  (
64  logging::trivial::severity >= logging::trivial::warning
65  );
66  }
67  if (sev_level == "error")
68  {
69  core->set_filter
70  (
71  logging::trivial::severity >= logging::trivial::error
72  );
73  }
74  if (sev_level == "fatal")
75  {
76  core->set_filter
77  (
78  logging::trivial::severity >= logging::trivial::fatal
79  );
80  }
81 
82  // set up sink as text file
83  boost::shared_ptr< sinks::text_file_backend > backend =
84  boost::make_shared< sinks::text_file_backend >(
85  keywords::file_name = "sample_%5N.log",
86  keywords::rotation_size = 5 * 1024 * 1024,
87  keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0)
88  );
89 
90 
91  backend->auto_flush(true); // flushes buffers of attached streams after each log record is written
92 
93  typedef sinks::synchronous_sink<sinks::text_file_backend> sink_t;
94  boost::shared_ptr<sink_t> sink(new sink_t(backend));
95 
96  // set up format for message, data(min:sec.frac) [thread_id] message
97  logging::formatter formatter = expr::stream
98  <<expr::format_date_time<boost::posix_time::ptime >("TimeStamp", "%-%M:%S.%f")
99  <<" ["<<logging::expressions::attr<logging::attributes::current_thread_id::value_type>("ThreadID")<<"]:"
100  <<expr::message;
101  sink->set_formatter(formatter);
102  core->add_sink(sink);
103  logging::add_common_attributes();
104 }
105 
106 
107 using namespace logging::trivial;
108 src::severity_logger< severity_level > lg;
109 
111 
119 {
120  private:
121  std::mutex lgmutex;
122  std::map<std::thread::id, std::string> spacers;
123  public:
124  void addSpace();
125  void delSpace();
126  std::string spacer();
127  friend std::ostream& operator<<(std::ostream& ofs, logSpacer& lgSpacer);
128 };
129 
131 
136 {
137  //std::lock_guard<std::mutex> lg1(lgmutex); // acquire mutex, released when lg1 goes out of scope
138  // Critical Section Starts //
139  std::thread::id t_id = std::this_thread::get_id();
140  if (spacers.find(t_id) == spacers.end())
141  spacers[t_id] = "";
142  spacers[t_id] += " ";
143  // Critical Section Ends //
144 }
145 
147 
152 {
153  // std::lock_guard<std::mutex> lg1(lgmutex); // acquire mutex, released when lg1 goes out of scope
154  // Critical Section Starts //
155  std::thread::id t_id = std::this_thread::get_id();
156  if (spacers.find(t_id) == spacers.end())
157  return;
158  if (spacers[t_id].empty())
159  return;
160  spacers[t_id].erase(0,2);
161  // Critical Section Ends //
162 }
163 
165 std::string logSpacer::spacer()
166 {
167 
168  std::thread::id t_id = std::this_thread::get_id();
169  if (spacers.find(t_id) == spacers.end())
170  return "";
171  return spacers[t_id];
172 }
173 
175 
179 std::ostream& operator<<(std::ostream& ofs, logSpacer& lgSpacer)
180 {
181  std::lock_guard<std::mutex> lg1(lgSpacer.lgmutex);
182  ofs<<lgSpacer.spacer();
183  return ofs;
184 }
185 
187 #endif
std::string spacer()
returns white-space string corresponding to invoking thread
Definition: rtop_logger.h:165
void init_logging(std::string sev_level)
sets up logging using Boost.Log library
Definition: rtop_logger.h:42
logSpacer log_spacer
Definition: rtop_logger.h:186
void delSpace()
deletes one white-space from white-space string corresponding to invoking thread
Definition: rtop_logger.h:151
std::mutex lgmutex
Definition: rtop_logger.h:121
void addSpace()
adds one white-space to white-space string corresponding to invoking thread
Definition: rtop_logger.h:135
std::map< std::thread::id, std::string > spacers
Definition: rtop_logger.h:122
src::severity_logger< severity_level > lg
Definition: rtop_logger.h:108
std::ostream & operator<<(std::ostream &ofs, logSpacer &lgSpacer)
pushes white-space string corresponding to invoking thread to std::ostream
Definition: rtop_logger.h:179
enables indentation of logs for easy viewing
Definition: rtop_logger.h:118