bitz-server  2.0.1
logger_impl.h
1 //
2 // Copyright(c) 2015 Gabi Melman.
3 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
4 //
5 
6 #pragma once
7 
8 #include "../logger.h"
9 
10 #include <memory>
11 #include <string>
12 
13 // create logger with given name, sinks and the default pattern formatter
14 // all other ctors will call this one
15 template<class It>
16 inline spdlog::logger::logger(std::string logger_name, const It &begin, const It &end)
17  : _name(std::move(logger_name))
18  , _sinks(begin, end)
19  , _formatter(std::make_shared<pattern_formatter>("%+"))
20  , _level(level::info)
21  , _flush_level(level::off)
22  , _last_err_time(0)
23  , _msg_counter(1) // message counter will start from 1. 0-message id will be reserved for controll messages
24 {
25  _err_handler = [this](const std::string &msg) { this->_default_err_handler(msg); };
26 }
27 
28 // ctor with sinks as init list
29 inline spdlog::logger::logger(const std::string &logger_name, sinks_init_list sinks_list)
30  : logger(logger_name, sinks_list.begin(), sinks_list.end())
31 {
32 }
33 
34 // ctor with single sink
35 inline spdlog::logger::logger(const std::string &logger_name, spdlog::sink_ptr single_sink)
36  : logger(logger_name, {std::move(single_sink)})
37 {
38 }
39 
40 inline spdlog::logger::~logger() = default;
41 
42 inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter)
43 {
44  _set_formatter(std::move(msg_formatter));
45 }
46 
47 inline void spdlog::logger::set_pattern(const std::string &pattern, pattern_time_type pattern_time)
48 {
49  _set_pattern(pattern, pattern_time);
50 }
51 
52 template<typename... Args>
53 inline void spdlog::logger::log(level::level_enum lvl, const char *fmt, const Args &... args)
54 {
55  if (!should_log(lvl))
56  {
57  return;
58  }
59 
60  try
61  {
62  details::log_msg log_msg(&_name, lvl);
63 
64 #if defined(SPDLOG_FMT_PRINTF)
65  fmt::printf(log_msg.raw, fmt, args...);
66 #else
67  log_msg.raw.write(fmt, args...);
68 #endif
69  _sink_it(log_msg);
70  }
71  SPDLOG_CATCH_AND_HANDLE
72 }
73 
74 template<typename... Args>
75 inline void spdlog::logger::log(level::level_enum lvl, const char *msg)
76 {
77  if (!should_log(lvl))
78  {
79  return;
80  }
81  try
82  {
83  details::log_msg log_msg(&_name, lvl);
84  log_msg.raw << msg;
85  _sink_it(log_msg);
86  }
87  SPDLOG_CATCH_AND_HANDLE
88 }
89 
90 template<typename T>
91 inline void spdlog::logger::log(level::level_enum lvl, const T &msg)
92 {
93  if (!should_log(lvl))
94  {
95  return;
96  }
97  try
98  {
99  details::log_msg log_msg(&_name, lvl);
100  log_msg.raw << msg;
101  _sink_it(log_msg);
102  }
103  SPDLOG_CATCH_AND_HANDLE
104 }
105 
106 template<typename Arg1, typename... Args>
107 inline void spdlog::logger::trace(const char *fmt, const Arg1 &arg1, const Args &... args)
108 {
109  log(level::trace, fmt, arg1, args...);
110 }
111 
112 template<typename Arg1, typename... Args>
113 inline void spdlog::logger::debug(const char *fmt, const Arg1 &arg1, const Args &... args)
114 {
115  log(level::debug, fmt, arg1, args...);
116 }
117 
118 template<typename Arg1, typename... Args>
119 inline void spdlog::logger::info(const char *fmt, const Arg1 &arg1, const Args &... args)
120 {
121  log(level::info, fmt, arg1, args...);
122 }
123 
124 template<typename Arg1, typename... Args>
125 inline void spdlog::logger::warn(const char *fmt, const Arg1 &arg1, const Args &... args)
126 {
127  log(level::warn, fmt, arg1, args...);
128 }
129 
130 template<typename Arg1, typename... Args>
131 inline void spdlog::logger::error(const char *fmt, const Arg1 &arg1, const Args &... args)
132 {
133  log(level::err, fmt, arg1, args...);
134 }
135 
136 template<typename Arg1, typename... Args>
137 inline void spdlog::logger::critical(const char *fmt, const Arg1 &arg1, const Args &... args)
138 {
139  log(level::critical, fmt, arg1, args...);
140 }
141 
142 template<typename T>
143 inline void spdlog::logger::trace(const T &msg)
144 {
145  log(level::trace, msg);
146 }
147 
148 template<typename T>
149 inline void spdlog::logger::debug(const T &msg)
150 {
151  log(level::debug, msg);
152 }
153 
154 template<typename T>
155 inline void spdlog::logger::info(const T &msg)
156 {
157  log(level::info, msg);
158 }
159 
160 template<typename T>
161 inline void spdlog::logger::warn(const T &msg)
162 {
163  log(level::warn, msg);
164 }
165 
166 template<typename T>
167 inline void spdlog::logger::error(const T &msg)
168 {
169  log(level::err, msg);
170 }
171 
172 template<typename T>
173 inline void spdlog::logger::critical(const T &msg)
174 {
175  log(level::critical, msg);
176 }
177 
178 #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
179 #include <codecvt>
180 #include <locale>
181 
182 template<typename... Args>
183 inline void spdlog::logger::log(level::level_enum lvl, const wchar_t *msg)
184 {
185  std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
186 
187  log(lvl, conv.to_bytes(msg));
188 }
189 
190 template<typename... Args>
191 inline void spdlog::logger::log(level::level_enum lvl, const wchar_t *fmt, const Args &... args)
192 {
193  fmt::WMemoryWriter wWriter;
194 
195  wWriter.write(fmt, args...);
196  log(lvl, wWriter.c_str());
197 }
198 
199 template<typename... Args>
200 inline void spdlog::logger::trace(const wchar_t *fmt, const Args &... args)
201 {
202  log(level::trace, fmt, args...);
203 }
204 
205 template<typename... Args>
206 inline void spdlog::logger::debug(const wchar_t *fmt, const Args &... args)
207 {
208  log(level::debug, fmt, args...);
209 }
210 
211 template<typename... Args>
212 inline void spdlog::logger::info(const wchar_t *fmt, const Args &... args)
213 {
214  log(level::info, fmt, args...);
215 }
216 
217 template<typename... Args>
218 inline void spdlog::logger::warn(const wchar_t *fmt, const Args &... args)
219 {
220  log(level::warn, fmt, args...);
221 }
222 
223 template<typename... Args>
224 inline void spdlog::logger::error(const wchar_t *fmt, const Args &... args)
225 {
226  log(level::err, fmt, args...);
227 }
228 
229 template<typename... Args>
230 inline void spdlog::logger::critical(const wchar_t *fmt, const Args &... args)
231 {
232  log(level::critical, fmt, args...);
233 }
234 
235 #endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
236 
237 //
238 // name and level
239 //
240 inline const std::string &spdlog::logger::name() const
241 {
242  return _name;
243 }
244 
245 inline void spdlog::logger::set_level(spdlog::level::level_enum log_level)
246 {
247  _level.store(log_level);
248 }
249 
250 inline void spdlog::logger::set_error_handler(spdlog::log_err_handler err_handler)
251 {
252  _err_handler = std::move(err_handler);
253 }
254 
255 inline spdlog::log_err_handler spdlog::logger::error_handler()
256 {
257  return _err_handler;
258 }
259 
260 inline void spdlog::logger::flush_on(level::level_enum log_level)
261 {
262  _flush_level.store(log_level);
263 }
264 
265 inline spdlog::level::level_enum spdlog::logger::level() const
266 {
267  return static_cast<spdlog::level::level_enum>(_level.load(std::memory_order_relaxed));
268 }
269 
270 inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) const
271 {
272  return msg_level >= _level.load(std::memory_order_relaxed);
273 }
274 
275 //
276 // protected virtual called at end of each user log call (if enabled) by the line_logger
277 //
278 inline void spdlog::logger::_sink_it(details::log_msg &msg)
279 {
280 #if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
281  _incr_msg_counter(msg);
282 #endif
283  _formatter->format(msg);
284  for (auto &sink : _sinks)
285  {
286  if (sink->should_log(msg.level))
287  {
288  sink->log(msg);
289  }
290  }
291 
292  if (_should_flush_on(msg))
293  {
294  flush();
295  }
296 }
297 
298 inline void spdlog::logger::_set_pattern(const std::string &pattern, pattern_time_type pattern_time)
299 {
300  _formatter = std::make_shared<pattern_formatter>(pattern, pattern_time);
301 }
302 
303 inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter)
304 {
305  _formatter = std::move(msg_formatter);
306 }
307 
308 inline void spdlog::logger::flush()
309 {
310  try
311  {
312  for (auto &sink : _sinks)
313  {
314  sink->flush();
315  }
316  }
317  SPDLOG_CATCH_AND_HANDLE
318 }
319 
320 inline void spdlog::logger::_default_err_handler(const std::string &msg)
321 {
322  auto now = time(nullptr);
323  if (now - _last_err_time < 60)
324  {
325  return;
326  }
327  _last_err_time = now;
328  auto tm_time = details::os::localtime(now);
329  char date_buf[100];
330  std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
331  fmt::print(stderr, "[*** LOG ERROR ***] [{}] [{}] {}\n", date_buf, name(), msg);
332 }
333 
334 inline bool spdlog::logger::_should_flush_on(const details::log_msg &msg)
335 {
336  const auto flush_level = _flush_level.load(std::memory_order_relaxed);
337  return (msg.level >= flush_level) && (msg.level != level::off);
338 }
339 
340 inline void spdlog::logger::_incr_msg_counter(details::log_msg &msg)
341 {
342  msg.msg_id = _msg_counter.fetch_add(1, std::memory_order_relaxed);
343 }
344 
345 inline const std::vector<spdlog::sink_ptr> &spdlog::logger::sinks() const
346 {
347  return _sinks;
348 }
const Char * c_str() const
Definition: format.h:3289
Definition: format.h:448
void write(BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3332
Definition: format.h:3924
Definition: format.cc:84