From f2305fe5bfb7dbadec37ef350f15cbceba2c4645 Mon Sep 17 00:00:00 2001 From: gabime Date: Thu, 22 Nov 2018 18:47:50 +0200 Subject: [PATCH] Support for source file/line logging --- include/spdlog/common.h | 9 +++ include/spdlog/details/log_msg.h | 7 +- include/spdlog/details/logger_impl.h | 67 ++++++++++++++------ include/spdlog/details/pattern_formatter.h | 74 ++++++++++++++++++++++ include/spdlog/logger.h | 16 +++++ include/spdlog/spdlog.h | 35 ++++++---- 6 files changed, 176 insertions(+), 32 deletions(-) diff --git a/include/spdlog/common.h b/include/spdlog/common.h index 1c1da08b..ee4bc249 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -185,6 +185,15 @@ using filename_t = std::wstring; using filename_t = std::string; #endif + +struct source_loc +{ + SPDLOG_CONSTEXPR source_loc(): filename(""), line(0) {} + SPDLOG_CONSTEXPR source_loc(const char *filename, int line) : filename(filename), line(line) {} + const char* const filename ; + const uint32_t line; +}; + namespace details { // make_unique support for pre c++14 diff --git a/include/spdlog/details/log_msg.h b/include/spdlog/details/log_msg.h index 6244f3a9..56f4729a 100644 --- a/include/spdlog/details/log_msg.h +++ b/include/spdlog/details/log_msg.h @@ -16,7 +16,7 @@ namespace details { struct log_msg { - log_msg(const std::string *loggers_name, level::level_enum lvl, string_view_t view) + log_msg(source_loc loc, const std::string *loggers_name, level::level_enum lvl, string_view_t view) : logger_name(loggers_name) , level(lvl) #ifndef SPDLOG_NO_DATETIME @@ -25,11 +25,15 @@ struct log_msg #ifndef SPDLOG_NO_THREAD_ID , thread_id(os::thread_id()) + , source(loc) , payload(view) #endif { } + log_msg(const std::string *loggers_name, level::level_enum lvl, string_view_t view): + log_msg(source_loc{}, loggers_name, lvl, view){} + log_msg(const log_msg &other) = default; log_msg &operator=(const log_msg &other) = default; @@ -43,6 +47,7 @@ struct log_msg mutable size_t color_range_start{0}; mutable size_t color_range_end{0}; + source_loc source; const string_view_t payload; }; } // namespace details diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index efe6a66a..de2f76ff 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -57,8 +57,9 @@ inline void spdlog::logger::set_pattern(std::string pattern, pattern_time_type t set_formatter(std::move(new_formatter)); } + template -inline void spdlog::logger::log(level::level_enum lvl, const char *fmt, const Args &... args) +inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const char *fmt, const Args &... args) { if (!should_log(lvl)) { @@ -70,13 +71,20 @@ inline void spdlog::logger::log(level::level_enum lvl, const char *fmt, const Ar using details::fmt_helper::to_string_view; fmt::memory_buffer buf; fmt::format_to(buf, fmt, args...); - details::log_msg log_msg(&name_, lvl, to_string_view(buf)); + details::log_msg log_msg(source, &name_, lvl, to_string_view(buf)); sink_it_(log_msg); } SPDLOG_CATCH_AND_HANDLE } -inline void spdlog::logger::log(level::level_enum lvl, const char *msg) + +template +inline void spdlog::logger::log(level::level_enum lvl, const char *fmt, const Args &... args) +{ + log(source_loc{}, lvl, fmt, args...); +} + +inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const char *msg) { if (!should_log(lvl)) { @@ -85,7 +93,27 @@ inline void spdlog::logger::log(level::level_enum lvl, const char *msg) try { - details::log_msg log_msg(&name_, lvl, spdlog::string_view_t(msg)); + details::log_msg log_msg(source, &name_, lvl, spdlog::string_view_t(msg)); + sink_it_(log_msg); + } + SPDLOG_CATCH_AND_HANDLE +} + +inline void spdlog::logger::log(level::level_enum lvl, const char *msg) +{ + log(source_loc{}, lvl, msg); +} + +template::value, T>::type *> +inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const T &msg) +{ + if (!should_log(lvl)) + { + return; + } + try + { + details::log_msg log_msg(source, &name_, lvl, msg); sink_it_(log_msg); } SPDLOG_CATCH_AND_HANDLE @@ -94,20 +122,11 @@ inline void spdlog::logger::log(level::level_enum lvl, const char *msg) template::value, T>::type *> inline void spdlog::logger::log(level::level_enum lvl, const T &msg) { - if (!should_log(lvl)) - { - return; - } - try - { - details::log_msg log_msg(&name_, lvl, msg); - sink_it_(log_msg); - } - SPDLOG_CATCH_AND_HANDLE + log(source_loc{}, lvl, msg); } template::value, T>::type *> -inline void spdlog::logger::log(level::level_enum lvl, const T &msg) +inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const T &msg) { if (!should_log(lvl)) { @@ -118,12 +137,18 @@ inline void spdlog::logger::log(level::level_enum lvl, const T &msg) using details::fmt_helper::to_string_view; fmt::memory_buffer buf; fmt::format_to(buf, "{}", msg); - details::log_msg log_msg(&name_, lvl, to_string_view(buf)); + details::log_msg log_msg(source, &name_, lvl, to_string_view(buf)); sink_it_(log_msg); } SPDLOG_CATCH_AND_HANDLE } +template::value, T>::type *> +inline void spdlog::logger::log(level::level_enum lvl, const T &msg) +{ + log(source_loc{}, lvl, msg); +} + template inline void spdlog::logger::trace(const char *fmt, const Args &... args) { @@ -220,7 +245,7 @@ inline void wbuf_to_utf8buf(const fmt::wmemory_buffer &wbuf, fmt::memory_buffer } template -inline void spdlog::logger::log(level::level_enum lvl, const wchar_t *fmt, const Args &... args) +inline void spdlog::logger::log(source_location source, level::level_enum lvl, const wchar_t *fmt, const Args &... args) { if (!should_log(lvl)) { @@ -235,12 +260,18 @@ inline void spdlog::logger::log(level::level_enum lvl, const wchar_t *fmt, const fmt::format_to(wbuf, fmt, args...); fmt::memory_buffer buf; wbuf_to_utf8buf(wbuf, buf); - details::log_msg log_msg(&name_, lvl, to_string_view(buf)); + details::log_msg log_msg(source, &name_, lvl, to_string_view(buf)); sink_it_(log_msg); } SPDLOG_CATCH_AND_HANDLE } +template +inline void spdlog::logger::log(level::level_enum lvl, const wchar_t *fmt, const Args &... args) +{ + log(source_location{}, lvl, fmt, args...); +} + template inline void spdlog::logger::trace(const wchar_t *fmt, const Args &... args) { diff --git a/include/spdlog/details/pattern_formatter.h b/include/spdlog/details/pattern_formatter.h index 5d71ecf0..044006c5 100644 --- a/include/spdlog/details/pattern_formatter.h +++ b/include/spdlog/details/pattern_formatter.h @@ -808,6 +808,68 @@ public: } }; +// print soruce location +class source_location_formatter final : public flag_formatter +{ +public: + explicit source_location_formatter(padding_info padinfo) + : flag_formatter(padinfo){}; + +void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override +{ + if(padinfo_.width_) + { + const auto text_size = std::char_traits::length(msg.source.filename) + + fmt_helper::count_digits(msg.source.line) + +1; + scoped_pad p(text_size, padinfo_, dest); + fmt_helper::append_string_view(msg.source.filename, dest); + dest.push_back(':'); + fmt_helper::append_int(msg.source.line, dest); + } + else + { + fmt_helper::append_string_view(msg.source.filename, dest); + dest.push_back(':'); + fmt_helper::append_int(msg.source.line, dest); + } +} +}; +// print soruce filename +class source_filename_formatter final : public flag_formatter +{ +public: + explicit source_filename_formatter(padding_info padinfo) + : flag_formatter(padinfo){}; + + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override + { + scoped_pad p(msg.source.filename, padinfo_, dest); + fmt_helper::append_string_view(msg.source.filename, dest); + } +}; + +class source_linenum_formatter final : public flag_formatter +{ +public: + explicit source_linenum_formatter(padding_info padinfo) + : flag_formatter(padinfo){}; + + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override + { + + if(padinfo_.width_) { + const size_t field_size = fmt::internal::count_digits(msg.source.line); + scoped_pad p(field_size, padinfo_, dest); + fmt_helper::append_int(msg.source.line, dest); + } + else + { + fmt_helper::append_int(msg.source.line, dest); + } + } +}; + // Full info formatter // pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v class full_formatter final : public flag_formatter @@ -1102,6 +1164,18 @@ private: formatters_.push_back(details::make_unique(padding)); break; + case ('@'): + formatters_.push_back(details::make_unique(padding)); + break; + + case ('s'): + formatters_.push_back(details::make_unique(padding)); + break; + + case ('#'): + formatters_.push_back(details::make_unique(padding)); + break; + case ('%'): formatters_.push_back(details::make_unique('%')); break; diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index d1da624f..640895a3 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -46,8 +46,13 @@ public: template void log(level::level_enum lvl, const char *fmt, const Args &... args); + template + void log(source_loc loc, level::level_enum lvl, const char *fmt, const Args &... args); + void log(level::level_enum lvl, const char *msg); + void log(source_loc loc, level::level_enum lvl, const char *msg); + template void trace(const char *fmt, const Args &... args); @@ -73,6 +78,9 @@ public: template void log(level::level_enum lvl, const wchar_t *fmt, const Args &... args); + template + void log(source_location soruce, level::level_enum lvl, const wchar_t *fmt, const Args &... args); + template void trace(const wchar_t *fmt, const Args &... args); @@ -97,10 +105,18 @@ public: template::value, T>::type * = nullptr> void log(level::level_enum lvl, const T &); + // T can be statically converted to string_view + template::value, T>::type * = nullptr> + void log(source_loc loc, level::level_enum lvl, const T &); + // T cannot be statically converted to string_view template::value, T>::type * = nullptr> void log(level::level_enum lvl, const T &); + // T cannot be statically converted to string_view + template::value, T>::type * = nullptr> + void log(source_loc loc, level::level_enum lvl, const T &); + template void trace(const T &msg); diff --git a/include/spdlog/spdlog.h b/include/spdlog/spdlog.h index c314c07b..64a53fbe 100644 --- a/include/spdlog/spdlog.h +++ b/include/spdlog/spdlog.h @@ -161,10 +161,16 @@ inline void set_default_logger(std::shared_ptr default_logger) details::registry::instance().set_default_logger(std::move(default_logger)); } +template +inline void log(source_loc source, level::level_enum lvl, const char *fmt, const Args &... args) +{ + default_logger_raw()->log(source, lvl, fmt, args...); +} + template inline void log(level::level_enum lvl, const char *fmt, const Args &... args) { - default_logger_raw()->log(lvl, fmt, args...); + default_logger_raw()->log(source_loc{}, lvl, fmt, args...); } template @@ -303,49 +309,52 @@ inline void critical(const wchar_t *fmt, const Args &... args) // SPDLOG_LEVEL_OFF // + +#define SPDLOG_LOGGER_LOG(logger, level, ...) logger->log(spdlog::source_loc{__FILE__, __LINE__}, level, __VA_ARGS__) + #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE -#define SPDLOG_LOGGER_TRACE(logger, ...) logger->trace(__VA_ARGS__) -#define SPDLOG_TRACE(...) spdlog::trace(__VA_ARGS__) +#define SPDLOG_LOGGER_TRACE(logger, ...) SPDLOG_LOGGER_LOG(logger, spdlog::level::trace, __VA_ARGS__) +#define SPDLOG_TRACE(...) SPDLOG_LOGGER_LOG(spdlog::default_logger_raw(), spdlog::level::trace, __VA_ARGS__) #else #define SPDLOG_LOGGER_TRACE(logger, ...) (void)0 #define SPDLOG_TRACE(...) (void)0 #endif #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG -#define SPDLOG_LOGGER_DEBUG(logger, ...) logger->debug(__VA_ARGS__) -#define SPDLOG_DEBUG(...) spdlog::debug(__VA_ARGS__) +#define SPDLOG_LOGGER_DEBUG(logger, ...) SPDLOG_LOGGER_LOG(logger, spdlog::level::debug, __VA_ARGS__) +#define SPDLOG_DEBUG(...) SPDLOG_LOGGER_LOG(spdlog::default_logger_raw(), spdlog::level::debug, __VA_ARGS__) #else #define SPDLOG_LOGGER_DEBUG(logger, ...) (void)0 #define SPDLOG_DEBUG(...) (void)0 #endif #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_INFO -#define SPDLOG_LOGGER_INFO(logger, ...) logger->info(__VA_ARGS__) -#define SPDLOG_INFO(...) spdlog::info(__VA_ARGS__) +#define SPDLOG_LOGGER_INFO(logger, ...) SPDLOG_LOGGER_LOG(logger, spdlog::level::info, __VA_ARGS__) +#define SPDLOG_INFO(...) SPDLOG_LOGGER_LOG(spdlog::default_logger_raw(), spdlog::level::info, __VA_ARGS__) #else #define SPDLOG_LOGGER_INFO(logger, ...) (void)0 #define SPDLOG_INFO(...) (void)0 #endif #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_WARN -#define SPDLOG_LOGGER_WARN(logger, ...) logger->warn(__VA_ARGS__) -#define SPDLOG_WARN(...) spdlog::warn(__VA_ARGS__) +#define SPDLOG_LOGGER_WARN(logger, ...) SPDLOG_LOGGER_LOG(logger, spdlog::level::warn, __VA_ARGS__) +#define SPDLOG_WARN(...) SPDLOG_LOGGER_LOG(spdlog::default_logger_raw(), spdlog::level::warn, __VA_ARGS__) #else #define SPDLOG_LOGGER_WARN(logger, ...) (void)0 #define SPDLOG_WARN(...) (void)0 #endif #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_ERROR -#define SPDLOG_LOGGER_ERROR(logger, ...) logger->error(__VA_ARGS__) -#define SPDLOG_ERROR(...) spdlog::error(__VA_ARGS__) +#define SPDLOG_LOGGER_ERROR(logger, ...) SPDLOG_LOGGER_LOG(logger, spdlog::level::err, __VA_ARGS__) +#define SPDLOG_ERROR(...) SPDLOG_LOGGER_LOG(spdlog::default_logger_raw(), spdlog::level::err, __VA_ARGS__) #else #define SPDLOG_LOGGER_ERROR(logger, ...) (void)0 #define SPDLOG_ERROR(...) (void)0 #endif #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_CRITICAL -#define SPDLOG_LOGGER_CRITICAL(logger, ...) logger->critical(__VA_ARGS__) -#define SPDLOG_CRITICAL(...) spdlog::critical(__VA_ARGS__) +#define SPDLOG_LOGGER_CRITICAL(logger, ...) SPDLOG_LOGGER_LOG(logger, spdlog::level::critical, __VA_ARGS__) +#define SPDLOG_CRITICAL(...) SPDLOG_LOGGER_LOG(spdlog::default_logger_raw(), spdlog::level::critical, __VA_ARGS__) #else #define SPDLOG_LOGGER_CRITICAL(logger, ...) (void)0 #define SPDLOG_CRITICAL(...) (void)0