clang-format

This commit is contained in:
gabime 2019-04-27 02:34:50 +03:00
parent c1c2ff2d07
commit 2de924a187
17 changed files with 694 additions and 715 deletions

View File

@ -19,7 +19,6 @@
// Upon destruction, logs all remaining messages in the queue before // Upon destruction, logs all remaining messages in the queue before
// destructing.. // destructing..
#include "spdlog/logger.h" #include "spdlog/logger.h"
namespace spdlog { namespace spdlog {
@ -69,5 +68,3 @@ private:
#ifdef SPDLOG_HEADER_ONLY #ifdef SPDLOG_HEADER_ONLY
#include "spdlog/impl/async_logger.cpp" #include "spdlog/impl/async_logger.cpp"
#endif // SPDLOG_HEADER_ONLY #endif // SPDLOG_HEADER_ONLY

View File

@ -70,7 +70,6 @@
#define SPDLOG_FUNCTION __FUNCTION__ #define SPDLOG_FUNCTION __FUNCTION__
#endif #endif
namespace spdlog { namespace spdlog {
class formatter; class formatter;

View File

@ -24,17 +24,17 @@ public:
file_helper(const file_helper &) = delete; file_helper(const file_helper &) = delete;
file_helper &operator=(const file_helper &) = delete; file_helper &operator=(const file_helper &) = delete;
~file_helper(); ~file_helper();
void open(const filename_t &fname, bool truncate = false); void open(const filename_t &fname, bool truncate = false);
void reopen(bool truncate); void reopen(bool truncate);
void flush(); void flush();
void close(); void close();
void write(const fmt::memory_buffer &buf); void write(const fmt::memory_buffer &buf);
size_t size() const; size_t size() const;
const filename_t &filename() const; const filename_t &filename() const;
static bool file_exists(const filename_t &fname); static bool file_exists(const filename_t &fname);
// //
// return file path and its extension: // return file path and its extension:
// //
@ -57,6 +57,6 @@ private:
} // namespace details } // namespace details
} // namespace spdlog } // namespace spdlog
#ifdef SPDLOG_HEADER_ONLY #ifdef SPDLOG_HEADER_ONLY
#include "spdlog/impl/file_helper.cpp" #include "spdlog/impl/file_helper.cpp"
#endif // ! SPDLOG_HEADER_ONLY #endif // ! SPDLOG_HEADER_ONLY

View File

@ -13,7 +13,7 @@ namespace details {
struct log_msg struct log_msg
{ {
log_msg(source_loc loc, 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);
log_msg(const std::string *loggers_name, level::level_enum lvl, string_view_t view); log_msg(const std::string *loggers_name, level::level_enum lvl, string_view_t view);
log_msg(const log_msg &other) = default; log_msg(const log_msg &other) = default;
@ -33,6 +33,6 @@ struct log_msg
} // namespace details } // namespace details
} // namespace spdlog } // namespace spdlog
#ifdef SPDLOG_HEADER_ONLY #ifdef SPDLOG_HEADER_ONLY
#include "spdlog/impl/log_msg.cpp" #include "spdlog/impl/log_msg.cpp"
#endif // SPDLOG_HEADER_ONLY #endif // SPDLOG_HEADER_ONLY

View File

@ -20,7 +20,6 @@
namespace spdlog { namespace spdlog {
namespace details { namespace details {
// padding information. // padding information.
struct padding_info struct padding_info
{ {
@ -61,26 +60,22 @@ protected:
padding_info padinfo_; padding_info padinfo_;
}; };
} } // namespace details
class pattern_formatter final : public formatter class pattern_formatter final : public formatter
{ {
public: public:
explicit pattern_formatter( explicit pattern_formatter(
std::string pattern, std::string pattern, pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol);
pattern_time_type time_type = pattern_time_type::local,
std::string eol = spdlog::details::os::default_eol);
// use default pattern is not given // use default pattern is not given
explicit pattern_formatter( explicit pattern_formatter(pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol);
pattern_time_type time_type = pattern_time_type::local,
std::string eol = spdlog::details::os::default_eol);
pattern_formatter(const pattern_formatter &other) = delete; pattern_formatter(const pattern_formatter &other) = delete;
pattern_formatter &operator=(const pattern_formatter &other) = delete; pattern_formatter &operator=(const pattern_formatter &other) = delete;
std::unique_ptr<formatter> clone() const override; std::unique_ptr<formatter> clone() const override;
void format(const details::log_msg &msg, fmt::memory_buffer &dest) override; void format(const details::log_msg &msg, fmt::memory_buffer &dest) override;
private: private:
std::string pattern_; std::string pattern_;
@ -89,15 +84,15 @@ private:
std::tm cached_tm_; std::tm cached_tm_;
std::chrono::seconds last_log_secs_; std::chrono::seconds last_log_secs_;
std::vector<std::unique_ptr<details::flag_formatter>> formatters_; std::vector<std::unique_ptr<details::flag_formatter>> formatters_;
std::tm get_time_(const details::log_msg &msg); std::tm get_time_(const details::log_msg &msg);
void handle_flag_(char flag, details::padding_info padding); void handle_flag_(char flag, details::padding_info padding);
// Extract given pad spec (e.g. %8X) // Extract given pad spec (e.g. %8X)
// Advance the given it pass the end of the padding spec found (if any) // Advance the given it pass the end of the padding spec found (if any)
// Return padding. // Return padding.
details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end); details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end);
void compile_pattern_(const std::string &pattern); void compile_pattern_(const std::string &pattern);
}; };
} // namespace spdlog } // namespace spdlog

View File

@ -32,59 +32,59 @@ public:
registry(const registry &) = delete; registry(const registry &) = delete;
registry &operator=(const registry &) = delete; registry &operator=(const registry &) = delete;
void register_logger(std::shared_ptr<logger> new_logger); void register_logger(std::shared_ptr<logger> new_logger);
void initialize_logger(std::shared_ptr<logger> new_logger); void initialize_logger(std::shared_ptr<logger> new_logger);
std::shared_ptr<logger> get(const std::string &logger_name); std::shared_ptr<logger> get(const std::string &logger_name);
std::shared_ptr<logger> default_logger(); std::shared_ptr<logger> default_logger();
// Return raw ptr to the default logger. // Return raw ptr to the default logger.
// To be used directly by the spdlog default api (e.g. spdlog::info) // To be used directly by the spdlog default api (e.g. spdlog::info)
// This make the default API faster, but cannot be used concurrently with set_default_logger(). // This make the default API faster, but cannot be used concurrently with set_default_logger().
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another. // e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
logger *get_default_raw(); logger *get_default_raw();
// set default logger. // set default logger.
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map. // default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
void set_default_logger(std::shared_ptr<logger> new_default_logger); void set_default_logger(std::shared_ptr<logger> new_default_logger);
void set_tp(std::shared_ptr<thread_pool> tp); void set_tp(std::shared_ptr<thread_pool> tp);
std::shared_ptr<thread_pool> get_tp(); std::shared_ptr<thread_pool> get_tp();
// Set global formatter. Each sink in each logger will get a clone of this object // Set global formatter. Each sink in each logger will get a clone of this object
void set_formatter(std::unique_ptr<formatter> formatter); void set_formatter(std::unique_ptr<formatter> formatter);
void set_level(level::level_enum log_level); void set_level(level::level_enum log_level);
void flush_on(level::level_enum log_level); void flush_on(level::level_enum log_level);
void flush_every(std::chrono::seconds interval); void flush_every(std::chrono::seconds interval);
void set_error_handler(void (*handler)(const std::string &msg)); void set_error_handler(void (*handler)(const std::string &msg));
void apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun); void apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun);
void flush_all(); void flush_all();
void drop(const std::string &logger_name); void drop(const std::string &logger_name);
void drop_all(); void drop_all();
// clean all resources and threads started by the registry // clean all resources and threads started by the registry
void shutdown(); void shutdown();
std::recursive_mutex &tp_mutex();
std::recursive_mutex &tp_mutex();
void set_automatic_registration(bool automatic_regsistration); void set_automatic_registration(bool automatic_regsistration);
static registry &instance(); static registry &instance();
private: private:
registry(); registry();
~registry() = default; ~registry() = default;
void throw_if_exists_(const std::string &logger_name); void throw_if_exists_(const std::string &logger_name);
void register_logger_(std::shared_ptr<logger> new_logger); void register_logger_(std::shared_ptr<logger> new_logger);
std::mutex logger_map_mutex_, flusher_mutex_; std::mutex logger_map_mutex_, flusher_mutex_;
std::recursive_mutex tp_mutex_; std::recursive_mutex tp_mutex_;
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_; std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;

View File

@ -2,7 +2,6 @@
#include "spdlog/async_logger.h" #include "spdlog/async_logger.h"
#endif #endif
// async logger implementation // async logger implementation
// uses a thread pool to perform the actual logging // uses a thread pool to perform the actual logging
@ -15,22 +14,22 @@
template<typename It> template<typename It>
SPDLOG_INLINE spdlog::async_logger::async_logger( SPDLOG_INLINE spdlog::async_logger::async_logger(
std::string logger_name, It begin, It end, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy) std::string logger_name, It begin, It end, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy)
: logger(std::move(logger_name), begin, end) : logger(std::move(logger_name), begin, end)
, thread_pool_(std::move(tp)) , thread_pool_(std::move(tp))
, overflow_policy_(overflow_policy) , overflow_policy_(overflow_policy)
{ {
} }
SPDLOG_INLINE spdlog::async_logger::async_logger( SPDLOG_INLINE spdlog::async_logger::async_logger(
std::string logger_name, sinks_init_list sinks_list, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy) std::string logger_name, sinks_init_list sinks_list, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy)
: async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy) : async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy)
{ {
} }
SPDLOG_INLINE spdlog::async_logger::async_logger( SPDLOG_INLINE spdlog::async_logger::async_logger(
std::string logger_name, sink_ptr single_sink, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy) std::string logger_name, sink_ptr single_sink, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy)
: async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy) : async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy)
{ {
} }
@ -118,6 +117,3 @@ SPDLOG_INLINE std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::s
cloned->set_error_handler(this->custom_err_handler_); cloned->set_error_handler(this->custom_err_handler_);
return std::move(cloned); return std::move(cloned);
} }

View File

@ -17,116 +17,115 @@
#include <tuple> #include <tuple>
namespace spdlog { namespace spdlog {
namespace details namespace details {
SPDLOG_INLINE file_helper::~file_helper()
{ {
SPDLOG_INLINE file_helper::~file_helper() close();
{ }
close();
}
SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate) SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate)
{
close();
auto *mode = truncate ? SPDLOG_FILENAME_T("wb") : SPDLOG_FILENAME_T("ab");
_filename = fname;
for (int tries = 0; tries < open_tries; ++tries)
{ {
close(); if (!os::fopen_s(&fd_, fname, mode))
auto *mode = truncate ? SPDLOG_FILENAME_T("wb") : SPDLOG_FILENAME_T("ab");
_filename = fname;
for (int tries = 0; tries < open_tries; ++tries)
{ {
if (!os::fopen_s(&fd_, fname, mode)) return;
{
return;
}
details::os::sleep_for_millis(open_interval);
} }
throw spdlog_ex("Failed opening file " + os::filename_to_str(_filename) + " for writing", errno); details::os::sleep_for_millis(open_interval);
} }
SPDLOG_INLINE void file_helper::reopen(bool truncate) throw spdlog_ex("Failed opening file " + os::filename_to_str(_filename) + " for writing", errno);
}
SPDLOG_INLINE void file_helper::reopen(bool truncate)
{
if (_filename.empty())
{ {
if (_filename.empty()) throw spdlog_ex("Failed re opening file - was not opened before");
{
throw spdlog_ex("Failed re opening file - was not opened before");
}
open(_filename, truncate);
} }
open(_filename, truncate);
}
SPDLOG_INLINE void file_helper::flush() SPDLOG_INLINE void file_helper::flush()
{
std::fflush(fd_);
}
SPDLOG_INLINE void file_helper::close()
{
if (fd_ != nullptr)
{ {
std::fflush(fd_); std::fclose(fd_);
fd_ = nullptr;
} }
}
SPDLOG_INLINE void file_helper::close() SPDLOG_INLINE void file_helper::write(const fmt::memory_buffer &buf)
{
size_t msg_size = buf.size();
auto data = buf.data();
if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
{ {
if (fd_ != nullptr) throw spdlog_ex("Failed writing to file " + os::filename_to_str(_filename), errno);
{
std::fclose(fd_);
fd_ = nullptr;
}
} }
}
SPDLOG_INLINE void file_helper::write(const fmt::memory_buffer &buf) SPDLOG_INLINE size_t file_helper::size() const
{
if (fd_ == nullptr)
{ {
size_t msg_size = buf.size(); throw spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(_filename));
auto data = buf.data();
if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
{
throw spdlog_ex("Failed writing to file " + os::filename_to_str(_filename), errno);
}
} }
return os::filesize(fd_);
}
SPDLOG_INLINE size_t file_helper::size() const SPDLOG_INLINE const filename_t &file_helper::filename() const
{
return _filename;
}
SPDLOG_INLINE bool file_helper::file_exists(const filename_t &fname)
{
return os::file_exists(fname);
}
//
// return file path and its extension:
//
// "mylog.txt" => ("mylog", ".txt")
// "mylog" => ("mylog", "")
// "mylog." => ("mylog.", "")
// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
//
// the starting dot in filenames is ignored (hidden files):
//
// ".mylog" => (".mylog". "")
// "my_folder/.mylog" => ("my_folder/.mylog", "")
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
SPDLOG_INLINE std::tuple<filename_t, filename_t> file_helper::split_by_extension(const filename_t &fname)
{
auto ext_index = fname.rfind('.');
// no valid extension found - return whole path and empty string as
// extension
if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1)
{ {
if (fd_ == nullptr) return std::make_tuple(fname, filename_t());
{
throw spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(_filename));
}
return os::filesize(fd_);
} }
SPDLOG_INLINE const filename_t &file_helper::filename() const // treat casese like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
auto folder_index = fname.rfind(details::os::folder_sep);
if (folder_index != filename_t::npos && folder_index >= ext_index - 1)
{ {
return _filename; return std::make_tuple(fname, filename_t());
} }
SPDLOG_INLINE bool file_helper::file_exists(const filename_t &fname) // finally - return a valid base and extension tuple
{ return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
return os::file_exists(fname); }
}
//
// return file path and its extension:
//
// "mylog.txt" => ("mylog", ".txt")
// "mylog" => ("mylog", "")
// "mylog." => ("mylog.", "")
// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
//
// the starting dot in filenames is ignored (hidden files):
//
// ".mylog" => (".mylog". "")
// "my_folder/.mylog" => ("my_folder/.mylog", "")
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
SPDLOG_INLINE std::tuple<filename_t, filename_t> file_helper::split_by_extension(const filename_t &fname)
{
auto ext_index = fname.rfind('.');
// no valid extension found - return whole path and empty string as
// extension
if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1)
{
return std::make_tuple(fname, filename_t());
}
// treat casese like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
auto folder_index = fname.rfind(details::os::folder_sep);
if (folder_index != filename_t::npos && folder_index >= ext_index - 1)
{
return std::make_tuple(fname, filename_t());
}
// finally - return a valid base and extension tuple
return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
}
} // namespace details } // namespace details
} // namespace spdlog } // namespace spdlog

View File

@ -1,12 +1,10 @@
#include "spdlog/details/os.h" #include "spdlog/details/os.h"
#include "spdlog/sinks/sink.h" #include "spdlog/sinks/sink.h"
#ifndef SPDLOG_HEADER_ONLY #ifndef SPDLOG_HEADER_ONLY
#include "spdlog/details/log_msg.h" #include "spdlog/details/log_msg.h"
#endif #endif
SPDLOG_INLINE spdlog::details::log_msg::log_msg( SPDLOG_INLINE spdlog::details::log_msg::log_msg(
spdlog::source_loc loc, const std::string *loggers_name, spdlog::level::level_enum lvl, spdlog::string_view_t view) spdlog::source_loc loc, const std::string *loggers_name, spdlog::level::level_enum lvl, spdlog::string_view_t view)
: logger_name(loggers_name) : logger_name(loggers_name)

View File

@ -160,11 +160,11 @@ SPDLOG_INLINE bool spdlog::logger::should_flush_(const spdlog::details::log_msg
} }
SPDLOG_INLINE void spdlog::logger::err_handler_(const std::string &msg) SPDLOG_INLINE void spdlog::logger::err_handler_(const std::string &msg)
{ {
if (custom_err_handler_) if (custom_err_handler_)
{ {
custom_err_handler_(msg); custom_err_handler_(msg);
} }
else else
{ {
auto tm_time = spdlog::details::os::localtime(); auto tm_time = spdlog::details::os::localtime();

View File

@ -959,308 +959,304 @@ private:
} // namespace details } // namespace details
SPDLOG_INLINE pattern_formatter::pattern_formatter(std::string pattern, pattern_time_type time_type, std::string eol)
: pattern_(std::move(pattern))
, eol_(std::move(eol))
, pattern_time_type_(time_type)
, last_log_secs_(0)
{
std::memset(&cached_tm_, 0, sizeof(cached_tm_));
compile_pattern_(pattern_);
}
SPDLOG_INLINE pattern_formatter::pattern_formatter( // use by default full formatter for if pattern is not given
std::string pattern, pattern_time_type time_type, std::string eol) SPDLOG_INLINE pattern_formatter::pattern_formatter(pattern_time_type time_type, std::string eol)
: pattern_(std::move(pattern)) : pattern_("%+")
, eol_(std::move(eol)) , eol_(std::move(eol))
, pattern_time_type_(time_type) , pattern_time_type_(time_type)
, last_log_secs_(0) , last_log_secs_(0)
{ {
std::memset(&cached_tm_, 0, sizeof(cached_tm_)); std::memset(&cached_tm_, 0, sizeof(cached_tm_));
compile_pattern_(pattern_); formatters_.push_back(details::make_unique<details::full_formatter>(details::padding_info{}));
} }
// use by default full formatter for if pattern is not given SPDLOG_INLINE std::unique_ptr<formatter> pattern_formatter::clone() const
SPDLOG_INLINE pattern_formatter::pattern_formatter(pattern_time_type time_type, std::string eol) {
: pattern_("%+") return details::make_unique<pattern_formatter>(pattern_, pattern_time_type_, eol_);
, eol_(std::move(eol)) }
, pattern_time_type_(time_type)
, last_log_secs_(0)
{
std::memset(&cached_tm_, 0, sizeof(cached_tm_));
formatters_.push_back(details::make_unique<details::full_formatter>(details::padding_info{}));
}
SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, fmt::memory_buffer &dest)
SPDLOG_INLINE std::unique_ptr<formatter> pattern_formatter::clone() const {
{
return details::make_unique<pattern_formatter>(pattern_, pattern_time_type_, eol_);
}
SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, fmt::memory_buffer &dest)
{
#ifndef SPDLOG_NO_DATETIME #ifndef SPDLOG_NO_DATETIME
auto secs = std::chrono::duration_cast<std::chrono::seconds>(msg.time.time_since_epoch()); auto secs = std::chrono::duration_cast<std::chrono::seconds>(msg.time.time_since_epoch());
if (secs != last_log_secs_) if (secs != last_log_secs_)
{ {
cached_tm_ = get_time_(msg); cached_tm_ = get_time_(msg);
last_log_secs_ = secs; last_log_secs_ = secs;
} }
#endif #endif
for (auto &f : formatters_) for (auto &f : formatters_)
{ {
f->format(msg, cached_tm_, dest); f->format(msg, cached_tm_, dest);
} }
// write eol // write eol
details::fmt_helper::append_string_view(eol_, dest); details::fmt_helper::append_string_view(eol_, dest);
}
SPDLOG_INLINE std::tm pattern_formatter::get_time_(const details::log_msg &msg)
{
if (pattern_time_type_ == pattern_time_type::local)
{
return details::os::localtime(log_clock::to_time_t(msg.time));
}
return details::os::gmtime(log_clock::to_time_t(msg.time));
}
SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_info padding)
{
switch (flag)
{
case ('+'): // default formatter
formatters_.push_back(details::make_unique<details::full_formatter>(padding));
break;
case 'n': // logger name
formatters_.push_back(details::make_unique<details::name_formatter>(padding));
break;
case 'l': // level
formatters_.push_back(details::make_unique<details::level_formatter>(padding));
break;
case 'L': // short level
formatters_.push_back(details::make_unique<details::short_level_formatter>(padding));
break;
case ('t'): // thread id
formatters_.push_back(details::make_unique<details::t_formatter>(padding));
break;
case ('v'): // the message text
formatters_.push_back(details::make_unique<details::v_formatter>(padding));
break;
case ('a'): // weekday
formatters_.push_back(details::make_unique<details::a_formatter>(padding));
break;
case ('A'): // short weekday
formatters_.push_back(details::make_unique<details::A_formatter>(padding));
break;
case ('b'):
case ('h'): // month
formatters_.push_back(details::make_unique<details::b_formatter>(padding));
break;
case ('B'): // short month
formatters_.push_back(details::make_unique<details::B_formatter>(padding));
break;
case ('c'): // datetime
formatters_.push_back(details::make_unique<details::c_formatter>(padding));
break;
case ('C'): // year 2 digits
formatters_.push_back(details::make_unique<details::C_formatter>(padding));
break;
case ('Y'): // year 4 digits
formatters_.push_back(details::make_unique<details::Y_formatter>(padding));
break;
case ('D'):
case ('x'): // datetime MM/DD/YY
formatters_.push_back(details::make_unique<details::D_formatter>(padding));
break;
case ('m'): // month 1-12
formatters_.push_back(details::make_unique<details::m_formatter>(padding));
break;
case ('d'): // day of month 1-31
formatters_.push_back(details::make_unique<details::d_formatter>(padding));
break;
case ('H'): // hours 24
formatters_.push_back(details::make_unique<details::H_formatter>(padding));
break;
case ('I'): // hours 12
formatters_.push_back(details::make_unique<details::I_formatter>(padding));
break;
case ('M'): // minutes
formatters_.push_back(details::make_unique<details::M_formatter>(padding));
break;
case ('S'): // seconds
formatters_.push_back(details::make_unique<details::S_formatter>(padding));
break;
case ('e'): // milliseconds
formatters_.push_back(details::make_unique<details::e_formatter>(padding));
break;
case ('f'): // microseconds
formatters_.push_back(details::make_unique<details::f_formatter>(padding));
break;
case ('F'): // nanoseconds
formatters_.push_back(details::make_unique<details::F_formatter>(padding));
break;
case ('E'): // seconds since epoch
formatters_.push_back(details::make_unique<details::E_formatter>(padding));
break;
case ('p'): // am/pm
formatters_.push_back(details::make_unique<details::p_formatter>(padding));
break;
case ('r'): // 12 hour clock 02:55:02 pm
formatters_.push_back(details::make_unique<details::r_formatter>(padding));
break;
case ('R'): // 24-hour HH:MM time
formatters_.push_back(details::make_unique<details::R_formatter>(padding));
break;
case ('T'):
case ('X'): // ISO 8601 time format (HH:MM:SS)
formatters_.push_back(details::make_unique<details::T_formatter>(padding));
break;
case ('z'): // timezone
formatters_.push_back(details::make_unique<details::z_formatter>(padding));
break;
case ('P'): // pid
formatters_.push_back(details::make_unique<details::pid_formatter>(padding));
break;
case ('^'): // color range start
formatters_.push_back(details::make_unique<details::color_start_formatter>(padding));
break;
case ('$'): // color range end
formatters_.push_back(details::make_unique<details::color_stop_formatter>(padding));
break;
case ('@'): // source location (filename:filenumber)
formatters_.push_back(details::make_unique<details::source_location_formatter>(padding));
break;
case ('s'): // source filename
formatters_.push_back(details::make_unique<details::source_filename_formatter>(padding));
break;
case ('#'): // source line number
formatters_.push_back(details::make_unique<details::source_linenum_formatter>(padding));
break;
case ('!'): // source funcname
formatters_.push_back(details::make_unique<details::source_funcname_formatter>(padding));
break;
case ('%'): // % char
formatters_.push_back(details::make_unique<details::ch_formatter>('%'));
break;
default: // Unknown flag appears as is
auto unknown_flag = details::make_unique<details::aggregate_formatter>();
unknown_flag->add_ch('%');
unknown_flag->add_ch(flag);
formatters_.push_back((std::move(unknown_flag)));
break;
}
}
// Extract given pad spec (e.g. %8X)
// Advance the given it pass the end of the padding spec found (if any)
// Return padding.
SPDLOG_INLINE details::padding_info pattern_formatter::handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end)
{
using details::padding_info;
using details::scoped_pad;
const size_t max_width = 128;
if (it == end)
{
return padding_info{};
} }
SPDLOG_INLINE std::tm pattern_formatter::get_time_(const details::log_msg &msg) padding_info::pad_side side;
switch (*it)
{ {
if (pattern_time_type_ == pattern_time_type::local) case '-':
{ side = padding_info::right;
return details::os::localtime(log_clock::to_time_t(msg.time)); ++it;
} break;
return details::os::gmtime(log_clock::to_time_t(msg.time)); case '=':
side = padding_info::center;
++it;
break;
default:
side = details::padding_info::left;
break;
} }
SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_info padding) if (it == end || !std::isdigit(static_cast<unsigned char>(*it)))
{ {
switch (flag) return padding_info{0, side};
{
case ('+'): // default formatter
formatters_.push_back(details::make_unique<details::full_formatter>(padding));
break;
case 'n': // logger name
formatters_.push_back(details::make_unique<details::name_formatter>(padding));
break;
case 'l': // level
formatters_.push_back(details::make_unique<details::level_formatter>(padding));
break;
case 'L': // short level
formatters_.push_back(details::make_unique<details::short_level_formatter>(padding));
break;
case ('t'): // thread id
formatters_.push_back(details::make_unique<details::t_formatter>(padding));
break;
case ('v'): // the message text
formatters_.push_back(details::make_unique<details::v_formatter>(padding));
break;
case ('a'): // weekday
formatters_.push_back(details::make_unique<details::a_formatter>(padding));
break;
case ('A'): // short weekday
formatters_.push_back(details::make_unique<details::A_formatter>(padding));
break;
case ('b'):
case ('h'): // month
formatters_.push_back(details::make_unique<details::b_formatter>(padding));
break;
case ('B'): // short month
formatters_.push_back(details::make_unique<details::B_formatter>(padding));
break;
case ('c'): // datetime
formatters_.push_back(details::make_unique<details::c_formatter>(padding));
break;
case ('C'): // year 2 digits
formatters_.push_back(details::make_unique<details::C_formatter>(padding));
break;
case ('Y'): // year 4 digits
formatters_.push_back(details::make_unique<details::Y_formatter>(padding));
break;
case ('D'):
case ('x'): // datetime MM/DD/YY
formatters_.push_back(details::make_unique<details::D_formatter>(padding));
break;
case ('m'): // month 1-12
formatters_.push_back(details::make_unique<details::m_formatter>(padding));
break;
case ('d'): // day of month 1-31
formatters_.push_back(details::make_unique<details::d_formatter>(padding));
break;
case ('H'): // hours 24
formatters_.push_back(details::make_unique<details::H_formatter>(padding));
break;
case ('I'): // hours 12
formatters_.push_back(details::make_unique<details::I_formatter>(padding));
break;
case ('M'): // minutes
formatters_.push_back(details::make_unique<details::M_formatter>(padding));
break;
case ('S'): // seconds
formatters_.push_back(details::make_unique<details::S_formatter>(padding));
break;
case ('e'): // milliseconds
formatters_.push_back(details::make_unique<details::e_formatter>(padding));
break;
case ('f'): // microseconds
formatters_.push_back(details::make_unique<details::f_formatter>(padding));
break;
case ('F'): // nanoseconds
formatters_.push_back(details::make_unique<details::F_formatter>(padding));
break;
case ('E'): // seconds since epoch
formatters_.push_back(details::make_unique<details::E_formatter>(padding));
break;
case ('p'): // am/pm
formatters_.push_back(details::make_unique<details::p_formatter>(padding));
break;
case ('r'): // 12 hour clock 02:55:02 pm
formatters_.push_back(details::make_unique<details::r_formatter>(padding));
break;
case ('R'): // 24-hour HH:MM time
formatters_.push_back(details::make_unique<details::R_formatter>(padding));
break;
case ('T'):
case ('X'): // ISO 8601 time format (HH:MM:SS)
formatters_.push_back(details::make_unique<details::T_formatter>(padding));
break;
case ('z'): // timezone
formatters_.push_back(details::make_unique<details::z_formatter>(padding));
break;
case ('P'): // pid
formatters_.push_back(details::make_unique<details::pid_formatter>(padding));
break;
case ('^'): // color range start
formatters_.push_back(details::make_unique<details::color_start_formatter>(padding));
break;
case ('$'): // color range end
formatters_.push_back(details::make_unique<details::color_stop_formatter>(padding));
break;
case ('@'): // source location (filename:filenumber)
formatters_.push_back(details::make_unique<details::source_location_formatter>(padding));
break;
case ('s'): // source filename
formatters_.push_back(details::make_unique<details::source_filename_formatter>(padding));
break;
case ('#'): // source line number
formatters_.push_back(details::make_unique<details::source_linenum_formatter>(padding));
break;
case ('!'): // source funcname
formatters_.push_back(details::make_unique<details::source_funcname_formatter>(padding));
break;
case ('%'): // % char
formatters_.push_back(details::make_unique<details::ch_formatter>('%'));
break;
default: // Unknown flag appears as is
auto unknown_flag = details::make_unique<details::aggregate_formatter>();
unknown_flag->add_ch('%');
unknown_flag->add_ch(flag);
formatters_.push_back((std::move(unknown_flag)));
break;
}
} }
// Extract given pad spec (e.g. %8X) auto width = static_cast<size_t>(*it - '0');
// Advance the given it pass the end of the padding spec found (if any) for (++it; it != end && std::isdigit(static_cast<unsigned char>(*it)); ++it)
// Return padding.
SPDLOG_INLINE details::padding_info pattern_formatter::handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end)
{ {
using details::padding_info; auto digit = static_cast<size_t>(*it - '0');
using details::scoped_pad; width = width * 10 + digit;
const size_t max_width = 128;
if (it == end)
{
return padding_info{};
}
padding_info::pad_side side;
switch (*it)
{
case '-':
side = padding_info::right;
++it;
break;
case '=':
side = padding_info::center;
++it;
break;
default:
side = details::padding_info::left;
break;
}
if (it == end || !std::isdigit(static_cast<unsigned char>(*it)))
{
return padding_info{0, side};
}
auto width = static_cast<size_t>(*it - '0');
for (++it; it != end && std::isdigit(static_cast<unsigned char>(*it)); ++it)
{
auto digit = static_cast<size_t>(*it - '0');
width = width * 10 + digit;
}
return details::padding_info{std::min<size_t>(width, max_width), side};
} }
return details::padding_info{std::min<size_t>(width, max_width), side};
}
SPDLOG_INLINE void pattern_formatter::compile_pattern_(const std::string &pattern) SPDLOG_INLINE void pattern_formatter::compile_pattern_(const std::string &pattern)
{
auto end = pattern.end();
std::unique_ptr<details::aggregate_formatter> user_chars;
formatters_.clear();
for (auto it = pattern.begin(); it != end; ++it)
{ {
auto end = pattern.end(); if (*it == '%')
std::unique_ptr<details::aggregate_formatter> user_chars;
formatters_.clear();
for (auto it = pattern.begin(); it != end; ++it)
{ {
if (*it == '%') if (user_chars) // append user chars found so far
{ {
if (user_chars) // append user chars found so far formatters_.push_back(std::move(user_chars));
{
formatters_.push_back(std::move(user_chars));
}
auto padding = handle_padspec_(++it, end);
if (it != end)
{
handle_flag_(*it, padding);
}
else
{
break;
}
} }
else // chars not following the % sign should be displayed as is
auto padding = handle_padspec_(++it, end);
if (it != end)
{ {
if (!user_chars) handle_flag_(*it, padding);
{ }
user_chars = details::make_unique<details::aggregate_formatter>(); else
} {
user_chars->add_ch(*it); break;
} }
} }
if (user_chars) // append raw chars found so far else // chars not following the % sign should be displayed as is
{ {
formatters_.push_back(std::move(user_chars)); if (!user_chars)
{
user_chars = details::make_unique<details::aggregate_formatter>();
}
user_chars->add_ch(*it);
} }
} }
if (user_chars) // append raw chars found so far
{
formatters_.push_back(std::move(user_chars));
}
}
} // namespace spdlog } // namespace spdlog

View File

@ -6,7 +6,6 @@
#include "spdlog/details/registry.h" #include "spdlog/details/registry.h"
#endif #endif
#include "spdlog/common.h" #include "spdlog/common.h"
#include "spdlog/details/periodic_worker.h" #include "spdlog/details/periodic_worker.h"
#include "spdlog/logger.h" #include "spdlog/logger.h"

View File

@ -1,29 +1,31 @@
#include "spdlog/common.h" #include "spdlog/common.h"
#include "spdlog/details/pattern_formatter.h" #include "spdlog/details/pattern_formatter.h"
#ifndef SPDLOG_HEADER_ONLY #ifndef SPDLOG_HEADER_ONLY
#include "spdlog/sinks/sink.h" #include "spdlog/sinks/sink.h"
#endif #endif
SPDLOG_INLINE spdlog::sinks::sink::sink() SPDLOG_INLINE spdlog::sinks::sink::sink()
: formatter_{details::make_unique<spdlog::pattern_formatter>()} : formatter_{details::make_unique<spdlog::pattern_formatter>()}
{} {
}
SPDLOG_INLINE spdlog::sinks::sink::sink(std::unique_ptr<spdlog::formatter> formatter)
: formatter_{std::move(formatter)} SPDLOG_INLINE spdlog::sinks::sink::sink(std::unique_ptr<spdlog::formatter> formatter)
{} : formatter_{std::move(formatter)}
{
SPDLOG_INLINE bool spdlog::sinks::sink::should_log(spdlog::level::level_enum msg_level) const }
{
return msg_level >= level_.load(std::memory_order_relaxed); SPDLOG_INLINE bool spdlog::sinks::sink::should_log(spdlog::level::level_enum msg_level) const
} {
return msg_level >= level_.load(std::memory_order_relaxed);
SPDLOG_INLINE void spdlog::sinks::sink::set_level(level::level_enum log_level) }
{
level_.store(log_level); SPDLOG_INLINE void spdlog::sinks::sink::set_level(level::level_enum log_level)
} {
level_.store(log_level);
SPDLOG_INLINE spdlog::level::level_enum spdlog::sinks::sink::level() const }
{
return static_cast<spdlog::level::level_enum>(level_.load(std::memory_order_relaxed)); SPDLOG_INLINE spdlog::level::level_enum spdlog::sinks::sink::level() const
} {
return static_cast<spdlog::level::level_enum>(level_.load(std::memory_order_relaxed));
}

View File

@ -33,313 +33,310 @@ namespace spdlog {
class logger class logger
{ {
public: public:
template<typename It> template<typename It>
logger(std::string name, It begin, It end) logger(std::string name, It begin, It end)
: name_(std::move(name)) : name_(std::move(name))
, sinks_(begin, end) , sinks_(begin, end)
{
}
logger(std::string name, sink_ptr single_sink)
: logger(std::move(name), {std::move(single_sink)})
{
}
logger(std::string name, sinks_init_list sinks)
: logger(std::move(name), sinks.begin(), sinks.end())
{
}
virtual ~logger() = default;
logger(const logger &) = delete;
logger &operator=(const logger &) = delete;
template<typename... Args>
void log(source_loc loc, level::level_enum lvl, const char *fmt, const Args &... args)
{
if (!should_log(lvl))
{ {
return;
} }
logger(std::string name, sink_ptr single_sink) try
: logger(std::move(name), {std::move(single_sink)})
{ {
fmt::memory_buffer buf;
fmt::format_to(buf, fmt, args...);
details::log_msg log_msg(loc, &name_, lvl, string_view_t(buf.data(), buf.size()));
sink_it_(log_msg);
} }
logger(std::string name, sinks_init_list sinks) catch (const std::exception &ex)
: logger(std::move(name), sinks.begin(), sinks.end())
{ {
err_handler_(ex.what());
} }
catch (...)
virtual ~logger() = default;
logger(const logger &) = delete;
logger &operator=(const logger &) = delete;
template<typename... Args>
void log(source_loc loc, level::level_enum lvl, const char *fmt, const Args &... args)
{ {
if (!should_log(lvl)) err_handler_("Unknown exception in logger");
{
return;
}
try
{
fmt::memory_buffer buf;
fmt::format_to(buf, fmt, args...);
details::log_msg log_msg(loc, &name_, lvl, string_view_t(buf.data(), buf.size()));
sink_it_(log_msg);
}
catch (const std::exception &ex)
{
err_handler_(ex.what());
}
catch (...)
{
err_handler_("Unknown exception in logger");
}
} }
}
template<typename... Args> template<typename... Args>
void log(level::level_enum lvl, const char *fmt, const Args &... args) void log(level::level_enum lvl, const char *fmt, const Args &... args)
{
log(source_loc{}, lvl, fmt, args...);
}
void log(source_loc loc, level::level_enum lvl, const char *msg);
void log(level::level_enum lvl, const char *msg);
template<typename... Args>
void trace(const char *fmt, const Args &... args)
{
log(level::trace, fmt, args...);
}
template<typename... Args>
void debug(const char *fmt, const Args &... args)
{
log(level::debug, fmt, args...);
}
template<typename... Args>
void info(const char *fmt, const Args &... args)
{
log(level::info, fmt, args...);
}
template<typename... Args>
void warn(const char *fmt, const Args &... args)
{
log(level::warn, fmt, args...);
}
template<typename... Args>
void error(const char *fmt, const Args &... args)
{
log(level::err, fmt, args...);
}
template<typename... Args>
void critical(const char *fmt, const Args &... args)
{
log(level::critical, fmt, args...);
}
template<typename T>
void log(level::level_enum lvl, const T &msg)
{
log(source_loc{}, lvl, msg);
}
// T can be statically converted to string_view
template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr>
void log(source_loc loc, level::level_enum lvl, const T &msg)
{
if (!should_log(lvl))
{ {
log(source_loc{}, lvl, fmt, args...); return;
} }
try
void log(source_loc loc, level::level_enum lvl, const char *msg);
void log(level::level_enum lvl, const char *msg);
template<typename... Args>
void trace(const char *fmt, const Args &... args)
{ {
log(level::trace, fmt, args...); details::log_msg log_msg(loc, &name_, lvl, msg);
sink_it_(log_msg);
} }
catch (const std::exception &ex)
template<typename... Args>
void debug(const char *fmt, const Args &... args)
{ {
log(level::debug, fmt, args...); err_handler_(ex.what());
} }
catch (...)
template<typename... Args>
void info(const char *fmt, const Args &... args)
{ {
log(level::info, fmt, args...); err_handler_("Unknown exception in logger");
} }
}
template<typename... Args> // T cannot be statically converted to string_view
void warn(const char *fmt, const Args &... args) template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr>
void log(source_loc loc, level::level_enum lvl, const T &msg)
{
if (!should_log(lvl))
{ {
log(level::warn, fmt, args...); return;
} }
try
template<typename... Args>
void error(const char *fmt, const Args &... args)
{ {
log(level::err, fmt, args...); fmt::memory_buffer buf;
fmt::format_to(buf, "{}", msg);
details::log_msg log_msg(loc, &name_, lvl, string_view_t(buf.data(), buf.size()));
sink_it_(log_msg);
} }
catch (const std::exception &ex)
template<typename... Args>
void critical(const char *fmt, const Args &... args)
{ {
log(level::critical, fmt, args...); err_handler_(ex.what());
} }
catch (...)
template<typename T>
void log(level::level_enum lvl, const T &msg)
{ {
log(source_loc{}, lvl, msg); err_handler_("Unknown exception in logger");
} }
}
// T can be statically converted to string_view template<typename T>
template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr> void trace(const T &msg)
void log(source_loc loc, level::level_enum lvl, const T &msg) {
{ log(level::trace, msg);
if (!should_log(lvl)) }
{
return;
}
try
{
details::log_msg log_msg(loc, &name_, lvl, msg);
sink_it_(log_msg);
}
catch (const std::exception &ex)
{
err_handler_(ex.what());
}
catch (...)
{
err_handler_("Unknown exception in logger");
}
}
// T cannot be statically converted to string_view template<typename T>
template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr> void debug(const T &msg)
void log(source_loc loc, level::level_enum lvl, const T &msg) {
{ log(level::debug, msg);
if (!should_log(lvl)) }
{
return;
}
try
{
fmt::memory_buffer buf;
fmt::format_to(buf, "{}", msg);
details::log_msg log_msg(loc, &name_, lvl, string_view_t(buf.data(), buf.size()));
sink_it_(log_msg);
}
catch (const std::exception &ex)
{
err_handler_(ex.what());
}
catch (...)
{
err_handler_("Unknown exception in logger");
}
}
template<typename T> template<typename T>
void trace(const T &msg) void info(const T &msg)
{ {
log(level::trace, msg); log(level::info, msg);
} }
template<typename T> template<typename T>
void debug(const T &msg) void warn(const T &msg)
{ {
log(level::debug, msg); log(level::warn, msg);
} }
template<typename T> template<typename T>
void info(const T &msg) void error(const T &msg)
{ {
log(level::info, msg); log(level::err, msg);
} }
template<typename T> template<typename T>
void warn(const T &msg) void critical(const T &msg)
{ {
log(level::warn, msg); log(level::critical, msg);
} }
template<typename T>
void error(const T &msg)
{
log(level::err, msg);
}
template<typename T>
void critical(const T &msg)
{
log(level::critical, msg);
}
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
#ifndef _WIN32 #ifndef _WIN32
#error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows #error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows
#else #else
template<typename... Args> template<typename... Args>
void log(source_loc source, level::level_enum lvl, const wchar_t *fmt, const Args &... args) void log(source_loc source, level::level_enum lvl, const wchar_t *fmt, const Args &... args)
{
if (!should_log(lvl))
{ {
if (!should_log(lvl)) return;
{
return;
}
try
{
// format to wmemory_buffer and convert to utf8
fmt::wmemory_buffer wbuf;
fmt::format_to(wbuf, fmt, args...);
fmt::memory_buffer buf;
details::os::wbuf_to_utf8buf(wbuf, buf);
details::log_msg log_msg(source, &name_, lvl, string_view_t(buf.data(), buf.size()));
sink_it_(log_msg);
}
catch (const std::exception &ex)
{
err_handler_(ex.what());
}
catch (...)
{
err_handler_("Unknown exception in logger");
}
} }
template<typename... Args> try
void log(level::level_enum lvl, const wchar_t *fmt, const Args &... args)
{ {
log(source_loc{}, lvl, fmt, args...); // format to wmemory_buffer and convert to utf8
fmt::wmemory_buffer wbuf;
fmt::format_to(wbuf, fmt, args...);
fmt::memory_buffer buf;
details::os::wbuf_to_utf8buf(wbuf, buf);
details::log_msg log_msg(source, &name_, lvl, string_view_t(buf.data(), buf.size()));
sink_it_(log_msg);
} }
catch (const std::exception &ex)
{
err_handler_(ex.what());
}
catch (...)
{
err_handler_("Unknown exception in logger");
}
}
template<typename... Args> template<typename... Args>
void trace(const wchar_t *fmt, const Args &... args) void log(level::level_enum lvl, const wchar_t *fmt, const Args &... args)
{ {
log(level::trace, fmt, args...); log(source_loc{}, lvl, fmt, args...);
} }
template<typename... Args> template<typename... Args>
void debug(const wchar_t *fmt, const Args &... args) void trace(const wchar_t *fmt, const Args &... args)
{ {
log(level::debug, fmt, args...); log(level::trace, fmt, args...);
} }
template<typename... Args> template<typename... Args>
void info(const wchar_t *fmt, const Args &... args) void debug(const wchar_t *fmt, const Args &... args)
{ {
log(level::info, fmt, args...); log(level::debug, fmt, args...);
} }
template<typename... Args> template<typename... Args>
void warn(const wchar_t *fmt, const Args &... args) void info(const wchar_t *fmt, const Args &... args)
{ {
log(level::warn, fmt, args...); log(level::info, fmt, args...);
} }
template<typename... Args> template<typename... Args>
void error(const wchar_t *fmt, const Args &... args) void warn(const wchar_t *fmt, const Args &... args)
{ {
log(level::err, fmt, args...); log(level::warn, fmt, args...);
} }
template<typename... Args> template<typename... Args>
void critical(const wchar_t *fmt, const Args &... args) void error(const wchar_t *fmt, const Args &... args)
{ {
log(level::critical, fmt, args...); log(level::err, fmt, args...);
} }
template<typename... Args>
void critical(const wchar_t *fmt, const Args &... args)
{
log(level::critical, fmt, args...);
}
#endif // _WIN32 #endif // _WIN32
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT #endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
bool should_log(level::level_enum msg_level) const; bool should_log(level::level_enum msg_level) const;
void set_level(level::level_enum log_level); void set_level(level::level_enum log_level);
static level::level_enum default_level(); static level::level_enum default_level();
level::level_enum level() const; level::level_enum level() const;
const std::string &name() const; const std::string &name() const;
// set formatting for the sinks in this logger. // set formatting for the sinks in this logger.
// each sink will get a seperate instance of the formatter object. // each sink will get a seperate instance of the formatter object.
void set_formatter(std::unique_ptr<formatter> f); void set_formatter(std::unique_ptr<formatter> f);
void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local); void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
// flush functions // flush functions
void flush(); void flush();
void flush_on(level::level_enum log_level); void flush_on(level::level_enum log_level);
level::level_enum flush_level() const; level::level_enum flush_level() const;
// sinks // sinks
const std::vector<sink_ptr> &sinks() const; const std::vector<sink_ptr> &sinks() const;
std::vector<sink_ptr> &sinks(); std::vector<sink_ptr> &sinks();
// error handler // error handler
void set_error_handler(err_handler); void set_error_handler(err_handler);
// create new logger with same sinks and configuration.
virtual std::shared_ptr<logger> clone(std::string logger_name);
protected: // create new logger with same sinks and configuration.
virtual void sink_it_(details::log_msg &msg); virtual std::shared_ptr<logger> clone(std::string logger_name);
virtual void flush_(); protected:
bool should_flush_(const details::log_msg &msg); virtual void sink_it_(details::log_msg &msg);
// default error handler. virtual void flush_();
// print the error to stderr with the max rate of 1 message/minute. bool should_flush_(const details::log_msg &msg);
void err_handler_(const std::string &msg);
const std::string name_;
std::vector<sink_ptr> sinks_;
spdlog::level_t level_{spdlog::logger::default_level()};
spdlog::level_t flush_level_{level::off};
err_handler custom_err_handler_{nullptr};
// default error handler.
// print the error to stderr with the max rate of 1 message/minute.
void err_handler_(const std::string &msg);
const std::string name_;
std::vector<sink_ptr> sinks_;
spdlog::level_t level_{spdlog::logger::default_level()};
spdlog::level_t flush_level_{level::off};
err_handler custom_err_handler_{nullptr};
}; };
} // namespace spdlog } // namespace spdlog

View File

@ -17,7 +17,7 @@ class sink
public: public:
sink(); sink();
explicit sink(std::unique_ptr<spdlog::formatter> formatter); explicit sink(std::unique_ptr<spdlog::formatter> formatter);
virtual ~sink() = default; virtual ~sink() = default;
virtual void log(const details::log_msg &msg) = 0; virtual void log(const details::log_msg &msg) = 0;
virtual void flush() = 0; virtual void flush() = 0;
@ -25,9 +25,9 @@ public:
virtual void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) = 0; virtual void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) = 0;
bool should_log(level::level_enum msg_level) const; bool should_log(level::level_enum msg_level) const;
void set_level(level::level_enum log_level); void set_level(level::level_enum log_level);
level::level_enum level() const; level::level_enum level() const;
protected: protected:

View File

@ -328,7 +328,8 @@ inline void critical(const wchar_t *fmt, const Args &... args)
// //
#define SPDLOG_LOGGER_CALL(logger, level, ...) \ #define SPDLOG_LOGGER_CALL(logger, level, ...) \
do { \ do \
{ \
if (logger->should_log(level)) \ if (logger->should_log(level)) \
logger->log(spdlog::source_loc{SPDLOG_FILE_BASENAME(__FILE__), __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__); \ logger->log(spdlog::source_loc{SPDLOG_FILE_BASENAME(__FILE__), __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__); \
} while (0) } while (0)

View File

@ -107,7 +107,7 @@ TEST_CASE("clone-logger", "[clone]")
cloned->info("Some message 2"); cloned->info("Some message 2");
auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(cloned->sinks()[0]); auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(cloned->sinks()[0]);
spdlog::drop_all(); spdlog::drop_all();
} }
@ -128,7 +128,7 @@ TEST_CASE("clone async", "[clone]")
spdlog::details::os::sleep_for_millis(10); spdlog::details::os::sleep_for_millis(10);
auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(cloned->sinks()[0]); auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(cloned->sinks()[0]);
spdlog::drop_all(); spdlog::drop_all();
} }