TCPSPSuite
log.hpp
1 #ifndef LOG_H
2 #define LOG_H
3 
4 #define BOOST_LOG_DYN_LINK 1
5 
6 #include "generated_config.hpp"
7 
8 #include <cassert>
9 #include <ctime>
10 #include <fstream>
11 #include <functional>
12 #include <iostream>
13 #include <locale>
14 #include <mutex>
15 #include <ostream>
16 #include <set>
17 #include <shared_mutex>
18 #include <sstream>
19 #include <stdio.h>
20 #include <string.h>
21 #include <thread>
22 #include <utility>
23 #include <vector>
24 
25 #include <boost/log/attributes/current_thread_id.hpp>
26 #include <boost/log/sources/severity_logger.hpp>
27 #include <boost/log/sources/record_ostream.hpp>
28 #include <boost/date_time.hpp>
29 
30 // red
31 #define COLOR_ERROR "\033[31m"
32 // yellow
33 #define COLOR_WARNING "\033[33m"
34 // green
35 #define COLOR_INFO "\033[32m"
36 // cyan
37 #define COLOR_DEBUG "\033[36m"
38 
39 // Outputting tuples
40 template <class _CharT, class _Traits, typename Type, size_t N, size_t Last>
41 struct tuple_printer
42 {
43  static void
44  print(std::basic_ostream<_CharT, _Traits> & out, const Type & value) noexcept
45  {
46  out << std::get<N>(value) << ", ";
47  tuple_printer<_CharT, _Traits, Type, N + 1, Last>::print(out, value);
48  }
49 };
50 
51 template <class _CharT, class _Traits, typename Type, size_t N>
52 struct tuple_printer<_CharT, _Traits, Type, N, N>
53 {
54  static void
55  print(std::basic_ostream<_CharT, _Traits> & out, const Type & value) noexcept
56  {
57  out << std::get<N>(value);
58  }
59 };
60 
61 template <class _CharT, class _Traits, typename... Types>
62 std::basic_ostream<_CharT, _Traits> &
63 operator<<(std::basic_ostream<_CharT, _Traits> & out,
64  const std::tuple<Types...> & value) noexcept
65 {
66  out << "{ ";
67  tuple_printer<_CharT, _Traits, std::tuple<Types...>, 0,
68  sizeof...(Types) - 1>::print(out, value);
69  out << " }";
70  return out;
71 }
72 
73 template <class T, class _CharT, class _Traits>
74 std::basic_ostream<_CharT, _Traits> &
75 operator<<(std::basic_ostream<_CharT, _Traits> & os,
76  const std::set<T> & set) noexcept
77 {
78  os << "{ ";
79  bool first = true;
80  for (auto el : set) {
81  if (!first) {
82  os << ", ";
83  }
84 
85  os << el;
86 
87  first = false;
88  }
89  os << " }";
90 
91  return os;
92 }
93 
94 template <class T1, class T2, class _CharT, class _Traits>
95 std::basic_ostream<_CharT, _Traits> &
96 operator<<(std::basic_ostream<_CharT, _Traits> & os,
97  const std::pair<T1, T2> & pair) noexcept
98 {
99  os << "{ ";
100  os << pair.first << ", " << pair.second;
101  os << " }";
102  return os;
103 }
104 
105 template <class T, class _CharT, class _Traits>
106 std::basic_ostream<_CharT, _Traits> &
107 operator<<(std::basic_ostream<_CharT, _Traits> & os, const std::vector<T> & v) noexcept
108 {
109  os << "< ";
110  bool first = true;
111  for (const auto & el : v) {
112  if (!first) {
113  os << ", ";
114  }
115 
116  os << el;
117 
118  first = false;
119  }
120  os << " >";
121 
122  return os;
123 }
124 
125 class Log {
126 public:
127  enum class severity
128  {
129  debug,
130  info,
131  normal,
132  warning,
133  error,
134  fatal
135  };
136 
137 private:
138  // Map thread IDs to small numbers
139  static std::map<boost::log::attributes::current_thread_id::value_type,
140  unsigned int>
141  thread_id_map;
142  static std::shared_timed_mutex thread_id_map_mutex;
143 
144  static std::locale get_locale() noexcept;
145 
146  static void
147  coloring_formatter(boost::log::record_view const & rec,
148  boost::log::formatting_ostream & strm) noexcept;
149 
150 public:
151  static void setup() noexcept;
152 
153  Log(std::string component) noexcept;
154 
155  boost::log::sources::severity_logger<severity> &
156  d(unsigned int level = 0) const noexcept;
157 
158  boost::log::sources::severity_logger<severity> & i() const noexcept;
159 
160  boost::log::sources::severity_logger<severity> & n() const noexcept;
161 
162  boost::log::sources::severity_logger<severity> & w() const noexcept;
163 
164  boost::log::sources::severity_logger<severity> & e() const noexcept;
165 
166  boost::log::sources::severity_logger<severity> & f() const noexcept;
167 
168 private:
169  // TODO check if this impacts performance!
170  boost::log::sources::severity_logger<severity> filtered_logger;
171 
172  std::array<boost::log::sources::severity_logger<severity>, MAX_DBG_LEVEL>
173  d_logger;
174  boost::log::sources::severity_logger<severity> i_logger;
175  boost::log::sources::severity_logger<severity> n_logger;
176  boost::log::sources::severity_logger<severity> w_logger;
177  boost::log::sources::severity_logger<severity> e_logger;
178  boost::log::sources::severity_logger<severity> f_logger;
179 };
180 
181 #endif