spdlog
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() \
32 catch (const std::exception &ex) \
33 { \
34 err_handler_(ex.what()); \
35 } \
36 catch (...) \
37 { \
38 err_handler_("Rethrowing unknown exception in logger"); \
39 throw; \
40 }
41#else
42# define SPDLOG_LOGGER_CATCH()
43#endif
44
45namespace spdlog {
46
48{
49public:
50 // Empty logger
52 : name_(std::move(name))
53 , sinks_()
54 {}
55
56 // Logger with range on sinks
57 template<typename It>
58 logger(std::string name, It begin, It end)
59 : name_(std::move(name))
60 , sinks_(begin, end)
61 {}
62
63 // Logger with single sink
65 : logger(std::move(name), {std::move(single_sink)})
66 {}
67
68 // Logger with sinks init list
70 : logger(std::move(name), sinks.begin(), sinks.end())
71 {}
72
73 virtual ~logger() = default;
74
75 logger(const logger &other);
77 logger &operator=(logger other) SPDLOG_NOEXCEPT;
78 void swap(spdlog::logger &other) SPDLOG_NOEXCEPT;
79
80 template<typename... Args>
81 void log(source_loc loc, level::level_enum lvl, fmt::format_string<Args...> fmt, Args &&...args)
82 {
83 log_(loc, lvl, fmt, std::forward<Args>(args)...);
84 }
85
86 template<typename... Args>
87 void log(level::level_enum lvl, fmt::format_string<Args...> fmt, Args &&...args)
88 {
89 log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
90 }
91
92 template<typename T>
93 void log(level::level_enum lvl, const T &msg)
94 {
95 log(source_loc{}, lvl, msg);
96 }
97
98 // T can be statically converted to string_view
99 template<class T, typename std::enable_if<std::is_convertible<const T &, spdlog::string_view_t>::value, int>::type = 0>
100 void log(source_loc loc, level::level_enum lvl, const T &msg)
101 {
102 log(loc, lvl, string_view_t{msg});
103 }
104
105 // T cannot be statically converted to format string (including string_view)
106 template<class T, typename std::enable_if<!is_convertible_to_any_format_string<const T &>::value, int>::type = 0>
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(fmt::format_string<Args...> fmt, Args &&...args)
145 {
146 log(level::trace, fmt, std::forward<Args>(args)...);
147 }
148
149 template<typename... Args>
150 void debug(fmt::format_string<Args...> fmt, Args &&...args)
151 {
152 log(level::debug, fmt, std::forward<Args>(args)...);
153 }
154
155 template<typename... Args>
156 void info(fmt::format_string<Args...> fmt, Args &&...args)
157 {
158 log(level::info, fmt, std::forward<Args>(args)...);
159 }
160
161 template<typename... Args>
162 void warn(fmt::format_string<Args...> fmt, Args &&...args)
163 {
164 log(level::warn, fmt, std::forward<Args>(args)...);
165 }
166
167 template<typename... Args>
168 void error(fmt::format_string<Args...> fmt, Args &&...args)
169 {
170 log(level::err, fmt, std::forward<Args>(args)...);
171 }
172
173 template<typename... Args>
174 void critical(fmt::format_string<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(level::level_enum lvl, fmt::wformat_string<Args...> fmt, Args &&...args)
182 {
183 log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
184 }
185
186 template<typename... Args>
187 void log(source_loc loc, level::level_enum lvl, fmt::wformat_string<Args...> fmt, Args &&...args)
188 {
189 log_(loc, lvl, fmt, std::forward<Args>(args)...);
190 }
191
192 template<typename... Args>
193 void trace(fmt::wformat_string<Args...> fmt, Args &&...args)
194 {
195 log(level::trace, fmt, std::forward<Args>(args)...);
196 }
197
198 template<typename... Args>
199 void debug(fmt::wformat_string<Args...> fmt, Args &&...args)
200 {
201 log(level::debug, fmt, std::forward<Args>(args)...);
202 }
203
204 template<typename... Args>
205 void info(fmt::wformat_string<Args...> fmt, Args &&...args)
206 {
207 log(level::info, fmt, std::forward<Args>(args)...);
208 }
209
210 template<typename... Args>
211 void warn(fmt::wformat_string<Args...> fmt, Args &&...args)
212 {
213 log(level::warn, fmt, std::forward<Args>(args)...);
214 }
215
216 template<typename... Args>
217 void error(fmt::wformat_string<Args...> fmt, Args &&...args)
218 {
219 log(level::err, fmt, std::forward<Args>(args)...);
220 }
221
222 template<typename... Args>
223 void critical(fmt::wformat_string<Args...> fmt, Args &&...args)
224 {
225 log(level::critical, fmt, std::forward<Args>(args)...);
226 }
227#endif
228
229 template<typename T>
230 void trace(const T &msg)
231 {
232 log(level::trace, msg);
233 }
234
235 template<typename T>
236 void debug(const T &msg)
237 {
238 log(level::debug, msg);
239 }
240
241 template<typename T>
242 void info(const T &msg)
243 {
244 log(level::info, msg);
245 }
246
247 template<typename T>
248 void warn(const T &msg)
249 {
250 log(level::warn, msg);
251 }
252
253 template<typename T>
254 void error(const T &msg)
255 {
256 log(level::err, msg);
257 }
258
259 template<typename T>
260 void critical(const T &msg)
261 {
262 log(level::critical, msg);
263 }
264
265 // return true logging is enabled for the given level.
266 bool should_log(level::level_enum msg_level) const
267 {
268 return msg_level >= level_.load(std::memory_order_relaxed);
269 }
270
271 // return true if backtrace logging is enabled.
272 bool should_backtrace() const
273 {
274 return tracer_.enabled();
275 }
276
277 void set_level(level::level_enum log_level);
278
279 level::level_enum level() const;
280
281 const std::string &name() const;
282
283 // set formatting for the sinks in this logger.
284 // each sink will get a separate instance of the formatter object.
286
287 void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
288
289 // backtrace support.
290 // efficiently store all debug/trace messages in a circular buffer until needed for debugging.
291 void enable_backtrace(size_t n_messages);
292 void disable_backtrace();
293 void dump_backtrace();
294
295 // flush functions
296 void flush();
297 void flush_on(level::level_enum log_level);
298 level::level_enum flush_level() const;
299
300 // sinks
301 const std::vector<sink_ptr> &sinks() const;
302
303 std::vector<sink_ptr> &sinks();
304
305 // error handler
307
308 // create new logger with same sinks and configuration.
309 virtual std::shared_ptr<logger> clone(std::string logger_name);
310
311protected:
314 spdlog::level_t level_{level::info};
315 spdlog::level_t flush_level_{level::off};
316 err_handler custom_err_handler_{nullptr};
318
319 // common implementation for after templated public api has been resolved
320 template<typename... Args>
321 void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&...args)
322 {
323 bool log_enabled = should_log(lvl);
324 bool traceback_enabled = tracer_.enabled();
325 if (!log_enabled && !traceback_enabled)
326 {
327 return;
328 }
330 {
331 memory_buf_t buf;
332 fmt::detail::vformat_to(buf, fmt, fmt::make_format_args(args...));
333 details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
334 log_it_(log_msg, log_enabled, traceback_enabled);
335 }
337 }
338
339#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
340 template<typename... Args>
341 void log_(source_loc loc, level::level_enum lvl, wstring_view_t fmt, Args &&...args)
342 {
343 bool log_enabled = should_log(lvl);
344 bool traceback_enabled = tracer_.enabled();
345 if (!log_enabled && !traceback_enabled)
346 {
347 return;
348 }
350 {
351 // format to wmemory_buffer and convert to utf8
352 fmt::wmemory_buffer wbuf;
353 fmt::detail::vformat_to(wbuf, fmt, fmt::make_format_args<fmt::wformat_context>(args...));
354 memory_buf_t buf;
355 details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf);
356 details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
357 log_it_(log_msg, log_enabled, traceback_enabled);
358 }
360 }
361
362 // T can be statically converted to wstring_view, and no formatting needed.
363 template<class T, typename std::enable_if<std::is_convertible<const T &, spdlog::wstring_view_t>::value, int>::type = 0>
364 void log_(source_loc loc, level::level_enum lvl, const T &msg)
365 {
366 bool log_enabled = should_log(lvl);
367 bool traceback_enabled = tracer_.enabled();
368 if (!log_enabled && !traceback_enabled)
369 {
370 return;
371 }
373 {
374 memory_buf_t buf;
375 details::os::wstr_to_utf8buf(msg, buf);
376 details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
377 log_it_(log_msg, log_enabled, traceback_enabled);
378 }
380 }
381
382#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
383
384 // log the given message (if the given log level is high enough),
385 // and save backtrace (if backtrace is enabled).
386 void log_it_(const details::log_msg &log_msg, bool log_enabled, bool traceback_enabled);
387 virtual void sink_it_(const details::log_msg &msg);
388 virtual void flush_();
389 void dump_backtrace_();
390 bool should_flush_(const details::log_msg &msg);
391
392 // handle errors during logging.
393 // default handler prints the error to stderr at max rate of 1 message/sec.
394 void err_handler_(const std::string &msg);
395};
396
397void swap(logger &a, logger &b);
398
399} // namespace spdlog
400
401#ifdef SPDLOG_HEADER_ONLY
402# include "logger-inl.h"
403#endif
void log(source_loc loc, level::level_enum lvl, const T &msg)
Definition logger.h:100
void info(fmt::format_string< Args... > fmt, Args &&...args)
Definition logger.h:156
bool should_backtrace() const
Definition logger.h:272
void log(level::level_enum lvl, const T &msg)
Definition logger.h:93
void info(const T &msg)
Definition logger.h:242
void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg)
Definition logger.h:112
std::vector< sink_ptr > sinks_
Definition logger.h:313
void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&...args)
Definition logger.h:321
void critical(const T &msg)
Definition logger.h:260
void error(fmt::format_string< Args... > fmt, Args &&...args)
Definition logger.h:168
logger(std::string name, It begin, It end)
Definition logger.h:58
logger(std::string name)
Definition logger.h:51
logger(std::string name, sink_ptr single_sink)
Definition logger.h:64
virtual ~logger()=default
void trace(const T &msg)
Definition logger.h:230
void warn(fmt::format_string< Args... > fmt, Args &&...args)
Definition logger.h:162
std::string name_
Definition logger.h:312
void trace(fmt::format_string< Args... > fmt, Args &&...args)
Definition logger.h:144
void debug(fmt::format_string< Args... > fmt, Args &&...args)
Definition logger.h:150
void log(source_loc loc, level::level_enum lvl, fmt::format_string< Args... > fmt, Args &&...args)
Definition logger.h:81
bool should_log(level::level_enum msg_level) const
Definition logger.h:266
void error(const T &msg)
Definition logger.h:254
details::backtracer tracer_
Definition logger.h:317
void debug(const T &msg)
Definition logger.h:236
void log(level::level_enum lvl, fmt::format_string< Args... > fmt, Args &&...args)
Definition logger.h:87
void log(level::level_enum lvl, string_view_t msg)
Definition logger.h:138
void critical(fmt::format_string< Args... > fmt, Args &&...args)
Definition logger.h:174
void log(source_loc loc, level::level_enum lvl, string_view_t msg)
Definition logger.h:125
logger(std::string name, sinks_init_list sinks)
Definition logger.h:69
void warn(const T &msg)
Definition logger.h:248
#define SPDLOG_NOEXCEPT
Definition common.h:53
#define SPDLOG_TRY
Definition common.h:86
#define SPDLOG_API
Definition common.h:31
type
Definition core.h:1048
T
Definition core.h:320
T log(T... args)
#define SPDLOG_LOGGER_CATCH()
Definition logger.h:31
T make_shared(T... args)
Definition async.h:25
SPDLOG_INLINE void disable_backtrace()
Definition spdlog-inl.h:40
SPDLOG_INLINE void set_level(level::level_enum log_level)
Definition spdlog-inl.h:60
fmt::basic_string_view< wchar_t > wstring_view_t
Definition common.h:115
SPDLOG_INLINE void enable_backtrace(size_t n_messages)
Definition spdlog-inl.h:35
SPDLOG_INLINE void swap(logger &a, logger &b)
Definition logger-inl.h:62
SPDLOG_INLINE void set_error_handler(void(*handler)(const std::string &msg))
Definition spdlog-inl.h:75
SPDLOG_INLINE void dump_backtrace()
Definition spdlog-inl.h:45
fmt::basic_string_view< char > string_view_t
Definition common.h:114
SPDLOG_INLINE void flush_on(level::level_enum log_level)
Definition spdlog-inl.h:65
SPDLOG_INLINE void set_formatter(std::unique_ptr< spdlog::formatter > formatter)
Definition spdlog-inl.h:25
pattern_time_type
Definition common.h:218
SPDLOG_INLINE bool should_log(level::level_enum log_level)
Definition spdlog-inl.h:55
SPDLOG_INLINE void set_pattern(std::string pattern, pattern_time_type time_type)
Definition spdlog-inl.h:30
fmt::basic_memory_buffer< char, 250 > memory_buf_t
Definition common.h:116