Commit 0c19bdd7 authored by gabime's avatar gabime

pattern per sink and pattern caching

parent 9d7a5c25
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
#define SPDLOG_DEPRECATED #define SPDLOG_DEPRECATED
#endif #endif
#include "fmt/fmt.h" #include "spdlog/fmt/fmt.h"
namespace spdlog { namespace spdlog {
......
...@@ -71,7 +71,6 @@ inline void spdlog::async_logger::backend_log_(details::log_msg &incoming_log_ms ...@@ -71,7 +71,6 @@ inline void spdlog::async_logger::backend_log_(details::log_msg &incoming_log_ms
{ {
try try
{ {
formatter_->format(incoming_log_msg);
for (auto &s : sinks_) for (auto &s : sinks_)
{ {
if (s->should_log(incoming_log_msg.level)) if (s->should_log(incoming_log_msg.level))
......
...@@ -80,10 +80,10 @@ public: ...@@ -80,10 +80,10 @@ public:
} }
} }
void write(const log_msg &msg) void write(const fmt::memory_buffer &buf)
{ {
size_t msg_size = msg.formatted.size(); size_t msg_size = buf.size();
auto data = msg.formatted.data(); auto data = buf.data();
if (std::fwrite(data, 1, msg_size, fd_) != msg_size) if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
{ {
throw spdlog_ex("Failed writing to file " + os::filename_to_str(_filename), errno); throw spdlog_ex("Failed writing to file " + os::filename_to_str(_filename), errno);
......
...@@ -14,6 +14,12 @@ inline void append_str(const std::string &str, fmt::memory_buffer &dest) ...@@ -14,6 +14,12 @@ inline void append_str(const std::string &str, fmt::memory_buffer &dest)
dest.append(str_ptr, str_ptr + str.size()); dest.append(str_ptr, str_ptr + str.size());
} }
inline void append_c_str(const char *c_str, fmt::memory_buffer &dest)
{
auto str_size = strlen(c_str);
dest.append(c_str, c_str + str_size);
}
inline void append_buf(const fmt::memory_buffer &buf, fmt::memory_buffer &dest) inline void append_buf(const fmt::memory_buffer &buf, fmt::memory_buffer &dest)
{ {
const char *buf_ptr = buf.data(); const char *buf_ptr = buf.data();
...@@ -74,7 +80,7 @@ inline void append_and_pad3(int n, fmt::memory_buffer &dest) ...@@ -74,7 +80,7 @@ inline void append_and_pad3(int n, fmt::memory_buffer &dest)
append_int(n, dest); append_int(n, dest);
} }
void append_and_pad6(int n, fmt::memory_buffer &dest) inline void append_and_pad6(int n, fmt::memory_buffer &dest)
{ {
if (n > 99999) if (n > 99999)
{ {
......
...@@ -38,11 +38,10 @@ struct log_msg ...@@ -38,11 +38,10 @@ struct log_msg
log_clock::time_point time; log_clock::time_point time;
size_t thread_id; size_t thread_id;
fmt::memory_buffer raw; fmt::memory_buffer raw;
fmt::memory_buffer formatted;
size_t msg_id{0}; size_t msg_id{0};
// info about wrapping the formatted text with color // info about wrapping the formatted text with color
size_t color_range_start{0}; mutable size_t color_range_start{0};
size_t color_range_end{0}; mutable size_t color_range_end{0};
}; };
} // namespace details } // namespace details
} // namespace spdlog } // namespace spdlog
...@@ -14,7 +14,6 @@ template<class It> ...@@ -14,7 +14,6 @@ template<class It>
inline spdlog::logger::logger(std::string logger_name, const It &begin, const It &end) inline spdlog::logger::logger(std::string logger_name, const It &begin, const It &end)
: name_(std::move(logger_name)) : name_(std::move(logger_name))
, sinks_(begin, end) , sinks_(begin, end)
, formatter_(std::make_shared<pattern_formatter>("%+"))
, level_(level::info) , level_(level::info)
, flush_level_(level::off) , flush_level_(level::off)
, last_err_time_(0) , last_err_time_(0)
...@@ -37,14 +36,19 @@ inline spdlog::logger::logger(const std::string &logger_name, spdlog::sink_ptr s ...@@ -37,14 +36,19 @@ inline spdlog::logger::logger(const std::string &logger_name, spdlog::sink_ptr s
inline spdlog::logger::~logger() = default; inline spdlog::logger::~logger() = default;
inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter) template<class FormatterT, typename... Args>
inline void spdlog::logger::set_formatter(const Args &... args)
{ {
formatter_ = std::move(msg_formatter); for (auto &sink : sinks_)
{
std::unique_ptr<FormatterT> formatter(new FormatterT(args...));
sink->set_formatter(std::move(formatter));
}
} }
inline void spdlog::logger::set_pattern(const std::string &pattern, pattern_time_type pattern_time) inline void spdlog::logger::set_pattern(const std::string &pattern, pattern_time_type pattern_time)
{ {
formatter_ = std::make_shared<pattern_formatter>(pattern, pattern_time); set_formatter<spdlog::pattern_formatter>(pattern, pattern_time);
} }
template<typename... Args> template<typename... Args>
...@@ -288,7 +292,6 @@ inline void spdlog::logger::sink_it_(details::log_msg &msg) ...@@ -288,7 +292,6 @@ inline void spdlog::logger::sink_it_(details::log_msg &msg)
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER) #if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
incr_msg_counter_(msg); incr_msg_counter_(msg);
#endif #endif
formatter_->format(msg);
for (auto &sink : sinks_) for (auto &sink : sinks_)
{ {
if (sink->should_log(msg.level)) if (sink->should_log(msg.level))
......
...@@ -46,10 +46,9 @@ public: ...@@ -46,10 +46,9 @@ public:
auto logger_name = new_logger->name(); auto logger_name = new_logger->name();
throw_if_exists(logger_name); throw_if_exists(logger_name);
if (formatter_) // create default formatter if not exists
{
new_logger->set_formatter(formatter_); new_logger->set_pattern(formatter_pattern_);
}
if (err_handler_) if (err_handler_)
{ {
...@@ -82,23 +81,13 @@ public: ...@@ -82,23 +81,13 @@ public:
return tp_; return tp_;
} }
void set_formatter(formatter_ptr f)
{
std::lock_guard<Mutex> lock(mutex_);
formatter_ = f;
for (auto &l : loggers_)
{
l.second->set_formatter(formatter_);
}
}
void set_pattern(const std::string &pattern) void set_pattern(const std::string &pattern)
{ {
std::lock_guard<Mutex> lock(mutex_); std::lock_guard<Mutex> lock(mutex_);
formatter_ = std::make_shared<pattern_formatter>(pattern); formatter_pattern_ = pattern;
for (auto &l : loggers_) for (auto &l : loggers_)
{ {
l.second->set_formatter(formatter_); l.second->set_pattern(pattern);
} }
} }
...@@ -184,7 +173,7 @@ private: ...@@ -184,7 +173,7 @@ private:
Mutex mutex_; Mutex mutex_;
Mutex tp_mutex_; Mutex tp_mutex_;
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_; std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
formatter_ptr formatter_; std::string formatter_pattern_ = "%+";
level::level_enum level_ = level::info; level::level_enum level_ = level::info;
level::level_enum flush_level_ = level::off; level::level_enum flush_level_ = level::off;
log_err_handler err_handler_; log_err_handler err_handler_;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#pragma once #pragma once
#include "fmt/fmt.h"
#include "spdlog/details/log_msg.h" #include "spdlog/details/log_msg.h"
#include <memory> #include <memory>
...@@ -12,31 +13,32 @@ ...@@ -12,31 +13,32 @@
#include <vector> #include <vector>
namespace spdlog { namespace spdlog {
namespace details {
class flag_formatter;
}
class formatter class formatter
{ {
public: public:
virtual ~formatter() = default; virtual ~formatter() = default;
virtual void format(details::log_msg &msg) = 0; virtual void format(const details::log_msg &msg, fmt::memory_buffer &dest) = 0;
}; };
namespace details {
class flag_formatter;
}
class pattern_formatter SPDLOG_FINAL : public formatter class pattern_formatter SPDLOG_FINAL : public formatter
{ {
public: public:
explicit pattern_formatter(const std::string &pattern, pattern_time_type pattern_time = pattern_time_type::local, explicit pattern_formatter(const std::string &pattern, pattern_time_type pattern_time = pattern_time_type::local,
std::string eol = spdlog::details::os::default_eol); std::string eol = spdlog::details::os::default_eol);
pattern_formatter(const pattern_formatter &) = delete; pattern_formatter(const pattern_formatter &) = default;
pattern_formatter &operator=(const pattern_formatter &) = delete; pattern_formatter &operator=(const pattern_formatter &) = default;
void format(details::log_msg &msg) override; void format(const details::log_msg &msg, fmt::memory_buffer &dest) override;
private: private:
const std::string eol_; const std::string eol_;
const pattern_time_type pattern_time_; const pattern_time_type pattern_time_;
std::vector<std::unique_ptr<details::flag_formatter>> formatters_; std::vector<std::unique_ptr<details::flag_formatter>> formatters_;
std::tm get_time(details::log_msg &msg); std::tm get_time(const details::log_msg &msg);
void handle_flag(char flag); void handle_flag(char flag);
void compile_pattern(const std::string &pattern); void compile_pattern(const std::string &pattern);
}; };
......
...@@ -8,9 +8,12 @@ ...@@ -8,9 +8,12 @@
// Thread safe logger (except for set_pattern(..), set_formatter(..) and set_error_handler()) // Thread safe logger (except for set_pattern(..), set_formatter(..) and set_error_handler())
// Has name, log level, vector of std::shared sink pointers and formatter // Has name, log level, vector of std::shared sink pointers and formatter
// Upon each log write the logger: // Upon each log write the logger:
// 1. Checks if its log level is enough to log the message // 1. Checks if its log level is enough to log the message and if yes:
// 2. Format the message using the formatter function // 2. Call the underlying sinks to do the job.
// 3. Pass the formatted message to its sinks to performa the actual logging // 3. Each sink use its own private copy of a formatter to format the message and send to its destination.
//
// The use of private formatter per sink provides the opportunity to cache some formatted data,
// and support customize format per each sink.
#include "spdlog/common.h" #include "spdlog/common.h"
#include "spdlog/formatter.h" #include "spdlog/formatter.h"
...@@ -111,8 +114,15 @@ public: ...@@ -111,8 +114,15 @@ public:
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;
const std::string &name() const; const std::string &name() const;
// create a pattern formatter all the sinks in this logger.
// each sink gets itw own private copy of a formatter object.
void set_pattern(const std::string &pattern, pattern_time_type pattern_time = pattern_time_type::local); void set_pattern(const std::string &pattern, pattern_time_type pattern_time = pattern_time_type::local);
void set_formatter(formatter_ptr msg_formatter);
// create a FormatterT formatter all the sinks in this logger.
// each sink gets itw own private copy of a formatter object.
template<class FormatterT, typename... Args>
void set_formatter(const Args &... args);
void flush(); void flush();
void flush_on(level::level_enum log_level); void flush_on(level::level_enum log_level);
...@@ -137,7 +147,6 @@ protected: ...@@ -137,7 +147,6 @@ protected:
const std::string name_; const std::string name_;
std::vector<sink_ptr> sinks_; std::vector<sink_ptr> sinks_;
formatter_ptr formatter_;
spdlog::level_t level_; spdlog::level_t level_;
spdlog::level_t flush_level_; spdlog::level_t flush_level_;
log_err_handler err_handler_; log_err_handler err_handler_;
......
...@@ -39,7 +39,17 @@ public: ...@@ -39,7 +39,17 @@ public:
void log(const details::log_msg &msg) override void log(const details::log_msg &msg) override
{ {
const android_LogPriority priority = convert_to_android(msg.level); const android_LogPriority priority = convert_to_android(msg.level);
const char *msg_output = (use_raw_msg_ ? msg.raw.c_str() : msg.formatted.c_str()); fmt::memory_buffer formatted;
if (use_raw_msg_)
{
formatted.append(msg.raw.data(), msg.raw.data() + msg.raw.size());
}
else
{
formatter_->format(msg, formatted);
}
formatted.push_back('\0');
const char *msg_output = formatted.data();
// See system/core/liblog/logger_write.c for explanation of return value // See system/core/liblog/logger_write.c for explanation of return value
int ret = __android_log_write(priority, tag_.c_str(), msg_output); int ret = __android_log_write(priority, tag_.c_str(), msg_output);
......
...@@ -88,20 +88,23 @@ public: ...@@ -88,20 +88,23 @@ public:
// Wrap the originally formatted message in color codes. // Wrap the originally formatted message in color codes.
// If color is not supported in the terminal, log as is instead. // If color is not supported in the terminal, log as is instead.
std::lock_guard<mutex_t> lock(mutex_); std::lock_guard<mutex_t> lock(mutex_);
fmt::memory_buffer formatted;
formatter_->format(msg, formatted);
if (should_do_colors_ && msg.color_range_end > msg.color_range_start) if (should_do_colors_ && msg.color_range_end > msg.color_range_start)
{ {
// before color range // before color range
print_range_(msg, 0, msg.color_range_start); print_range_(formatted, 0, msg.color_range_start);
// in color range // in color range
print_ccode_(colors_[msg.level]); print_ccode_(colors_[msg.level]);
print_range_(msg, msg.color_range_start, msg.color_range_end); print_range_(formatted, msg.color_range_start, msg.color_range_end);
print_ccode_(reset); print_ccode_(reset);
// after color range // after color range
print_range_(msg, msg.color_range_end, msg.formatted.size()); print_range_(formatted, msg.color_range_end, formatted.size());
} }
else // no color else // no color
{ {
print_range_(msg, 0, msg.formatted.size()); print_range_(formatted, 0, formatted.size());
} }
fflush(target_file_); fflush(target_file_);
} }
...@@ -117,9 +120,9 @@ private: ...@@ -117,9 +120,9 @@ private:
{ {
fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_); fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_);
} }
void print_range_(const details::log_msg &msg, size_t start, size_t end) void print_range_(const fmt::memory_buffer &formatted, size_t start, size_t end)
{ {
fwrite(msg.formatted.data() + start, sizeof(char), end - start, target_file_); fwrite(formatted.data() + start, sizeof(char), end - start, target_file_);
} }
FILE *target_file_; FILE *target_file_;
......
...@@ -21,7 +21,20 @@ template<class Mutex> ...@@ -21,7 +21,20 @@ template<class Mutex>
class base_sink : public sink class base_sink : public sink
{ {
public: public:
base_sink() = default; base_sink()
: sink()
{
}
base_sink(const std::string &formatter_pattern)
: sink(formatter_pattern)
{
}
base_sink(std::unique_ptr<spdlog::formatter> sink_formatter)
: sink(std::move(sink_formatter))
{
}
base_sink(const base_sink &) = delete; base_sink(const base_sink &) = delete;
base_sink &operator=(const base_sink &) = delete; base_sink &operator=(const base_sink &) = delete;
...@@ -29,7 +42,9 @@ public: ...@@ -29,7 +42,9 @@ public:
void log(const details::log_msg &msg) SPDLOG_FINAL override void log(const details::log_msg &msg) SPDLOG_FINAL override
{ {
std::lock_guard<Mutex> lock(mutex_); std::lock_guard<Mutex> lock(mutex_);
sink_it_(msg); fmt::memory_buffer formatted;
formatter_->format(msg, formatted);
sink_it_(msg, formatted);
} }
void flush() SPDLOG_FINAL override void flush() SPDLOG_FINAL override
...@@ -39,7 +54,7 @@ public: ...@@ -39,7 +54,7 @@ public:
} }
protected: protected:
virtual void sink_it_(const details::log_msg &msg) = 0; virtual void sink_it_(const details::log_msg &msg, const fmt::memory_buffer &formatted) = 0;
virtual void flush_() = 0; virtual void flush_() = 0;
Mutex mutex_; Mutex mutex_;
}; };
......
...@@ -76,14 +76,14 @@ public: ...@@ -76,14 +76,14 @@ public:
} }
protected: protected:
void sink_it_(const details::log_msg &msg) override void sink_it_(const details::log_msg &, const fmt::memory_buffer &formatted) override
{ {
if (std::chrono::system_clock::now() >= rotation_tp_) if (std::chrono::system_clock::now() >= rotation_tp_)
{ {
file_helper_.open(FileNameCalc::calc_filename(base_filename_)); file_helper_.open(FileNameCalc::calc_filename(base_filename_));
rotation_tp_ = next_rotation_tp_(); rotation_tp_ = next_rotation_tp_();
} }
file_helper_.write(msg); file_helper_.write(formatted);
} }
void flush_() override void flush_() override
......
...@@ -17,12 +17,12 @@ template<class Mutex> ...@@ -17,12 +17,12 @@ template<class Mutex>
class null_sink : public base_sink<Mutex> class null_sink : public base_sink<Mutex>
{ {
protected: protected:
void sink_it_(const details::log_msg &) override {} void sink_it_(const details::log_msg &, const fmt::memory_buffer &) override {}
void flush_() override {} void flush_() override {}
}; };
using null_sink_mt = null_sink<details::null_mutex>; using null_sink_mt = null_sink<std::mutex>;
using null_sink_st = null_sink<details::null_mutex>; using null_sink_st = null_sink<details::null_mutex>;
} // namespace sinks } // namespace sinks
......
...@@ -26,9 +26,9 @@ public: ...@@ -26,9 +26,9 @@ public:
ostream_sink &operator=(const ostream_sink &) = delete; ostream_sink &operator=(const ostream_sink &) = delete;
protected: protected:
void sink_it_(const details::log_msg &msg) override void sink_it_(const details::log_msg &msg, const fmt::memory_buffer &formatted) override
{ {
ostream_.write(msg.formatted.data(), msg.formatted.size()); ostream_.write(formatted.data(), formatted.size());
if (force_flush_) if (force_flush_)
ostream_.flush(); ostream_.flush();
} }
......
...@@ -55,15 +55,15 @@ public: ...@@ -55,15 +55,15 @@ public:
} }
protected: protected:
void sink_it_(const details::log_msg &msg) override void sink_it_(const details::log_msg &, const fmt::memory_buffer &formatted) override
{ {
current_size_ += msg.formatted.size(); current_size_ += formatted.size();
if (current_size_ > max_size_) if (current_size_ > max_size_)
{ {
rotate_(); rotate_();
current_size_ = msg.formatted.size(); current_size_ = formatted.size();
} }
file_helper_.write(msg); file_helper_.write(formatted);
} }
void flush_() override void flush_() override
......
...@@ -33,9 +33,9 @@ public: ...@@ -33,9 +33,9 @@ public:
} }
protected: protected:
void sink_it_(const details::log_msg &msg) override void sink_it_(const details::log_msg &, const fmt::memory_buffer &formatted) override
{ {
file_helper_.write(msg); file_helper_.write(formatted);
if (force_flush_) if (force_flush_)
{ {
file_helper_.flush(); file_helper_.flush();
......
...@@ -6,39 +6,62 @@ ...@@ -6,39 +6,62 @@
#pragma once #pragma once
#include "spdlog/details/log_msg.h" #include "spdlog/details/log_msg.h"
#include "spdlog/formatter.h"
namespace spdlog { namespace spdlog {
namespace sinks { namespace sinks {
class sink class sink
{ {
public: public:
// default sink ctor with default pattern formatter
sink()
: formatter_(std::unique_ptr<spdlog::formatter>(new pattern_formatter("%+")))
{
}
explicit sink(const std::string &formatter_pattern)
: formatter_(std::unique_ptr<spdlog::formatter>(new pattern_formatter(formatter_pattern)))
{
}
// sink with custom formatter
explicit sink(std::unique_ptr<spdlog::formatter> sink_formatter)
: formatter_(std::move(sink_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;
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); {
level::level_enum level() const;
private:
level_t level_{level::trace};
};
inline bool sink::should_log(level::level_enum msg_level) const
{
return msg_level >= level_.load(std::memory_order_relaxed); return msg_level >= level_.load(std::memory_order_relaxed);
} }
void set_level(level::level_enum log_level)
inline void sink::set_level(level::level_enum log_level) {
{
level_.store(log_level); level_.store(log_level);
} }
level::level_enum level() const
inline level::level_enum sink::level() const {
{
return static_cast<spdlog::level::level_enum>(level_.load(std::memory_order_relaxed)); return static_cast<spdlog::level::level_enum>(level_.load(std::memory_order_relaxed));
} }
void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter)
{
formatter_ = std::move(sink_formatter);
}
spdlog::formatter *formatter()
{
return formatter_.get();
}
protected:
level_t level_{level::trace};
std::unique_ptr<spdlog::formatter> formatter_;
};
} // namespace sinks } // namespace sinks
} // namespace spdlog } // namespace spdlog
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#pragma once #pragma once
#include "../fmt/fmt.h"
#include "spdlog/common.h" #include "spdlog/common.h"
#include "spdlog/details/null_mutex.h" #include "spdlog/details/null_mutex.h"
#include "spdlog/details/traits.h" #include "spdlog/details/traits.h"
...@@ -63,22 +64,23 @@ public: ...@@ -63,22 +64,23 @@ public:
void log(const details::log_msg &msg) SPDLOG_FINAL override void log(const details::log_msg &msg) SPDLOG_FINAL override
{ {
std::lock_guard<mutex_t> lock(mutex_); std::lock_guard<mutex_t> lock(mutex_);
fmt::memory_buffer formatted;
formatter_->format(msg, formatted);
if (msg.color_range_end > msg.color_range_start) if (msg.color_range_end > msg.color_range_start)
{ {
// before color range // before color range
print_range_(msg, 0, msg.color_range_start); print_range_(formatted, 0, msg.color_range_start);
// in color range // in color range
auto orig_attribs = set_console_attribs(colors_[msg.level]); auto orig_attribs = set_console_attribs(colors_[msg.level]);
print_range_(msg, msg.color_range_start, msg.color_range_end); print_range_(formatted, msg.color_range_start, msg.color_range_end);
::SetConsoleTextAttribute(out_handle_, orig_attribs); // reset to orig colors ::SetConsoleTextAttribute(out_handle_, orig_attribs); // reset to orig colors
// after color range // after color range
print_range_(msg, msg.color_range_end, msg.formatted.size()); print_range_(formatted, msg.color_range_end, formatted.size());
} }
else // print without colors if color range is invalid else // print without colors if color range is invalid
{ {
print_range_(msg, 0, msg.formatted.size()); print_range_(formatted, 0, formatted.size());
} }
} }
...@@ -103,10 +105,10 @@ private: ...@@ -103,10 +105,10 @@ private:
} }
// print a range of formatted message to console // print a range of formatted message to console
void print_range_(const details::log_msg &msg, size_t start, size_t end) void print_range_(const fmt::memory_buffer formatted, size_t start, size_t end)
{ {
auto size = static_cast<DWORD>(end - start); auto size = static_cast<DWORD>(end - start);
::WriteConsoleA(out_handle_, msg.formatted.data() + start, size, nullptr, nullptr); ::WriteConsoleA(out_handle_, formatted.data() + start, size, nullptr, nullptr);
} }
HANDLE out_handle_; HANDLE out_handle_;
......
...@@ -62,11 +62,6 @@ inline void set_pattern(const std::string &format_string) ...@@ -62,11 +62,6 @@ inline void set_pattern(const std::string &format_string)
details::registry::instance().set_pattern(format_string); details::registry::instance().set_pattern(format_string);
} }
inline void set_formatter(formatter_ptr f)
{
details::registry::instance().set_formatter(std::move(f));
}
// //
// Set global logging level // Set global logging level
// //
......
...@@ -11,9 +11,9 @@ static const std::string target_filename = "logs/file_helper_test.txt"; ...@@ -11,9 +11,9 @@ static const std::string target_filename = "logs/file_helper_test.txt";
static void write_with_helper(file_helper &helper, size_t howmany) static void write_with_helper(file_helper &helper, size_t howmany)
{ {
log_msg msg; log_msg msg;
fmt::memory_buffer formatted;
fmt::format_to(msg.formatted, "{}", std::string(howmany, '1')); fmt::format_to(formatted, "{}", std::string(howmany, '1'));
helper.write(msg); helper.write(formatted);
helper.flush(); helper.flush();
} }
......
#include "includes.h" #include "includes.h"
// log to str and return it // log to str and return it
static std::string log_to_str(const std::string &msg, const std::shared_ptr<spdlog::formatter> &formatter = nullptr) template<typename... Args>
static std::string log_to_str(const std::string &msg, const Args &... args)
{ {
std::ostringstream oss; std::ostringstream oss;
auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss);
spdlog::logger oss_logger("pattern_tester", oss_sink); spdlog::logger oss_logger("pattern_tester", oss_sink);
oss_logger.set_level(spdlog::level::info); oss_logger.set_level(spdlog::level::info);
if (formatter) oss_logger.set_formatter<spdlog::pattern_formatter>(args...);
{
oss_logger.set_formatter(formatter);
}
oss_logger.info(msg); oss_logger.info(msg);
return oss.str(); return oss.str();
} }
...@@ -19,49 +19,44 @@ TEST_CASE("custom eol", "[pattern_formatter]") ...@@ -19,49 +19,44 @@ TEST_CASE("custom eol", "[pattern_formatter]")
{ {
std::string msg = "Hello custom eol test"; std::string msg = "Hello custom eol test";
std::string eol = ";)"; std::string eol = ";)";
auto formatter = std::make_shared<spdlog::pattern_formatter>("%v", spdlog::pattern_time_type::local, ";)"); // auto formatter = std::make_shared<spdlog::pattern_formatter>("%v", spdlog::pattern_time_type::local, ";)");
std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter("%v", spdlog::pattern_time_type::local, ";)"));
REQUIRE(log_to_str(msg, formatter) == msg + eol); REQUIRE(log_to_str(msg, "%v", spdlog::pattern_time_type::local, ";)") == msg + eol);
} }
TEST_CASE("empty format", "[pattern_formatter]") TEST_CASE("empty format", "[pattern_formatter]")
{ {
auto formatter = std::make_shared<spdlog::pattern_formatter>("", spdlog::pattern_time_type::local, ""); REQUIRE(log_to_str("Some message", "", spdlog::pattern_time_type::local, "") == "");
REQUIRE(log_to_str("Some message", formatter) == "");
} }
TEST_CASE("empty format2", "[pattern_formatter]") TEST_CASE("empty format2", "[pattern_formatter]")
{ {
auto formatter = std::make_shared<spdlog::pattern_formatter>("", spdlog::pattern_time_type::local, "\n"); REQUIRE(log_to_str("Some message", "", spdlog::pattern_time_type::local, "\n") == "\n");
REQUIRE(log_to_str("Some message", formatter) == "\n");
} }
TEST_CASE("level", "[pattern_formatter]") TEST_CASE("level", "[pattern_formatter]")
{ {
auto formatter = std::make_shared<spdlog::pattern_formatter>("[%l] %v", spdlog::pattern_time_type::local, "\n"); REQUIRE(log_to_str("Some message", "[%l] %v", spdlog::pattern_time_type::local, "\n") == "[info] Some message\n");
REQUIRE(log_to_str("Some message", formatter) == "[info] Some message\n");
} }
TEST_CASE("short level", "[pattern_formatter]") TEST_CASE("short level", "[pattern_formatter]")
{ {
auto formatter = std::make_shared<spdlog::pattern_formatter>("[%L] %v", spdlog::pattern_time_type::local, "\n"); REQUIRE(log_to_str("Some message", "[%L] %v", spdlog::pattern_time_type::local, "\n") == "[I] Some message\n");
REQUIRE(log_to_str("Some message", formatter) == "[I] Some message\n");
} }
TEST_CASE("name", "[pattern_formatter]") TEST_CASE("name", "[pattern_formatter]")
{ {
auto formatter = std::make_shared<spdlog::pattern_formatter>("[%n] %v", spdlog::pattern_time_type::local, "\n"); REQUIRE(log_to_str("Some message", "[%n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n");
REQUIRE(log_to_str("Some message", formatter) == "[pattern_tester] Some message\n");
} }
TEST_CASE("date MM/DD/YY ", "[pattern_formatter]") TEST_CASE("date MM/DD/YY ", "[pattern_formatter]")
{ {
auto formatter = std::make_shared<spdlog::pattern_formatter>("%D %v", spdlog::pattern_time_type::local, "\n");
auto now_tm = spdlog::details::os::localtime(); auto now_tm = spdlog::details::os::localtime();
std::stringstream oss; std::stringstream oss;
oss << std::setfill('0') << std::setw(2) << now_tm.tm_mon + 1 << "/" << std::setw(2) << now_tm.tm_mday << "/" << std::setw(2) oss << std::setfill('0') << std::setw(2) << now_tm.tm_mon + 1 << "/" << std::setw(2) << now_tm.tm_mday << "/" << std::setw(2)
<< (now_tm.tm_year + 1900) % 1000 << " Some message\n"; << (now_tm.tm_year + 1900) % 1000 << " Some message\n";
REQUIRE(log_to_str("Some message", formatter) == oss.str()); REQUIRE(log_to_str("Some message", "%D %v", spdlog::pattern_time_type::local, "\n") == oss.str());
} }
TEST_CASE("color range test1", "[pattern_formatter]") TEST_CASE("color range test1", "[pattern_formatter]")
...@@ -69,27 +64,30 @@ TEST_CASE("color range test1", "[pattern_formatter]") ...@@ -69,27 +64,30 @@ TEST_CASE("color range test1", "[pattern_formatter]")
auto formatter = std::make_shared<spdlog::pattern_formatter>("%^%v%$", spdlog::pattern_time_type::local, "\n"); auto formatter = std::make_shared<spdlog::pattern_formatter>("%^%v%$", spdlog::pattern_time_type::local, "\n");
spdlog::details::log_msg msg; spdlog::details::log_msg msg;
fmt::format_to(msg.raw, "Hello"); fmt::format_to(msg.raw, "Hello");
formatter->format(msg); fmt::memory_buffer formatted;
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 0); REQUIRE(msg.color_range_start == 0);
REQUIRE(msg.color_range_end == 5); REQUIRE(msg.color_range_end == 5);
REQUIRE(log_to_str("hello", formatter) == "hello\n"); REQUIRE(log_to_str("hello", "%^%v%$", spdlog::pattern_time_type::local, "\n") == "hello\n");
} }
TEST_CASE("color range test2", "[pattern_formatter]") TEST_CASE("color range test2", "[pattern_formatter]")
{ {
auto formatter = std::make_shared<spdlog::pattern_formatter>("%^%$", spdlog::pattern_time_type::local, "\n"); auto formatter = std::make_shared<spdlog::pattern_formatter>("%^%$", spdlog::pattern_time_type::local, "\n");
spdlog::details::log_msg msg; spdlog::details::log_msg msg;
formatter->format(msg); fmt::memory_buffer formatted;
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 0); REQUIRE(msg.color_range_start == 0);
REQUIRE(msg.color_range_end == 0); REQUIRE(msg.color_range_end == 0);
REQUIRE(log_to_str("", formatter) == "\n"); REQUIRE(log_to_str("", "%^%$", spdlog::pattern_time_type::local, "\n") == "\n");
} }
TEST_CASE("color range test3", "[pattern_formatter]") TEST_CASE("color range test3", "[pattern_formatter]")
{ {
auto formatter = std::make_shared<spdlog::pattern_formatter>("%^***%$"); auto formatter = std::make_shared<spdlog::pattern_formatter>("%^***%$");
spdlog::details::log_msg msg; spdlog::details::log_msg msg;
formatter->format(msg); fmt::memory_buffer formatted;
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 0); REQUIRE(msg.color_range_start == 0);
REQUIRE(msg.color_range_end == 3); REQUIRE(msg.color_range_end == 3);
} }
...@@ -99,17 +97,19 @@ TEST_CASE("color range test4", "[pattern_formatter]") ...@@ -99,17 +97,19 @@ TEST_CASE("color range test4", "[pattern_formatter]")
auto formatter = std::make_shared<spdlog::pattern_formatter>("XX%^YYY%$", spdlog::pattern_time_type::local, "\n"); auto formatter = std::make_shared<spdlog::pattern_formatter>("XX%^YYY%$", spdlog::pattern_time_type::local, "\n");
spdlog::details::log_msg msg; spdlog::details::log_msg msg;
fmt::format_to(msg.raw, "ignored"); fmt::format_to(msg.raw, "ignored");
formatter->format(msg); fmt::memory_buffer formatted;
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 2); REQUIRE(msg.color_range_start == 2);
REQUIRE(msg.color_range_end == 5); REQUIRE(msg.color_range_end == 5);
REQUIRE(log_to_str("ignored", formatter) == "XXYYY\n"); REQUIRE(log_to_str("ignored", "XX%^YYY%$", spdlog::pattern_time_type::local, "\n") == "XXYYY\n");
} }
TEST_CASE("color range test5", "[pattern_formatter]") TEST_CASE("color range test5", "[pattern_formatter]")
{ {
auto formatter = std::make_shared<spdlog::pattern_formatter>("**%^"); auto formatter = std::make_shared<spdlog::pattern_formatter>("**%^");
spdlog::details::log_msg msg; spdlog::details::log_msg msg;
formatter->format(msg); fmt::memory_buffer formatted;
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 2); REQUIRE(msg.color_range_start == 2);
REQUIRE(msg.color_range_end == 0); REQUIRE(msg.color_range_end == 0);
} }
...@@ -118,7 +118,8 @@ TEST_CASE("color range test6", "[pattern_formatter]") ...@@ -118,7 +118,8 @@ TEST_CASE("color range test6", "[pattern_formatter]")
{ {
auto formatter = std::make_shared<spdlog::pattern_formatter>("**%$"); auto formatter = std::make_shared<spdlog::pattern_formatter>("**%$");
spdlog::details::log_msg msg; spdlog::details::log_msg msg;
formatter->format(msg); fmt::memory_buffer formatted;
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 0); REQUIRE(msg.color_range_start == 0);
REQUIRE(msg.color_range_end == 2); REQUIRE(msg.color_range_end == 2);
} }
...@@ -35,7 +35,7 @@ public: ...@@ -35,7 +35,7 @@ public:
} }
protected: protected:
void sink_it_(const details::log_msg &) override void sink_it_(const details::log_msg &, const fmt::memory_buffer &) override
{ {
msg_counter_++; msg_counter_++;
std::this_thread::sleep_for(delay_); std::this_thread::sleep_for(delay_);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment