Livox SDK API  V2.2.0
logger_impl.h
Go to the documentation of this file.
1 //
2 // Copyright(c) 2015 Gabi Melman.
3 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
4 //
5 
6 #pragma once
7 
9 
10 #include <memory>
11 #include <string>
12 
13 #define SPDLOG_CATCH_AND_HANDLE \
14  catch (const std::exception &ex) \
15  { \
16  err_handler_(ex.what()); \
17  } \
18  catch (...) \
19  { \
20  err_handler_("Unknown exception in logger"); \
21  }
22 
23 // create logger with given name, sinks and the default pattern formatter
24 // all other ctors will call this one
25 template<typename It>
26 inline spdlog::logger::logger(std::string logger_name, It begin, It end)
27  : name_(std::move(logger_name))
28  , sinks_(begin, end)
29 {
30 }
31 
32 // ctor with sinks as init list
33 inline spdlog::logger::logger(std::string logger_name, sinks_init_list sinks_list)
34  : logger(std::move(logger_name), sinks_list.begin(), sinks_list.end())
35 {
36 }
37 
38 // ctor with single sink
39 inline spdlog::logger::logger(std::string logger_name, spdlog::sink_ptr single_sink)
40  : logger(std::move(logger_name), {std::move(single_sink)})
41 {
42 }
43 
44 inline spdlog::logger::~logger() = default;
45 
46 inline void spdlog::logger::set_formatter(std::unique_ptr<spdlog::formatter> f)
47 {
48  for (auto &sink : sinks_)
49  {
50  sink->set_formatter(f->clone());
51  }
52 }
53 
54 inline void spdlog::logger::set_pattern(std::string pattern, pattern_time_type time_type)
55 {
56  auto new_formatter = details::make_unique<spdlog::pattern_formatter>(std::move(pattern), time_type);
57  set_formatter(std::move(new_formatter));
58 }
59 
60 template<typename... Args>
61 inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const char *fmt, const Args &... args)
62 {
63  if (!should_log(lvl))
64  {
65  return;
66  }
67 
68  try
69  {
72  fmt::format_to(buf, fmt, args...);
73  details::log_msg log_msg(source, &name_, lvl, to_string_view(buf));
74  sink_it_(log_msg);
75  }
77 }
78 
79 template<typename... Args>
80 inline void spdlog::logger::log(level::level_enum lvl, const char *fmt, const Args &... args)
81 {
82  log(source_loc{}, lvl, fmt, args...);
83 }
84 
85 inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const char *msg)
86 {
87  if (!should_log(lvl))
88  {
89  return;
90  }
91 
92  try
93  {
94  details::log_msg log_msg(source, &name_, lvl, spdlog::string_view_t(msg));
95  sink_it_(log_msg);
96  }
98 }
99 
100 inline void spdlog::logger::log(level::level_enum lvl, const char *msg)
101 {
102  log(source_loc{}, lvl, msg);
103 }
104 
105 template<class T>
106 inline void spdlog::logger::log(level::level_enum lvl, const T &msg)
107 {
108  log(source_loc{}, lvl, msg);
109 }
110 
111 template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type *>
112 inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const T &msg)
113 {
114  if (!should_log(lvl))
115  {
116  return;
117  }
118  try
119  {
120  details::log_msg log_msg(source, &name_, lvl, msg);
121  sink_it_(log_msg);
122  }
124 }
125 
126 template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type *>
127 inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const T &msg)
128 {
129  if (!should_log(lvl))
130  {
131  return;
132  }
133  try
134  {
136  fmt::memory_buffer buf;
137  fmt::format_to(buf, "{}", msg);
138  details::log_msg log_msg(source, &name_, lvl, to_string_view(buf));
139  sink_it_(log_msg);
140  }
142 }
143 
144 template<typename... Args>
145 inline void spdlog::logger::trace(const char *fmt, const Args &... args)
146 {
147  log(level::trace, fmt, args...);
148 }
149 
150 template<typename... Args>
151 inline void spdlog::logger::debug(const char *fmt, const Args &... args)
152 {
153  log(level::debug, fmt, args...);
154 }
155 
156 template<typename... Args>
157 inline void spdlog::logger::info(const char *fmt, const Args &... args)
158 {
159  log(level::info, fmt, args...);
160 }
161 
162 template<typename... Args>
163 inline void spdlog::logger::warn(const char *fmt, const Args &... args)
164 {
165  log(level::warn, fmt, args...);
166 }
167 
168 template<typename... Args>
169 inline void spdlog::logger::error(const char *fmt, const Args &... args)
170 {
171  log(level::err, fmt, args...);
172 }
173 
174 template<typename... Args>
175 inline void spdlog::logger::critical(const char *fmt, const Args &... args)
176 {
177  log(level::critical, fmt, args...);
178 }
179 
180 template<typename T>
181 inline void spdlog::logger::trace(const T &msg)
182 {
183  log(level::trace, msg);
184 }
185 
186 template<typename T>
187 inline void spdlog::logger::debug(const T &msg)
188 {
189  log(level::debug, msg);
190 }
191 
192 template<typename T>
193 inline void spdlog::logger::info(const T &msg)
194 {
195  log(level::info, msg);
196 }
197 
198 template<typename T>
199 inline void spdlog::logger::warn(const T &msg)
200 {
201  log(level::warn, msg);
202 }
203 
204 template<typename T>
205 inline void spdlog::logger::error(const T &msg)
206 {
207  log(level::err, msg);
208 }
209 
210 template<typename T>
211 inline void spdlog::logger::critical(const T &msg)
212 {
213  log(level::critical, msg);
214 }
215 
216 #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
217 
218 inline void wbuf_to_utf8buf(const fmt::wmemory_buffer &wbuf, fmt::memory_buffer &target)
219 {
220  int wbuf_size = static_cast<int>(wbuf.size());
221  if (wbuf_size == 0)
222  {
223  return;
224  }
225 
226  auto result_size = ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, NULL, 0, NULL, NULL);
227 
228  if (result_size > 0)
229  {
230  target.resize(result_size);
231  ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, &target.data()[0], result_size, NULL, NULL);
232  }
233  else
234  {
235  throw spdlog::spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()));
236  }
237 }
238 
239 template<typename... Args>
240 inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const wchar_t *fmt, const Args &... args)
241 {
242  if (!should_log(lvl))
243  {
244  return;
245  }
246 
247  try
248  {
249  // format to wmemory_buffer and convert to utf8
251  fmt::wmemory_buffer wbuf;
252  fmt::format_to(wbuf, fmt, args...);
253  fmt::memory_buffer buf;
254  wbuf_to_utf8buf(wbuf, buf);
255  details::log_msg log_msg(source, &name_, lvl, to_string_view(buf));
256  sink_it_(log_msg);
257  }
259 }
260 
261 template<typename... Args>
262 inline void spdlog::logger::log(level::level_enum lvl, const wchar_t *fmt, const Args &... args)
263 {
264  log(source_loc{}, lvl, fmt, args...);
265 }
266 
267 template<typename... Args>
268 inline void spdlog::logger::trace(const wchar_t *fmt, const Args &... args)
269 {
270  log(level::trace, fmt, args...);
271 }
272 
273 template<typename... Args>
274 inline void spdlog::logger::debug(const wchar_t *fmt, const Args &... args)
275 {
276  log(level::debug, fmt, args...);
277 }
278 
279 template<typename... Args>
280 inline void spdlog::logger::info(const wchar_t *fmt, const Args &... args)
281 {
282  log(level::info, fmt, args...);
283 }
284 
285 template<typename... Args>
286 inline void spdlog::logger::warn(const wchar_t *fmt, const Args &... args)
287 {
288  log(level::warn, fmt, args...);
289 }
290 
291 template<typename... Args>
292 inline void spdlog::logger::error(const wchar_t *fmt, const Args &... args)
293 {
294  log(level::err, fmt, args...);
295 }
296 
297 template<typename... Args>
298 inline void spdlog::logger::critical(const wchar_t *fmt, const Args &... args)
299 {
300  log(level::critical, fmt, args...);
301 }
302 
303 #endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
304 
305 //
306 // name and level
307 //
308 inline const std::string &spdlog::logger::name() const
309 {
310  return name_;
311 }
312 
314 {
315  level_.store(log_level);
316 }
317 
319 {
320  err_handler_ = std::move(err_handler);
321 }
322 
324 {
325  return err_handler_;
326 }
327 
329 {
330  try
331  {
332  flush_();
333  }
335 }
336 
338 {
339  flush_level_.store(log_level);
340 }
341 
343 {
344  return static_cast<spdlog::level::level_enum>(flush_level_.load(std::memory_order_relaxed));
345 }
346 
348 {
349  auto flush_level = flush_level_.load(std::memory_order_relaxed);
350  return (msg.level >= flush_level) && (msg.level != level::off);
351 }
352 
354 {
355  return static_cast<spdlog::level::level_enum>(SPDLOG_ACTIVE_LEVEL);
356 }
357 
359 {
360  return static_cast<spdlog::level::level_enum>(level_.load(std::memory_order_relaxed));
361 }
362 
364 {
365  return msg_level >= level_.load(std::memory_order_relaxed);
366 }
367 
368 //
369 // protected virtual called at end of each user log call (if enabled) by the
370 // line_logger
371 //
373 {
374 #if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
375  incr_msg_counter_(msg);
376 #endif
377  for (auto &sink : sinks_)
378  {
379  if (sink->should_log(msg.level))
380  {
381  sink->log(msg);
382  }
383  }
384 
385  if (should_flush_(msg))
386  {
387  flush_();
388  }
389 }
390 
392 {
393  for (auto &sink : sinks_)
394  {
395  sink->flush();
396  }
397 }
398 
399 inline void spdlog::logger::default_err_handler_(const std::string &msg)
400 {
401  auto now = time(nullptr);
402  if (now - last_err_time_ < 60)
403  {
404  return;
405  }
407  auto tm_time = details::os::localtime(now);
408  char date_buf[100];
409  std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
410  fmt::print(stderr, "[*** LOG ERROR ***] [{}] [{}] {}\n", date_buf, name(), msg);
411 }
412 
414 {
415  msg.msg_id = msg_counter_.fetch_add(1, std::memory_order_relaxed);
416 }
417 
418 inline const std::vector<spdlog::sink_ptr> &spdlog::logger::sinks() const
419 {
420  return sinks_;
421 }
422 
423 inline std::vector<spdlog::sink_ptr> &spdlog::logger::sinks()
424 {
425  return sinks_;
426 }
427 
428 inline std::shared_ptr<spdlog::logger> spdlog::logger::clone(std::string logger_name)
429 {
430  auto cloned = std::make_shared<spdlog::logger>(std::move(logger_name), sinks_.begin(), sinks_.end());
431  cloned->set_level(this->level());
432  cloned->flush_on(this->flush_level());
433  cloned->set_error_handler(this->error_handler());
434  return cloned;
435 }
auto begin(const C &c) -> decltype(c.begin())
Definition: format.h:251
level::level_enum flush_level() const
Definition: logger_impl.h:342
std::atomic< time_t > last_err_time_
Definition: logger.h:178
std::enable_if< internal::is_string< String >::value >::type print(std::FILE *f, const text_style &ts, const String &format_str, const Args &...args)
Definition: color.h:549
void incr_msg_counter_(details::log_msg &msg)
Definition: logger_impl.h:413
void error(const char *fmt, const Args &...args)
Definition: logger_impl.h:169
log_err_handler error_handler() const
Definition: logger_impl.h:323
std::initializer_list< sink_ptr > sinks_init_list
Definition: common.h:81
void warn(const char *fmt, const Args &...args)
Definition: logger_impl.h:163
log_err_handler err_handler_
Definition: logger.h:177
spdlog::level_t level_
Definition: logger.h:175
spdlog::log_clock::time_point now() noexcept
Definition: os.h:60
std::atomic< size_t > msg_counter_
Definition: logger.h:179
void log(level::level_enum lvl, const char *fmt, const Args &...args)
Definition: logger_impl.h:80
void info(const char *fmt, const Args &...args)
Definition: logger_impl.h:157
std::tm localtime(const std::time_t &time_tt) noexcept
Definition: os.h:73
#define SPDLOG_CATCH_AND_HANDLE
Definition: logger_impl.h:13
Definition: format.h:297
const std::vector< sink_ptr > & sinks() const
Definition: logger_impl.h:418
std::shared_ptr< sinks::sink > sink_ptr
Definition: common.h:80
const std::string name_
Definition: logger.h:173
std::size_t size() const
Definition: core.h:250
void set_pattern(std::string pattern, pattern_time_type time_type=pattern_time_type::local)
Definition: logger_impl.h:54
static level::level_enum default_level()
Definition: logger_impl.h:353
std::vector< sink_ptr > sinks_
Definition: logger.h:174
bool should_flush_(const details::log_msg &msg)
Definition: logger_impl.h:347
level::level_enum level
Definition: log_msg.h:42
void resize(std::size_t new_size)
Definition: core.h:264
void default_err_handler_(const std::string &msg)
Definition: logger_impl.h:399
pattern_time_type
Definition: common.h:166
virtual ~logger()
void critical(const char *fmt, const Args &...args)
Definition: logger_impl.h:175
virtual std::shared_ptr< logger > clone(std::string logger_name)
Definition: logger_impl.h:428
std::basic_string< typename char_t< S >::type > format(const S &format_str, const Args &...args)
Definition: core.h:1454
void debug(const char *fmt, const Args &...args)
Definition: logger_impl.h:151
bool should_log(level::level_enum msg_level) const
Definition: logger_impl.h:363
spdlog::level_t flush_level_
Definition: logger.h:176
string_view_t & to_string_view(spdlog::level::level_enum l) noexcept
Definition: common.h:135
level::level_enum level() const
Definition: logger_impl.h:358
void set_formatter(std::unique_ptr< formatter > formatter)
Definition: logger_impl.h:46
void trace(const char *fmt, const Args &...args)
Definition: logger_impl.h:145
virtual void flush_()
Definition: logger_impl.h:391
std::enable_if< is_contiguous< Container >::value &&internal::is_string< S >::value, std::back_insert_iterator< Container > >::type format_to(std::back_insert_iterator< Container > out, const S &format_str, const Args &...args)
Definition: core.h:1430
Definition: bin_to_hex.h:69
void set_error_handler(log_err_handler err_handler)
Definition: logger_impl.h:318
const std::string & name() const
Definition: logger_impl.h:308
spdlog::string_view_t to_string_view(const fmt::basic_memory_buffer< char, Buffer_Size > &buf) SPDLOG_NOEXCEPT
Definition: fmt_helper.h:17
std::size_t strftime(char *str, std::size_t count, const char *format, const std::tm *time)
Definition: time.h:104
std::function< void(const std::string &err_msg)> log_err_handler
Definition: common.h:82
logger(std::string name, sink_ptr single_sink)
Definition: logger_impl.h:39
#define SPDLOG_ACTIVE_LEVEL
Definition: common.h:106
auto end(const C &c) -> decltype(c.end())
Definition: format.h:257
void set_level(level::level_enum log_level)
Definition: logger_impl.h:313
void flush_on(level::level_enum log_level)
Definition: logger_impl.h:337
virtual void sink_it_(details::log_msg &msg)
Definition: logger_impl.h:372