File indexing completed on 2025-07-27 08:58:01
0001
0002
0003
0004 #pragma once
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <spdlog/common.h>
0018 #include <spdlog/details/backtracer.h>
0019 #include <spdlog/details/log_msg.h>
0020
0021 #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
0022 #ifndef _WIN32
0023 #error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows
0024 #endif
0025 #include <spdlog/details/os.h>
0026 #endif
0027
0028 #include <vector>
0029
0030 #ifndef SPDLOG_NO_EXCEPTIONS
0031 #define SPDLOG_LOGGER_CATCH(location) \
0032 catch (const std::exception &ex) { \
0033 if (location.filename) { \
0034 err_handler_(fmt_lib::format(SPDLOG_FMT_STRING("{} [{}({})]"), ex.what(), \
0035 location.filename, location.line)); \
0036 } else { \
0037 err_handler_(ex.what()); \
0038 } \
0039 } \
0040 catch (...) { \
0041 err_handler_("Rethrowing unknown exception in logger"); \
0042 throw; \
0043 }
0044 #else
0045 #define SPDLOG_LOGGER_CATCH(location)
0046 #endif
0047
0048 namespace spdlog {
0049
0050 class SPDLOG_API logger {
0051 public:
0052
0053 explicit logger(std::string name)
0054 : name_(std::move(name)),
0055 sinks_() {}
0056
0057
0058 template <typename It>
0059 logger(std::string name, It begin, It end)
0060 : name_(std::move(name)),
0061 sinks_(begin, end) {}
0062
0063
0064 logger(std::string name, sink_ptr single_sink)
0065 : logger(std::move(name), {std::move(single_sink)}) {}
0066
0067
0068 logger(std::string name, sinks_init_list sinks)
0069 : logger(std::move(name), sinks.begin(), sinks.end()) {}
0070
0071 virtual ~logger() = default;
0072
0073 logger(const logger &other);
0074 logger(logger &&other) SPDLOG_NOEXCEPT;
0075 logger &operator=(logger other) SPDLOG_NOEXCEPT;
0076 void swap(spdlog::logger &other) SPDLOG_NOEXCEPT;
0077
0078 template <typename... Args>
0079 void log(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) {
0080 log_(loc, lvl, details::to_string_view(fmt), std::forward<Args>(args)...);
0081 }
0082
0083 template <typename... Args>
0084 void log(level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) {
0085 log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
0086 }
0087
0088 template <typename T>
0089 void log(level::level_enum lvl, const T &msg) {
0090 log(source_loc{}, lvl, msg);
0091 }
0092
0093
0094 template <class T,
0095 typename std::enable_if<!is_convertible_to_any_format_string<const T &>::value,
0096 int>::type = 0>
0097 void log(source_loc loc, level::level_enum lvl, const T &msg) {
0098 log(loc, lvl, "{}", msg);
0099 }
0100
0101 void log(log_clock::time_point log_time,
0102 source_loc loc,
0103 level::level_enum lvl,
0104 string_view_t msg) {
0105 bool log_enabled = should_log(lvl);
0106 bool traceback_enabled = tracer_.enabled();
0107 if (!log_enabled && !traceback_enabled) {
0108 return;
0109 }
0110
0111 details::log_msg log_msg(log_time, loc, name_, lvl, msg);
0112 log_it_(log_msg, log_enabled, traceback_enabled);
0113 }
0114
0115 void log(source_loc loc, level::level_enum lvl, string_view_t msg) {
0116 bool log_enabled = should_log(lvl);
0117 bool traceback_enabled = tracer_.enabled();
0118 if (!log_enabled && !traceback_enabled) {
0119 return;
0120 }
0121
0122 details::log_msg log_msg(loc, name_, lvl, msg);
0123 log_it_(log_msg, log_enabled, traceback_enabled);
0124 }
0125
0126 void log(level::level_enum lvl, string_view_t msg) { log(source_loc{}, lvl, msg); }
0127
0128 template <typename... Args>
0129 void trace(format_string_t<Args...> fmt, Args &&...args) {
0130 log(level::trace, fmt, std::forward<Args>(args)...);
0131 }
0132
0133 template <typename... Args>
0134 void debug(format_string_t<Args...> fmt, Args &&...args) {
0135 log(level::debug, fmt, std::forward<Args>(args)...);
0136 }
0137
0138 template <typename... Args>
0139 void info(format_string_t<Args...> fmt, Args &&...args) {
0140 log(level::info, fmt, std::forward<Args>(args)...);
0141 }
0142
0143 template <typename... Args>
0144 void warn(format_string_t<Args...> fmt, Args &&...args) {
0145 log(level::warn, fmt, std::forward<Args>(args)...);
0146 }
0147
0148 template <typename... Args>
0149 void error(format_string_t<Args...> fmt, Args &&...args) {
0150 log(level::err, fmt, std::forward<Args>(args)...);
0151 }
0152
0153 template <typename... Args>
0154 void critical(format_string_t<Args...> fmt, Args &&...args) {
0155 log(level::critical, fmt, std::forward<Args>(args)...);
0156 }
0157
0158 #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
0159 template <typename... Args>
0160 void log(source_loc loc, level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) {
0161 log_(loc, lvl, details::to_string_view(fmt), std::forward<Args>(args)...);
0162 }
0163
0164 template <typename... Args>
0165 void log(level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) {
0166 log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
0167 }
0168
0169 void log(log_clock::time_point log_time,
0170 source_loc loc,
0171 level::level_enum lvl,
0172 wstring_view_t msg) {
0173 bool log_enabled = should_log(lvl);
0174 bool traceback_enabled = tracer_.enabled();
0175 if (!log_enabled && !traceback_enabled) {
0176 return;
0177 }
0178
0179 memory_buf_t buf;
0180 details::os::wstr_to_utf8buf(wstring_view_t(msg.data(), msg.size()), buf);
0181 details::log_msg log_msg(log_time, loc, name_, lvl, string_view_t(buf.data(), buf.size()));
0182 log_it_(log_msg, log_enabled, traceback_enabled);
0183 }
0184
0185 void log(source_loc loc, level::level_enum lvl, wstring_view_t msg) {
0186 bool log_enabled = should_log(lvl);
0187 bool traceback_enabled = tracer_.enabled();
0188 if (!log_enabled && !traceback_enabled) {
0189 return;
0190 }
0191
0192 memory_buf_t buf;
0193 details::os::wstr_to_utf8buf(wstring_view_t(msg.data(), msg.size()), buf);
0194 details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
0195 log_it_(log_msg, log_enabled, traceback_enabled);
0196 }
0197
0198 void log(level::level_enum lvl, wstring_view_t msg) { log(source_loc{}, lvl, msg); }
0199
0200 template <typename... Args>
0201 void trace(wformat_string_t<Args...> fmt, Args &&...args) {
0202 log(level::trace, fmt, std::forward<Args>(args)...);
0203 }
0204
0205 template <typename... Args>
0206 void debug(wformat_string_t<Args...> fmt, Args &&...args) {
0207 log(level::debug, fmt, std::forward<Args>(args)...);
0208 }
0209
0210 template <typename... Args>
0211 void info(wformat_string_t<Args...> fmt, Args &&...args) {
0212 log(level::info, fmt, std::forward<Args>(args)...);
0213 }
0214
0215 template <typename... Args>
0216 void warn(wformat_string_t<Args...> fmt, Args &&...args) {
0217 log(level::warn, fmt, std::forward<Args>(args)...);
0218 }
0219
0220 template <typename... Args>
0221 void error(wformat_string_t<Args...> fmt, Args &&...args) {
0222 log(level::err, fmt, std::forward<Args>(args)...);
0223 }
0224
0225 template <typename... Args>
0226 void critical(wformat_string_t<Args...> fmt, Args &&...args) {
0227 log(level::critical, fmt, std::forward<Args>(args)...);
0228 }
0229 #endif
0230
0231 template <typename T>
0232 void trace(const T &msg) {
0233 log(level::trace, msg);
0234 }
0235
0236 template <typename T>
0237 void debug(const T &msg) {
0238 log(level::debug, msg);
0239 }
0240
0241 template <typename T>
0242 void info(const T &msg) {
0243 log(level::info, msg);
0244 }
0245
0246 template <typename T>
0247 void warn(const T &msg) {
0248 log(level::warn, msg);
0249 }
0250
0251 template <typename T>
0252 void error(const T &msg) {
0253 log(level::err, msg);
0254 }
0255
0256 template <typename T>
0257 void critical(const T &msg) {
0258 log(level::critical, msg);
0259 }
0260
0261
0262 bool should_log(level::level_enum msg_level) const {
0263 return msg_level >= level_.load(std::memory_order_relaxed);
0264 }
0265
0266
0267 bool should_backtrace() const { return tracer_.enabled(); }
0268
0269 void set_level(level::level_enum log_level);
0270
0271 level::level_enum level() const;
0272
0273 const std::string &name() const;
0274
0275
0276
0277 void set_formatter(std::unique_ptr<formatter> f);
0278
0279
0280
0281
0282
0283 void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
0284
0285
0286
0287 void enable_backtrace(size_t n_messages);
0288 void disable_backtrace();
0289 void dump_backtrace();
0290
0291
0292 void flush();
0293 void flush_on(level::level_enum log_level);
0294 level::level_enum flush_level() const;
0295
0296
0297 const std::vector<sink_ptr> &sinks() const;
0298
0299 std::vector<sink_ptr> &sinks();
0300
0301
0302 void set_error_handler(err_handler);
0303
0304
0305 virtual std::shared_ptr<logger> clone(std::string logger_name);
0306
0307 protected:
0308 std::string name_;
0309 std::vector<sink_ptr> sinks_;
0310 spdlog::level_t level_{level::info};
0311 spdlog::level_t flush_level_{level::off};
0312 err_handler custom_err_handler_{nullptr};
0313 details::backtracer tracer_;
0314
0315
0316 template <typename... Args>
0317 void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&...args) {
0318 bool log_enabled = should_log(lvl);
0319 bool traceback_enabled = tracer_.enabled();
0320 if (!log_enabled && !traceback_enabled) {
0321 return;
0322 }
0323 SPDLOG_TRY {
0324 memory_buf_t buf;
0325 #ifdef SPDLOG_USE_STD_FORMAT
0326 fmt_lib::vformat_to(std::back_inserter(buf), fmt, fmt_lib::make_format_args(args...));
0327 #else
0328 fmt::vformat_to(fmt::appender(buf), fmt, fmt::make_format_args(args...));
0329 #endif
0330
0331 details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
0332 log_it_(log_msg, log_enabled, traceback_enabled);
0333 }
0334 SPDLOG_LOGGER_CATCH(loc)
0335 }
0336
0337 #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
0338 template <typename... Args>
0339 void log_(source_loc loc, level::level_enum lvl, wstring_view_t fmt, Args &&...args) {
0340 bool log_enabled = should_log(lvl);
0341 bool traceback_enabled = tracer_.enabled();
0342 if (!log_enabled && !traceback_enabled) {
0343 return;
0344 }
0345 SPDLOG_TRY {
0346
0347 wmemory_buf_t wbuf;
0348 fmt_lib::vformat_to(std::back_inserter(wbuf), fmt,
0349 fmt_lib::make_format_args<fmt_lib::wformat_context>(args...));
0350
0351 memory_buf_t buf;
0352 details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf);
0353 details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
0354 log_it_(log_msg, log_enabled, traceback_enabled);
0355 }
0356 SPDLOG_LOGGER_CATCH(loc)
0357 }
0358 #endif
0359
0360
0361
0362 void log_it_(const details::log_msg &log_msg, bool log_enabled, bool traceback_enabled);
0363 virtual void sink_it_(const details::log_msg &msg);
0364 virtual void flush_();
0365 void dump_backtrace_();
0366 bool should_flush_(const details::log_msg &msg);
0367
0368
0369
0370 void err_handler_(const std::string &msg);
0371 };
0372
0373 void swap(logger &a, logger &b);
0374
0375 }
0376
0377 #ifdef SPDLOG_HEADER_ONLY
0378 #include "logger-inl.h"
0379 #endif