Agora  1.2.0
Agora project
logger.h
Go to the documentation of this file.
1 // Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
2 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
3 
4 #pragma once
5 
6 // Thread safe logger (except for set_error_handler())
7 // Has name, log level, vector of std::shared sink pointers and formatter
8 // Upon each log write the logger:
9 // 1. Checks if its log level is enough to log the message and if yes:
10 // 2. Call the underlying sinks to do the job.
11 // 3. Each sink use its own private copy of a formatter to format the message
12 // and send to its destination.
13 //
14 // The use of private formatter per sink provides the opportunity to cache some
15 // formatted data, and support for different format per sink.
16 
17 #include <spdlog/common.h>
18 #include <spdlog/details/log_msg.h>
20 
21 #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
22 # ifndef _WIN32
23 # error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows
24 # endif
25 # include <spdlog/details/os.h>
26 #endif
27 
28 #include <vector>
29 
30 #ifndef SPDLOG_NO_EXCEPTIONS
31 # define SPDLOG_LOGGER_CATCH(location) \
32  catch (const std::exception &ex) \
33  { \
34  if (location.filename) \
35  { \
36  err_handler_(fmt_lib::format("{} [{}({})]", ex.what(), location.filename, location.line)); \
37  } \
38  else \
39  { \
40  err_handler_(ex.what()); \
41  } \
42  } \
43  catch (...) \
44  { \
45  err_handler_("Rethrowing unknown exception in logger"); \
46  throw; \
47  }
48 #else
49 # define SPDLOG_LOGGER_CATCH(location)
50 #endif
51 
52 namespace spdlog {
53 
55 {
56 public:
57  // Empty logger
58  explicit logger(std::string name)
59  : name_(std::move(name))
60  , sinks_()
61  {}
62 
63  // Logger with range on sinks
64  template<typename It>
65  logger(std::string name, It begin, It end)
66  : name_(std::move(name))
67  , sinks_(begin, end)
68  {}
69 
70  // Logger with single sink
71  logger(std::string name, sink_ptr single_sink)
72  : logger(std::move(name), {std::move(single_sink)})
73  {}
74 
75  // Logger with sinks init list
76  logger(std::string name, sinks_init_list sinks)
77  : logger(std::move(name), sinks.begin(), sinks.end())
78  {}
79 
80  virtual ~logger() = default;
81 
82  logger(const logger &other);
83  logger(logger &&other) SPDLOG_NOEXCEPT;
84  logger &operator=(logger other) SPDLOG_NOEXCEPT;
85  void swap(spdlog::logger &other) SPDLOG_NOEXCEPT;
86 
87  template<typename... Args>
88  void log(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&... args)
89  {
90  log_(loc, lvl, fmt, std::forward<Args>(args)...);
91  }
92 
93  template<typename... Args>
94  void log(level::level_enum lvl, format_string_t<Args...> fmt, Args &&... args)
95  {
96  log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
97  }
98 
99  template<typename T>
100  void log(level::level_enum lvl, const T &msg)
101  {
102  log(source_loc{}, lvl, msg);
103  }
104 
105  // T cannot be statically converted to format string (including string_view/wstring_view)
107  void log(source_loc loc, level::level_enum lvl, const T &msg)
108  {
109  log(loc, lvl, "{}", msg);
110  }
111 
112  void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg)
113  {
114  bool log_enabled = should_log(lvl);
115  bool traceback_enabled = tracer_.enabled();
116  if (!log_enabled && !traceback_enabled)
117  {
118  return;
119  }
120 
121  details::log_msg log_msg(log_time, loc, name_, lvl, msg);
122  log_it_(log_msg, log_enabled, traceback_enabled);
123  }
124 
126  {
127  bool log_enabled = should_log(lvl);
128  bool traceback_enabled = tracer_.enabled();
129  if (!log_enabled && !traceback_enabled)
130  {
131  return;
132  }
133 
134  details::log_msg log_msg(loc, name_, lvl, msg);
135  log_it_(log_msg, log_enabled, traceback_enabled);
136  }
137 
139  {
140  log(source_loc{}, lvl, msg);
141  }
142 
143  template<typename... Args>
144  void trace(format_string_t<Args...> fmt, Args &&... args)
145  {
146  log(level::trace, fmt, std::forward<Args>(args)...);
147  }
148 
149  template<typename... Args>
150  void debug(format_string_t<Args...> fmt, Args &&... args)
151  {
152  log(level::debug, fmt, std::forward<Args>(args)...);
153  }
154 
155  template<typename... Args>
156  void info(format_string_t<Args...> fmt, Args &&... args)
157  {
158  log(level::info, fmt, std::forward<Args>(args)...);
159  }
160 
161  template<typename... Args>
162  void warn(format_string_t<Args...> fmt, Args &&... args)
163  {
164  log(level::warn, fmt, std::forward<Args>(args)...);
165  }
166 
167  template<typename... Args>
168  void error(format_string_t<Args...> fmt, Args &&... args)
169  {
170  log(level::err, fmt, std::forward<Args>(args)...);
171  }
172 
173  template<typename... Args>
174  void critical(format_string_t<Args...> fmt, Args &&... args)
175  {
176  log(level::critical, fmt, std::forward<Args>(args)...);
177  }
178 
179 #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
180  template<typename... Args>
181  void log(source_loc loc, level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&... args)
182  {
183  log_(loc, lvl, fmt, std::forward<Args>(args)...);
184  }
185 
186  template<typename... Args>
187  void log(level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&... args)
188  {
189  log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
190  }
191 
192  void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, wstring_view_t msg)
193  {
194  bool log_enabled = should_log(lvl);
195  bool traceback_enabled = tracer_.enabled();
196  if (!log_enabled && !traceback_enabled)
197  {
198  return;
199  }
200 
201  memory_buf_t buf;
202  details::os::wstr_to_utf8buf(wstring_view_t(msg.data(), msg.size()), buf);
203  details::log_msg log_msg(log_time, loc, name_, lvl, string_view_t(buf.data(), buf.size()));
204  log_it_(log_msg, log_enabled, traceback_enabled);
205  }
206 
207  void log(source_loc loc, level::level_enum lvl, wstring_view_t msg)
208  {
209  bool log_enabled = should_log(lvl);
210  bool traceback_enabled = tracer_.enabled();
211  if (!log_enabled && !traceback_enabled)
212  {
213  return;
214  }
215 
216  memory_buf_t buf;
217  details::os::wstr_to_utf8buf(wstring_view_t(msg.data(), msg.size()), buf);
218  details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
219  log_it_(log_msg, log_enabled, traceback_enabled);
220  }
221 
222  void log(level::level_enum lvl, wstring_view_t msg)
223  {
224  log(source_loc{}, lvl, msg);
225  }
226 
227  template<typename... Args>
228  void trace(wformat_string_t<Args...> fmt, Args &&... args)
229  {
230  log(level::trace, fmt, std::forward<Args>(args)...);
231  }
232 
233  template<typename... Args>
234  void debug(wformat_string_t<Args...> fmt, Args &&... args)
235  {
236  log(level::debug, fmt, std::forward<Args>(args)...);
237  }
238 
239  template<typename... Args>
240  void info(wformat_string_t<Args...> fmt, Args &&... args)
241  {
242  log(level::info, fmt, std::forward<Args>(args)...);
243  }
244 
245  template<typename... Args>
246  void warn(wformat_string_t<Args...> fmt, Args &&... args)
247  {
248  log(level::warn, fmt, std::forward<Args>(args)...);
249  }
250 
251  template<typename... Args>
252  void error(wformat_string_t<Args...> fmt, Args &&... args)
253  {
254  log(level::err, fmt, std::forward<Args>(args)...);
255  }
256 
257  template<typename... Args>
258  void critical(wformat_string_t<Args...> fmt, Args &&... args)
259  {
260  log(level::critical, fmt, std::forward<Args>(args)...);
261  }
262 #endif
263 
264  template<typename T>
265  void trace(const T &msg)
266  {
267  log(level::trace, msg);
268  }
269 
270  template<typename T>
271  void debug(const T &msg)
272  {
273  log(level::debug, msg);
274  }
275 
276  template<typename T>
277  void info(const T &msg)
278  {
279  log(level::info, msg);
280  }
281 
282  template<typename T>
283  void warn(const T &msg)
284  {
285  log(level::warn, msg);
286  }
287 
288  template<typename T>
289  void error(const T &msg)
290  {
291  log(level::err, msg);
292  }
293 
294  template<typename T>
295  void critical(const T &msg)
296  {
297  log(level::critical, msg);
298  }
299 
300  // return true logging is enabled for the given level.
301  bool should_log(level::level_enum msg_level) const
302  {
303  return msg_level >= level_.load(std::memory_order_relaxed);
304  }
305 
306  // return true if backtrace logging is enabled.
307  bool should_backtrace() const
308  {
309  return tracer_.enabled();
310  }
311 
312  void set_level(level::level_enum log_level);
313 
314  level::level_enum level() const;
315 
316  const std::string &name() const;
317 
318  // set formatting for the sinks in this logger.
319  // each sink will get a separate instance of the formatter object.
320  void set_formatter(std::unique_ptr<formatter> f);
321 
322  void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
323 
324  // backtrace support.
325  // efficiently store all debug/trace messages in a circular buffer until needed for debugging.
326  void enable_backtrace(size_t n_messages);
327  void disable_backtrace();
328  void dump_backtrace();
329 
330  // flush functions
331  void flush();
332  void flush_on(level::level_enum log_level);
333  level::level_enum flush_level() const;
334 
335  // sinks
336  const std::vector<sink_ptr> &sinks() const;
337 
338  std::vector<sink_ptr> &sinks();
339 
340  // error handler
342 
343  // create new logger with same sinks and configuration.
344  virtual std::shared_ptr<logger> clone(std::string logger_name);
345 
346 protected:
347  std::string name_;
348  std::vector<sink_ptr> sinks_;
351  err_handler custom_err_handler_{nullptr};
353 
354  // common implementation for after templated public api has been resolved
355  template<typename... Args>
356  void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&... args)
357  {
358  bool log_enabled = should_log(lvl);
359  bool traceback_enabled = tracer_.enabled();
360  if (!log_enabled && !traceback_enabled)
361  {
362  return;
363  }
364  SPDLOG_TRY
365  {
366 #ifdef SPDLOG_USE_STD_FORMAT
367  memory_buf_t buf = std::vformat(fmt, std::make_format_args(std::forward<Args>(args)...));
368 #else
369  memory_buf_t buf;
370  fmt::detail::vformat_to(buf, fmt, fmt::make_format_args(std::forward<Args>(args)...));
371 #endif
372  details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
373  log_it_(log_msg, log_enabled, traceback_enabled);
374  }
376  }
377 
378 #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
379  template<typename... Args>
380  void log_(source_loc loc, level::level_enum lvl, wstring_view_t fmt, Args &&... args)
381  {
382  bool log_enabled = should_log(lvl);
383  bool traceback_enabled = tracer_.enabled();
384  if (!log_enabled && !traceback_enabled)
385  {
386  return;
387  }
388  SPDLOG_TRY
389  {
390  // format to wmemory_buffer and convert to utf8
391  ;
392 # ifdef SPDLOG_USE_STD_FORMAT
393  wmemory_buf_t wbuf = std::vformat(fmt, std::make_wformat_args(std::forward<Args>(args)...));
394 # else
395  wmemory_buf_t wbuf;
396  fmt::detail::vformat_to(wbuf, fmt, fmt::make_format_args<fmt::wformat_context>(std::forward<Args>(args)...));
397 # endif
398  memory_buf_t buf;
399  details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf);
400  details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
401  log_it_(log_msg, log_enabled, traceback_enabled);
402  }
404  }
405 
406  // T can be statically converted to wstring_view, and no formatting needed.
408  void log_(source_loc loc, level::level_enum lvl, const T &msg)
409  {
410  bool log_enabled = should_log(lvl);
411  bool traceback_enabled = tracer_.enabled();
412  if (!log_enabled && !traceback_enabled)
413  {
414  return;
415  }
416  SPDLOG_TRY
417  {
418  memory_buf_t buf;
419  details::os::wstr_to_utf8buf(msg, buf);
420  details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
421  log_it_(log_msg, log_enabled, traceback_enabled);
422  }
424  }
425 
426 #endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
427 
428  // log the given message (if the given log level is high enough),
429  // and save backtrace (if backtrace is enabled).
430  void log_it_(const details::log_msg &log_msg, bool log_enabled, bool traceback_enabled);
431  virtual void sink_it_(const details::log_msg &msg);
432  virtual void flush_();
433  void dump_backtrace_();
434  bool should_flush_(const details::log_msg &msg);
435 
436  // handle errors during logging.
437  // default handler prints the error to stderr at max rate of 1 message/sec.
438  void err_handler_(const std::string &msg);
439 };
440 
441 void swap(logger &a, logger &b);
442 
443 } // namespace spdlog
444 
445 #ifdef SPDLOG_HEADER_ONLY
446 # include "logger-inl.h"
447 #endif
spdlog::logger::log
void log(source_loc loc, level::level_enum lvl, const T &msg)
Definition: logger.h:107
spdlog::logger::info
void info(const T &msg)
Definition: logger.h:277
spdlog::logger::logger
logger(std::string name)
Definition: logger.h:58
spdlog::logger::sinks_
std::vector< sink_ptr > sinks_
Definition: logger.h:348
spdlog::logger::trace
void trace(format_string_t< Args... > fmt, Args &&... args)
Definition: logger.h:144
spdlog::set_error_handler
SPDLOG_INLINE void set_error_handler(void(*handler)(const std::string &msg))
Definition: spdlog-inl.h:75
SPDLOG_NOEXCEPT
#define SPDLOG_NOEXCEPT
Definition: common.h:64
spdlog::logger::log_
void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&... args)
Definition: logger.h:356
fmt::v8::vformat
std::basic_string< Char > vformat(const text_style &ts, const S &format_str, basic_format_args< buffer_context< type_identity_t< Char >>> args)
Definition: color.h:573
spdlog::level::trace
@ trace
Definition: common.h:213
SPDLOG_LOGGER_CATCH
#define SPDLOG_LOGGER_CATCH(location)
Definition: logger.h:31
spdlog::error
void error(format_string_t< Args... > fmt, Args &&... args)
Definition: spdlog.h:167
spdlog::level::off
@ off
Definition: common.h:219
spdlog::logger::log
void log(level::level_enum lvl, format_string_t< Args... > fmt, Args &&... args)
Definition: logger.h:94
Catch::Generators::value
GeneratorWrapper< T > value(T &&value)
Definition: catch.hpp:3999
spdlog::string_view_t
fmt::basic_string_view< char > string_view_t
Definition: common.h:154
spdlog::logger::critical
void critical(const T &msg)
Definition: logger.h:295
spdlog::sink_ptr
std::shared_ptr< sinks::sink > sink_ptr
Definition: common.h:127
spdlog::level::warn
@ warn
Definition: common.h:216
fmt::v8::detail::buffer::size
constexpr auto size() const -> size_t
Definition: core.h:820
spdlog::critical
void critical(format_string_t< Args... > fmt, Args &&... args)
Definition: spdlog.h:173
spdlog::logger::log
void log(level::level_enum lvl, string_view_t msg)
Definition: logger.h:138
spdlog::set_level
SPDLOG_INLINE void set_level(level::level_enum log_level)
Definition: spdlog-inl.h:60
spdlog::level_t
std::atomic< int > level_t
Definition: common.h:194
spdlog::set_pattern
SPDLOG_INLINE void set_pattern(std::string pattern, pattern_time_type time_type)
Definition: spdlog-inl.h:30
fmt::v8::basic_string_view
Definition: core.h:448
spdlog::logger::tracer_
details::backtracer tracer_
Definition: logger.h:352
spdlog::logger
Definition: logger.h:54
spdlog::logger::debug
void debug(format_string_t< Args... > fmt, Args &&... args)
Definition: logger.h:150
spdlog::sinks_init_list
std::initializer_list< sink_ptr > sinks_init_list
Definition: common.h:128
spdlog::level::info
@ info
Definition: common.h:215
spdlog::level::level_enum
level_enum
Definition: common.h:211
spdlog::logger::error
void error(format_string_t< Args... > fmt, Args &&... args)
Definition: logger.h:168
spdlog::level::debug
@ debug
Definition: common.h:214
spdlog::logger::warn
void warn(format_string_t< Args... > fmt, Args &&... args)
Definition: logger.h:162
spdlog::warn
void warn(format_string_t< Args... > fmt, Args &&... args)
Definition: spdlog.h:161
spdlog::level::err
@ err
Definition: common.h:217
spdlog::logger::name_
std::string name_
Definition: logger.h:347
T
T
Definition: simulate_performance.m:4
spdlog::logger::debug
void debug(const T &msg)
Definition: logger.h:271
spdlog::swap
SPDLOG_INLINE void swap(logger &a, logger &b)
Definition: logger-inl.h:62
fmt::v8::basic_memory_buffer
Definition: format.h:677
spdlog::details::backtracer::enabled
bool enabled() const
Definition: backtracer-inl.h:46
spdlog
Definition: async.h:25
spdlog::logger::warn
void warn(const T &msg)
Definition: logger.h:283
nlohmann::json_v3_11_1NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON::detail2::begin
begin_tag begin(T &&...)
spdlog::enable_backtrace
SPDLOG_INLINE void enable_backtrace(size_t n_messages)
Definition: spdlog-inl.h:35
spdlog::logger::logger
logger(std::string name, sink_ptr single_sink)
Definition: logger.h:71
spdlog::logger::trace
void trace(const T &msg)
Definition: logger.h:265
spdlog::source_loc
Definition: common.h:290
os.h
logger-inl.h
fmt::v8::make_format_args
constexpr auto make_format_args(Args &&... args) -> format_arg_store< Context, remove_cvref_t< Args >... >
Definition: core.h:1870
spdlog::logger::logger
logger(std::string name, sinks_init_list sinks)
Definition: logger.h:76
fmt::v8::detail::vformat_to
void vformat_to(buffer< Char > &buf, const text_style &ts, basic_string_view< Char > format_str, basic_format_args< buffer_context< type_identity_t< Char >>> args)
Definition: color.h:502
spdlog::info
void info(format_string_t< Args... > fmt, Args &&... args)
Definition: spdlog.h:155
spdlog::trace
void trace(format_string_t< Args... > fmt, Args &&... args)
Definition: spdlog.h:143
spdlog::err_handler
std::function< void(const std::string &err_msg)> err_handler
Definition: common.h:129
fmt::v8::detail::buffer::data
auto data() -> T *
Definition: core.h:826
spdlog::logger::info
void info(format_string_t< Args... > fmt, Args &&... args)
Definition: logger.h:156
fmt::v8::make_wformat_args
constexpr format_arg_store< wformat_context, Args... > make_wformat_args(const Args &... args)
Definition: xchar.h:44
common.h
spdlog::pattern_time_type::local
@ local
spdlog::disable_backtrace
SPDLOG_INLINE void disable_backtrace()
Definition: spdlog-inl.h:40
spdlog::set_formatter
SPDLOG_INLINE void set_formatter(std::unique_ptr< spdlog::formatter > formatter)
Definition: spdlog-inl.h:25
spdlog::details::log_msg
Definition: log_msg.h:11
spdlog::pattern_time_type
pattern_time_type
Definition: common.h:267
spdlog::should_log
SPDLOG_INLINE bool should_log(level::level_enum log_level)
Definition: spdlog-inl.h:55
std
Definition: json.hpp:5213
spdlog::memory_buf_t
fmt::basic_memory_buffer< char, 250 > memory_buf_t
Definition: common.h:155
fmt
Definition: bin_to_hex.h:102
spdlog::logger::log
void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg)
Definition: logger.h:112
spdlog::dump_backtrace
SPDLOG_INLINE void dump_backtrace()
Definition: spdlog-inl.h:45
spdlog::logger::log
void log(source_loc loc, level::level_enum lvl, format_string_t< Args... > fmt, Args &&... args)
Definition: logger.h:88
spdlog::logger::should_backtrace
bool should_backtrace() const
Definition: logger.h:307
spdlog::logger::logger
logger(std::string name, It begin, It end)
Definition: logger.h:65
SPDLOG_TRY
#define SPDLOG_TRY
Definition: common.h:102
fmt::v8::basic_format_string
Definition: core.h:3049
spdlog::level::critical
@ critical
Definition: common.h:218
spdlog::logger::should_log
bool should_log(level::level_enum msg_level) const
Definition: logger.h:301
SPDLOG_API
#define SPDLOG_API
Definition: common.h:40
spdlog::debug
void debug(format_string_t< Args... > fmt, Args &&... args)
Definition: spdlog.h:149
log_msg.h
spdlog::flush_on
SPDLOG_INLINE void flush_on(level::level_enum log_level)
Definition: spdlog-inl.h:65
spdlog::logger::log
void log(level::level_enum lvl, const T &msg)
Definition: logger.h:100
spdlog::details::backtracer
Definition: backtracer.h:18
spdlog::logger::log
void log(source_loc loc, level::level_enum lvl, string_view_t msg)
Definition: logger.h:125
nlohmann::json_v3_11_1NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON::detail2::end
end_tag end(T &&...)
backtracer.h
spdlog::log
void log(source_loc source, level::level_enum lvl, format_string_t< Args... > fmt, Args &&... args)
Definition: spdlog.h:131
fmt::v8::detail::type
type
Definition: core.h:1131
spdlog::logger::error
void error(const T &msg)
Definition: logger.h:289
spdlog::logger::critical
void critical(format_string_t< Args... > fmt, Args &&... args)
Definition: logger.h:174