Photon 1.0.0
Loading...
Searching...
No Matches
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>
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(SPDLOG_FMT_STRING("{} [{}({})]"), 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
52namespace spdlog
53{
54
56 {
57 public:
58 // Empty logger
59 explicit logger(std::string name)
60 : name_(std::move(name)), sinks_()
61 {
62 }
63
64 // Logger with range on sinks
65 template <typename It>
66 logger(std::string name, It begin, It end)
67 : name_(std::move(name)), sinks_(begin, end)
68 {
69 }
70
71 // Logger with single sink
72 logger(std::string name, sink_ptr single_sink)
73 : logger(std::move(name), {std::move(single_sink)})
74 {
75 }
76
77 // Logger with sinks init list
78 logger(std::string name, sinks_init_list sinks)
79 : logger(std::move(name), sinks.begin(), sinks.end())
80 {
81 }
82
83 virtual ~logger() = default;
84
85 logger(const logger& other);
87 logger& operator=(logger other) SPDLOG_NOEXCEPT;
89
90 template <typename... Args>
92 {
93 log_(loc, lvl, details::to_string_view(fmt), std::forward<Args>(args)...);
94 }
95
96 template <typename... Args>
98 {
99 log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
100 }
101
102 template <typename T>
103 void log(level::level_enum lvl, const T& msg)
104 {
105 log(source_loc{}, lvl, msg);
106 }
107
108 // T cannot be statically converted to format string (including string_view/wstring_view)
109 template <class T, typename std::enable_if<!is_convertible_to_any_format_string<const T&>::value, int>::type = 0>
110 void log(source_loc loc, level::level_enum lvl, const T& msg)
111 {
112 log(loc, lvl, "{}", msg);
113 }
114
115 void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg)
116 {
117 bool log_enabled = should_log(lvl);
118 bool traceback_enabled = tracer_.enabled();
119 if (!log_enabled && !traceback_enabled)
120 {
121 return;
122 }
123
124 details::log_msg log_msg(log_time, loc, name_, lvl, msg);
125 log_it_(log_msg, log_enabled, traceback_enabled);
126 }
127
129 {
130 bool log_enabled = should_log(lvl);
131 bool traceback_enabled = tracer_.enabled();
132 if (!log_enabled && !traceback_enabled)
133 {
134 return;
135 }
136
137 details::log_msg log_msg(loc, name_, lvl, msg);
138 log_it_(log_msg, log_enabled, traceback_enabled);
139 }
140
142 {
143 log(source_loc{}, lvl, msg);
144 }
145
146 template <typename... Args>
147 void trace(format_string_t<Args...> fmt, Args&&... args)
148 {
149 log(level::trace, fmt, std::forward<Args>(args)...);
150 }
151
152 template <typename... Args>
153 void debug(format_string_t<Args...> fmt, Args&&... args)
154 {
155 log(level::debug, fmt, std::forward<Args>(args)...);
156 }
157
158 template <typename... Args>
159 void info(format_string_t<Args...> fmt, Args&&... args)
160 {
161 log(level::info, fmt, std::forward<Args>(args)...);
162 }
163
164 template <typename... Args>
165 void warn(format_string_t<Args...> fmt, Args&&... args)
166 {
167 log(level::warn, fmt, std::forward<Args>(args)...);
168 }
169
170 template <typename... Args>
171 void error(format_string_t<Args...> fmt, Args&&... args)
172 {
173 log(level::err, fmt, std::forward<Args>(args)...);
174 }
175
176 template <typename... Args>
178 {
179 log(level::critical, fmt, std::forward<Args>(args)...);
180 }
181
182#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
183 template <typename... Args>
184 void log(source_loc loc, level::level_enum lvl, wformat_string_t<Args...> fmt, Args&&... args)
185 {
186 log_(loc, lvl, details::to_string_view(fmt), std::forward<Args>(args)...);
187 }
188
189 template <typename... Args>
190 void log(level::level_enum lvl, wformat_string_t<Args...> fmt, Args&&... args)
191 {
192 log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
193 }
194
195 void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, wstring_view_t msg)
196 {
197 bool log_enabled = should_log(lvl);
198 bool traceback_enabled = tracer_.enabled();
199 if (!log_enabled && !traceback_enabled)
200 {
201 return;
202 }
203
204 memory_buf_t buf;
205 details::os::wstr_to_utf8buf(wstring_view_t(msg.data(), msg.size()), buf);
206 details::log_msg log_msg(log_time, loc, name_, lvl, string_view_t(buf.data(), buf.size()));
207 log_it_(log_msg, log_enabled, traceback_enabled);
208 }
209
210 void log(source_loc loc, level::level_enum lvl, wstring_view_t msg)
211 {
212 bool log_enabled = should_log(lvl);
213 bool traceback_enabled = tracer_.enabled();
214 if (!log_enabled && !traceback_enabled)
215 {
216 return;
217 }
218
219 memory_buf_t buf;
220 details::os::wstr_to_utf8buf(wstring_view_t(msg.data(), msg.size()), buf);
221 details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
222 log_it_(log_msg, log_enabled, traceback_enabled);
223 }
224
225 void log(level::level_enum lvl, wstring_view_t msg)
226 {
227 log(source_loc{}, lvl, msg);
228 }
229
230 template <typename... Args>
231 void trace(wformat_string_t<Args...> fmt, Args&&... args)
232 {
233 log(level::trace, fmt, std::forward<Args>(args)...);
234 }
235
236 template <typename... Args>
237 void debug(wformat_string_t<Args...> fmt, Args&&... args)
238 {
239 log(level::debug, fmt, std::forward<Args>(args)...);
240 }
241
242 template <typename... Args>
243 void info(wformat_string_t<Args...> fmt, Args&&... args)
244 {
245 log(level::info, fmt, std::forward<Args>(args)...);
246 }
247
248 template <typename... Args>
249 void warn(wformat_string_t<Args...> fmt, Args&&... args)
250 {
251 log(level::warn, fmt, std::forward<Args>(args)...);
252 }
253
254 template <typename... Args>
255 void error(wformat_string_t<Args...> fmt, Args&&... args)
256 {
257 log(level::err, fmt, std::forward<Args>(args)...);
258 }
259
260 template <typename... Args>
261 void critical(wformat_string_t<Args...> fmt, Args&&... args)
262 {
263 log(level::critical, fmt, std::forward<Args>(args)...);
264 }
265#endif
266
267 template <typename T>
268 void trace(const T& msg)
269 {
270 log(level::trace, msg);
271 }
272
273 template <typename T>
274 void debug(const T& msg)
275 {
276 log(level::debug, msg);
277 }
278
279 template <typename T>
280 void info(const T& msg)
281 {
282 log(level::info, msg);
283 }
284
285 template <typename T>
286 void warn(const T& msg)
287 {
288 log(level::warn, msg);
289 }
290
291 template <typename T>
292 void error(const T& msg)
293 {
294 log(level::err, msg);
295 }
296
297 template <typename T>
298 void critical(const T& msg)
299 {
300 log(level::critical, msg);
301 }
302
303 // return true logging is enabled for the given level.
304 bool should_log(level::level_enum msg_level) const
305 {
306 return msg_level >= level_.load(std::memory_order_relaxed);
307 }
308
309 // return true if backtrace logging is enabled.
310 bool should_backtrace() const
311 {
312 return tracer_.enabled();
313 }
314
315 void set_level(level::level_enum log_level);
316
317 level::level_enum level() const;
318
319 const std::string& name() const;
320
321 // set formatting for the sinks in this logger.
322 // each sink will get a separate instance of the formatter object.
323 void set_formatter(std::unique_ptr<formatter> f);
324
325 // set formatting for the sinks in this logger.
326 // equivalent to
327 // set_formatter(make_unique<pattern_formatter>(pattern, time_type))
328 // Note: each sink will get a new instance of a formatter object, replacing the old one.
329 void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
330
331 // backtrace support.
332 // efficiently store all debug/trace messages in a circular buffer until needed for debugging.
333 void enable_backtrace(size_t n_messages);
334 void disable_backtrace();
335 void dump_backtrace();
336
337 // flush functions
338 void flush();
339 void flush_on(level::level_enum log_level);
340 level::level_enum flush_level() const;
341
342 // sinks
343 const std::vector<sink_ptr>& sinks() const;
344
345 std::vector<sink_ptr>& sinks();
346
347 // error handler
349
350 // create new logger with same sinks and configuration.
351 virtual std::shared_ptr<logger> clone(std::string logger_name);
352
353 protected:
354 std::string name_;
355 std::vector<sink_ptr> sinks_;
356 spdlog::level_t level_{level::info};
357 spdlog::level_t flush_level_{level::off};
358 err_handler custom_err_handler_{nullptr};
360
361 // common implementation for after templated public api has been resolved
362 template <typename... Args>
363 void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args&&... args)
364 {
365 bool log_enabled = should_log(lvl);
366 bool traceback_enabled = tracer_.enabled();
367 if (!log_enabled && !traceback_enabled)
368 {
369 return;
370 }
372 {
373 memory_buf_t buf;
374#ifdef SPDLOG_USE_STD_FORMAT
375 fmt_lib::vformat_to(std::back_inserter(buf), fmt, fmt_lib::make_format_args(std::forward<Args>(args)...));
376#else
377 fmt::vformat_to(fmt::appender(buf), fmt, fmt::make_format_args(std::forward<Args>(args)...));
378#endif
379
380 details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
381 log_it_(log_msg, log_enabled, traceback_enabled);
382 }
384 }
385
386#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
387 template <typename... Args>
388 void log_(source_loc loc, level::level_enum lvl, wstring_view_t fmt, Args&&... args)
389 {
390 bool log_enabled = should_log(lvl);
391 bool traceback_enabled = tracer_.enabled();
392 if (!log_enabled && !traceback_enabled)
393 {
394 return;
395 }
397 {
398 // format to wmemory_buffer and convert to utf8
399 wmemory_buf_t wbuf;
400 fmt_lib::vformat_to(
401 std::back_inserter(wbuf), fmt, fmt_lib::make_format_args<fmt_lib::wformat_context>(std::forward<Args>(args)...));
402
403 memory_buf_t buf;
404 details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf);
405 details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
406 log_it_(log_msg, log_enabled, traceback_enabled);
407 }
409 }
410#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
411
412 // log the given message (if the given log level is high enough),
413 // and save backtrace (if backtrace is enabled).
414 void log_it_(const details::log_msg& log_msg, bool log_enabled, bool traceback_enabled);
415 virtual void sink_it_(const details::log_msg& msg);
416 virtual void flush_();
417 void dump_backtrace_();
418 bool should_flush_(const details::log_msg& msg);
419
420 // handle errors during logging.
421 // default handler prints the error to stderr at max rate of 1 message/sec.
422 void err_handler_(const std::string& msg);
423 };
424
425 void swap(logger& a, logger& b);
426
427} // namespace spdlog
428
429#ifdef SPDLOG_HEADER_ONLY
430#include "logger-inl.h"
431#endif
Definition backtracer.h:21
bool enabled() const
Definition backtracer-inl.h:48
Definition logger.h:56
void log(source_loc loc, level::level_enum lvl, const T &msg)
Definition logger.h:110
bool should_backtrace() const
Definition logger.h:310
void warn(format_string_t< Args... > fmt, Args &&... args)
Definition logger.h:165
void log(level::level_enum lvl, const T &msg)
Definition logger.h:103
void info(const T &msg)
Definition logger.h:280
void log(level::level_enum lvl, format_string_t< Args... > fmt, Args &&... args)
Definition logger.h:97
void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg)
Definition logger.h:115
std::vector< sink_ptr > sinks_
Definition logger.h:355
void trace(format_string_t< Args... > fmt, Args &&... args)
Definition logger.h:147
void critical(const T &msg)
Definition logger.h:298
logger(std::string name, It begin, It end)
Definition logger.h:66
logger(std::string name)
Definition logger.h:59
logger(std::string name, sink_ptr single_sink)
Definition logger.h:72
virtual ~logger()=default
void trace(const T &msg)
Definition logger.h:268
std::string name_
Definition logger.h:354
void error(format_string_t< Args... > fmt, Args &&... args)
Definition logger.h:171
bool should_log(level::level_enum msg_level) const
Definition logger.h:304
void critical(format_string_t< Args... > fmt, Args &&... args)
Definition logger.h:177
void error(const T &msg)
Definition logger.h:292
details::backtracer tracer_
Definition logger.h:359
void log(source_loc loc, level::level_enum lvl, format_string_t< Args... > fmt, Args &&... args)
Definition logger.h:91
void info(format_string_t< Args... > fmt, Args &&... args)
Definition logger.h:159
void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&... args)
Definition logger.h:363
void debug(const T &msg)
Definition logger.h:274
void debug(format_string_t< Args... > fmt, Args &&... args)
Definition logger.h:153
void log(level::level_enum lvl, string_view_t msg)
Definition logger.h:141
void log(source_loc loc, level::level_enum lvl, string_view_t msg)
Definition logger.h:128
logger(std::string name, sinks_init_list sinks)
Definition logger.h:78
void warn(const T &msg)
Definition logger.h:286
#define SPDLOG_NOEXCEPT
Definition common.h:69
#define SPDLOG_TRY
Definition common.h:107
#define SPDLOG_API
Definition common.h:45
type
Definition core.h:681
#define SPDLOG_LOGGER_CATCH(location)
Definition logger.h:31
@ error
Definition format.h:3062
Definition bin_to_hex.h:111
level_enum
Definition common.h:233
@ critical
Definition common.h:239
@ warn
Definition common.h:237
@ info
Definition common.h:236
@ trace
Definition common.h:234
Definition async.h:26
SPDLOG_INLINE void disable_backtrace()
Definition spdlog-inl.h:41
std::function< void(const std::string &err_msg)> err_handler
Definition common.h:138
fmt::format_string< Args... > format_string_t
Definition common.h:176
SPDLOG_INLINE void set_level(level::level_enum log_level)
Definition spdlog-inl.h:61
std::shared_ptr< sinks::sink > sink_ptr
Definition common.h:136
SPDLOG_INLINE void enable_backtrace(size_t n_messages)
Definition spdlog-inl.h:36
SPDLOG_INLINE void swap(logger &a, logger &b)
Definition logger-inl.h:60
SPDLOG_INLINE void set_error_handler(void(*handler)(const std::string &msg))
Definition spdlog-inl.h:71
SPDLOG_INLINE void dump_backtrace()
Definition spdlog-inl.h:46
std::atomic< int > level_t
Definition common.h:214
std::initializer_list< sink_ptr > sinks_init_list
Definition common.h:137
fmt::basic_string_view< char > string_view_t
Definition common.h:172
void log(source_loc source, level::level_enum lvl, format_string_t< Args... > fmt, Args &&... args)
Definition spdlog.h:145
SPDLOG_INLINE void flush_on(level::level_enum log_level)
Definition spdlog-inl.h:66
SPDLOG_INLINE void set_formatter(std::unique_ptr< spdlog::formatter > formatter)
Definition spdlog-inl.h:26
pattern_time_type
Definition common.h:289
SPDLOG_INLINE bool should_log(level::level_enum log_level)
Definition spdlog-inl.h:56
SPDLOG_INLINE void set_pattern(std::string pattern, pattern_time_type time_type)
Definition spdlog-inl.h:31
fmt::basic_memory_buffer< char, 250 > memory_buf_t
Definition common.h:173
Definition uuid.h:926
Definition log_msg.h:14
Definition common.h:312
b
Definition tag_strings.h:61
a
Definition tag_strings.h:43