Add logger context support

pull/1740/head
Могилин Виктор 5 years ago
parent eebb921c9f
commit 1e3bf67344

@ -2,6 +2,8 @@
cmake_minimum_required(VERSION 3.10)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# ---------------------------------------------------------------------------------------
# Start spdlog project
# ---------------------------------------------------------------------------------------

@ -20,6 +20,8 @@ void user_defined_example();
void err_handler_example();
void syslog_example();
void custom_flags_example();
void context_example();
void hierarchical_context_example();
#include "spdlog/spdlog.h"
#include "spdlog/cfg/env.h" // for loading levels from the environment variable
@ -74,6 +76,8 @@ int main(int, char *[])
trace_example();
stopwatch_example();
custom_flags_example();
context_example();
hierarchical_context_example();
// Flush all *registered* loggers using a worker thread every 3 seconds.
// note: registered loggers *must* be thread safe for this to work correctly!
@ -292,3 +296,40 @@ void custom_flags_example()
formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v");
spdlog::set_formatter(std::move(formatter));
}
#include "spdlog/sinks/stdout_sinks.h"
void context_example()
{
auto logger = spdlog::stdout_logger_mt("name");
logger->with_field("key1", "value1");
std::string k2 = "key2";
std::string v2 = "value2";
logger->with_field(k2, v2);
// the context is not printed because the flag %V is missing
logger->set_pattern("[%T] %v");
logger->info("example without context: {}", 42);
// the context will be printed
logger->set_pattern("[%T] [%V] %v");
logger->info("example with context: {}", 42);
spdlog::drop("name");
}
void hierarchical_context_example()
{
auto f = [](spdlog::logger *log)
{
auto new_log = log->clone("cloned");
new_log->with_field("key2", "val2").info("context print 2");
};
auto logger = spdlog::stdout_logger_mt("name");
logger->set_pattern("[%V] %v");
logger->with_field("key1", "value1").info("context print 1");
f(logger.get());
logger->info("context print 3");
spdlog::drop("name");
spdlog::drop("cloned");
}

@ -13,7 +13,7 @@ namespace spdlog {
namespace details {
SPDLOG_INLINE log_msg::log_msg(spdlog::log_clock::time_point log_time, spdlog::source_loc loc, string_view_t a_logger_name,
spdlog::level::level_enum lvl, spdlog::string_view_t msg)
spdlog::level::level_enum lvl, spdlog::string_view_t msg, spdlog::string_view_t ctx)
: logger_name(a_logger_name)
, level(lvl)
, time(log_time)
@ -22,15 +22,16 @@ SPDLOG_INLINE log_msg::log_msg(spdlog::log_clock::time_point log_time, spdlog::s
#endif
, source(loc)
, payload(msg)
, context(ctx)
{}
SPDLOG_INLINE log_msg::log_msg(
spdlog::source_loc loc, string_view_t a_logger_name, spdlog::level::level_enum lvl, spdlog::string_view_t msg)
: log_msg(os::now(), loc, a_logger_name, lvl, msg)
spdlog::source_loc loc, string_view_t a_logger_name, spdlog::level::level_enum lvl, spdlog::string_view_t msg, spdlog::string_view_t ctx)
: log_msg(os::now(), loc, a_logger_name, lvl, msg, ctx)
{}
SPDLOG_INLINE log_msg::log_msg(string_view_t a_logger_name, spdlog::level::level_enum lvl, spdlog::string_view_t msg)
: log_msg(os::now(), source_loc{}, a_logger_name, lvl, msg)
SPDLOG_INLINE log_msg::log_msg(string_view_t a_logger_name, spdlog::level::level_enum lvl, spdlog::string_view_t msg, spdlog::string_view_t ctx)
: log_msg(os::now(), source_loc{}, a_logger_name, lvl, msg, ctx)
{}
} // namespace details

@ -11,9 +11,9 @@ namespace details {
struct SPDLOG_API log_msg
{
log_msg() = default;
log_msg(log_clock::time_point log_time, source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg);
log_msg(source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg);
log_msg(string_view_t logger_name, level::level_enum lvl, string_view_t msg);
log_msg(log_clock::time_point log_time, source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg, string_view_t ctx);
log_msg(source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg, string_view_t ctx);
log_msg(string_view_t logger_name, level::level_enum lvl, string_view_t msg, string_view_t ctx);
log_msg(const log_msg &other) = default;
string_view_t logger_name;
@ -27,6 +27,7 @@ struct SPDLOG_API log_msg
source_loc source;
string_view_t payload;
string_view_t context;
};
} // namespace details
} // namespace spdlog

@ -23,15 +23,17 @@ SPDLOG_INLINE logger::logger(const logger &other)
, flush_level_(other.flush_level_.load(std::memory_order_relaxed))
, custom_err_handler_(other.custom_err_handler_)
, tracer_(other.tracer_)
{}
{
context_.append(other.context_.data(), other.context_.data() + other.context_.size());
}
SPDLOG_INLINE logger::logger(logger &&other) SPDLOG_NOEXCEPT : name_(std::move(other.name_)),
sinks_(std::move(other.sinks_)),
level_(other.level_.load(std::memory_order_relaxed)),
flush_level_(other.flush_level_.load(std::memory_order_relaxed)),
custom_err_handler_(std::move(other.custom_err_handler_)),
tracer_(std::move(other.tracer_))
tracer_(std::move(other.tracer_)),
context_(std::move(other.context_))
{}
SPDLOG_INLINE logger &logger::operator=(logger other) SPDLOG_NOEXCEPT
@ -57,6 +59,8 @@ SPDLOG_INLINE void logger::swap(spdlog::logger &other) SPDLOG_NOEXCEPT
custom_err_handler_.swap(other.custom_err_handler_);
std::swap(tracer_, other.tracer_);
std::swap(context_, other.context_);
}
SPDLOG_INLINE void swap(logger &a, logger &b)
@ -212,9 +216,13 @@ SPDLOG_INLINE void logger::dump_backtrace_()
using details::log_msg;
if (tracer_.enabled())
{
sink_it_(log_msg{name(), level::info, "****************** Backtrace Start ******************"});
sink_it_(log_msg{name(), level::info, "****************** Backtrace Start ******************",
string_view_t(context_.data(), context_.size())});
tracer_.foreach_pop([this](const log_msg &msg) { this->sink_it_(msg); });
sink_it_(log_msg{name(), level::info, "****************** Backtrace End ********************"});
sink_it_(log_msg{name(), level::info, "****************** Backtrace End ********************",
string_view_t(context_.data(), context_.size())});
}
}

@ -152,7 +152,7 @@ public:
return;
}
details::log_msg log_msg(log_time, loc, name_, lvl, msg);
details::log_msg log_msg(log_time, loc, name_, lvl, msg, string_view_t(context_.data(), context_.size()));
log_it_(log_msg, log_enabled, traceback_enabled);
}
@ -165,7 +165,7 @@ public:
return;
}
details::log_msg log_msg(loc, name_, lvl, msg);
details::log_msg log_msg(loc, name_, lvl, msg, string_view_t(context_.data(), context_.size()));
log_it_(log_msg, log_enabled, traceback_enabled);
}
@ -241,7 +241,7 @@ public:
memory_buf_t buf;
details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf);
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()), string_view_t(context_.data(), context_.size()));
log_it_(log_msg, log_enabled, traceback_enabled);
}
SPDLOG_LOGGER_CATCH()
@ -262,7 +262,7 @@ public:
{
memory_buf_t buf;
details::os::wstr_to_utf8buf(msg, buf);
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()), string_view_t(context_.data(), context_.size()));
log_it_(log_msg, log_enabled, traceback_enabled);
}
SPDLOG_LOGGER_CATCH()
@ -316,6 +316,32 @@ public:
// create new logger with same sinks and configuration.
virtual std::shared_ptr<logger> clone(std::string logger_name);
// add in context a new pair key=value
template <typename Key, typename Value>
logger &with_field(const Key &key, const Value &value)
{
if (context_.size() > 0)
{
static const std::string space = " ";
context_.append(space.data(), space.data() + space.size());
}
auto *buf_ptr = key.data();
context_.append(buf_ptr, buf_ptr + key.size());
static const std::string eq = "=";
context_.append(eq.data(), eq.data() + eq.size());
buf_ptr = value.data();
context_.append(buf_ptr, buf_ptr + value.size());
return *this;
}
logger &with_field(const char *key, const char *value)
{
return with_field(string_view_t(key), string_view_t(value));
}
protected:
std::string name_;
std::vector<sink_ptr> sinks_;
@ -323,6 +349,7 @@ protected:
spdlog::level_t flush_level_{level::off};
err_handler custom_err_handler_{nullptr};
details::backtracer tracer_;
memory_buf_t context_;
// common implementation for after templated public api has been resolved
template<typename FormatString, typename... Args>
@ -338,7 +365,7 @@ protected:
{
memory_buf_t buf;
fmt::format_to(buf, fmt, std::forward<Args>(args)...);
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()), string_view_t(context_.data(), context_.size()));
log_it_(log_msg, log_enabled, traceback_enabled);
}
SPDLOG_LOGGER_CATCH()

@ -689,6 +689,21 @@ public:
}
};
template<typename ScopedPadder>
class V_formatter final : public flag_formatter
{
public:
explicit V_formatter(padding_info padinfo)
: flag_formatter(padinfo)
{}
void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override
{
ScopedPadder p(msg.context.size(), padinfo_, dest);
fmt_helper::append_string_view(msg.context, dest);
}
};
class ch_formatter final : public flag_formatter
{
public:
@ -1097,6 +1112,10 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i
formatters_.push_back(details::make_unique<details::v_formatter<Padder>>(padding));
break;
case ('V'): // the context
formatters_.push_back(details::make_unique<details::V_formatter<Padder>>(padding));
break;
case ('a'): // weekday
formatters_.push_back(details::make_unique<details::a_formatter<Padder>>(padding));
break;

@ -64,7 +64,7 @@ protected:
{
memory_buf_t buf;
fmt::format_to(buf, "Skipped {} duplicate messages..", skip_counter_);
details::log_msg skipped_msg{msg.logger_name, level::info, string_view_t{buf.data(), buf.size()}};
details::log_msg skipped_msg{msg.logger_name, level::info, string_view_t{buf.data(), buf.size()}, msg.context};
dist_sink<Mutex>::sink_it_(skipped_msg);
}

@ -103,7 +103,7 @@ TEST_CASE("daily_file_sink::daily_filename_calculator", "[daily_file_sink]]")
static spdlog::details::log_msg create_msg(std::chrono::seconds offset)
{
using spdlog::log_clock;
spdlog::details::log_msg msg{"test", spdlog::level::info, "Hello Message"};
spdlog::details::log_msg msg{"test", spdlog::level::info, "Hello Message", ""};
msg.time = log_clock::now() + offset;
return msg;
}
@ -146,4 +146,4 @@ TEST_CASE("daily_logger rotate", "[daily_file_sink]")
test_rotate(days_to_run, 10, 10);
test_rotate(days_to_run, 11, 10);
test_rotate(days_to_run, 20, 10);
}
}

@ -13,7 +13,7 @@ TEST_CASE("dup_filter_test1", "[dup_filter_sink]")
for (int i = 0; i < 10; i++)
{
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1", ""});
}
REQUIRE(test_sink->msg_counter() == 1);
@ -30,7 +30,7 @@ TEST_CASE("dup_filter_test2", "[dup_filter_sink]")
for (int i = 0; i < 10; i++)
{
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1", ""});
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
@ -48,8 +48,8 @@ TEST_CASE("dup_filter_test3", "[dup_filter_sink]")
for (int i = 0; i < 10; i++)
{
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1", ""});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2", ""});
}
REQUIRE(test_sink->msg_counter() == 20);
@ -64,9 +64,9 @@ TEST_CASE("dup_filter_test4", "[dup_filter_sink]")
auto test_sink = std::make_shared<test_sink_mt>();
dup_sink.add_sink(test_sink);
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message"});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message", ""});
std::this_thread::sleep_for(std::chrono::milliseconds(50));
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message"});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message", ""});
REQUIRE(test_sink->msg_counter() == 2);
}
@ -79,10 +79,10 @@ TEST_CASE("dup_filter_test5", "[dup_filter_sink]")
auto test_sink = std::make_shared<test_sink_mt>();
dup_sink.add_sink(test_sink);
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1", ""});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1", ""});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1", ""});
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2", ""});
REQUIRE(test_sink->msg_counter() == 3); // skip 2 messages but log the "skipped.." message before message2
}

@ -114,6 +114,54 @@ TEST_CASE("clone-logger", "[clone]")
spdlog::drop_all();
}
TEST_CASE("clone-logger-with-context", "[clone]")
{
using spdlog::sinks::test_sink_mt;
auto test_sink = std::make_shared<test_sink_mt>();
auto logger = std::make_shared<spdlog::logger>("orig", test_sink);
logger->with_field("key", "value");
logger->set_pattern("[%V] %v");
auto cloned = logger->clone("clone");
REQUIRE(cloned->name() == "clone");
REQUIRE(logger->sinks() == cloned->sinks());
REQUIRE(logger->level() == cloned->level());
REQUIRE(logger->flush_level() == cloned->flush_level());
logger->info("Some message 1");
cloned->info("Some message 2");
REQUIRE(test_sink->lines().size() == 2);
REQUIRE(test_sink->lines()[0] == "[key=value] Some message 1");
REQUIRE(test_sink->lines()[1] == "[key=value] Some message 2");
spdlog::drop_all();
}
TEST_CASE("clone-logger-modify-context", "[clone]")
{
using spdlog::sinks::test_sink_mt;
auto test_sink = std::make_shared<test_sink_mt>();
auto logger = std::make_shared<spdlog::logger>("orig", test_sink);
logger->set_pattern("[%V] %v");
logger->with_field("key1", "val1");
auto cloned = logger->clone("clone");
cloned->with_field("key2", "val2");
REQUIRE(cloned->name() == "clone");
REQUIRE(logger->sinks() == cloned->sinks());
REQUIRE(logger->level() == cloned->level());
REQUIRE(logger->flush_level() == cloned->flush_level());
logger->info("Some message 1");
cloned->info("Some message 2");
REQUIRE(test_sink->lines().size() == 2);
REQUIRE(test_sink->lines()[0] == "[key1=val1] Some message 1");
REQUIRE(test_sink->lines()[1] == "[key1=val1 key2=val2] Some message 2");
spdlog::drop_all();
}
TEST_CASE("clone async", "[clone]")
{
using spdlog::sinks::test_sink_st;

@ -67,7 +67,7 @@ TEST_CASE("color range test1", "[pattern_formatter]")
fmt::format_to(buf, "Hello");
memory_buf_t formatted;
std::string logger_name = "test";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, spdlog::string_view_t(buf.data(), buf.size()));
spdlog::details::log_msg msg(logger_name, spdlog::level::info, spdlog::string_view_t(buf.data(), buf.size()), "");
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 0);
REQUIRE(msg.color_range_end == 5);
@ -78,7 +78,7 @@ TEST_CASE("color range test2", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("%^%$", spdlog::pattern_time_type::local, "\n");
std::string logger_name = "test";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "");
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "", "");
memory_buf_t formatted;
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 0);
@ -90,7 +90,7 @@ TEST_CASE("color range test3", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("%^***%$");
std::string logger_name = "test";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored");
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored", "");
memory_buf_t formatted;
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 0);
@ -101,7 +101,7 @@ TEST_CASE("color range test4", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("XX%^YYY%$", spdlog::pattern_time_type::local, "\n");
std::string logger_name = "test";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored");
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored", "");
memory_buf_t formatted;
formatter->format(msg, formatted);
@ -114,7 +114,7 @@ TEST_CASE("color range test5", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("**%^");
std::string logger_name = "test";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored");
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored", "");
memory_buf_t formatted;
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 2);
@ -125,7 +125,7 @@ TEST_CASE("color range test6", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("**%$");
std::string logger_name = "test";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored");
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored", "");
memory_buf_t formatted;
formatter->format(msg, formatted);
REQUIRE(msg.color_range_start == 0);
@ -235,11 +235,11 @@ TEST_CASE("padding_truncate_funcname", "[pattern_formatter]")
auto formatter = std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(pattern));
test_sink.set_formatter(std::move(formatter));
spdlog::details::log_msg msg1{spdlog::source_loc{"ignored", 1, "func"}, "test_logger", spdlog::level::info, "message"};
spdlog::details::log_msg msg1{spdlog::source_loc{"ignored", 1, "func"}, "test_logger", spdlog::level::info, "message", ""};
test_sink.log(msg1);
REQUIRE(test_sink.lines()[0] == "message [ func]");
spdlog::details::log_msg msg2{spdlog::source_loc{"ignored", 1, "function"}, "test_logger", spdlog::level::info, "message"};
spdlog::details::log_msg msg2{spdlog::source_loc{"ignored", 1, "function"}, "test_logger", spdlog::level::info, "message", ""};
test_sink.log(msg2);
REQUIRE(test_sink.lines()[1] == "message [funct]");
}
@ -252,11 +252,11 @@ TEST_CASE("padding_funcname", "[pattern_formatter]")
auto formatter = std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(pattern));
test_sink.set_formatter(std::move(formatter));
spdlog::details::log_msg msg1{spdlog::source_loc{"ignored", 1, "func"}, "test_logger", spdlog::level::info, "message"};
spdlog::details::log_msg msg1{spdlog::source_loc{"ignored", 1, "func"}, "test_logger", spdlog::level::info, "message", ""};
test_sink.log(msg1);
REQUIRE(test_sink.lines()[0] == "message [ func]");
spdlog::details::log_msg msg2{spdlog::source_loc{"ignored", 1, "func567890123"}, "test_logger", spdlog::level::info, "message"};
spdlog::details::log_msg msg2{spdlog::source_loc{"ignored", 1, "func567890123"}, "test_logger", spdlog::level::info, "message", ""};
test_sink.log(msg2);
REQUIRE(test_sink.lines()[1] == "message [func567890123]");
}
@ -266,7 +266,7 @@ TEST_CASE("clone-default-formatter", "[pattern_formatter]")
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>();
auto formatter_2 = formatter_1->clone();
std::string logger_name = "test";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message");
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message", "");
memory_buf_t formatted_1;
memory_buf_t formatted_2;
@ -281,7 +281,7 @@ TEST_CASE("clone-default-formatter2", "[pattern_formatter]")
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%+");
auto formatter_2 = formatter_1->clone();
std::string logger_name = "test";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message");
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message", "");
memory_buf_t formatted_1;
memory_buf_t formatted_2;
@ -296,7 +296,7 @@ TEST_CASE("clone-formatter", "[pattern_formatter]")
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%D %X [%] [%n] %v");
auto formatter_2 = formatter_1->clone();
std::string logger_name = "test";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message");
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message", "");
memory_buf_t formatted_1;
memory_buf_t formatted_2;
@ -311,7 +311,7 @@ TEST_CASE("clone-formatter-2", "[pattern_formatter]")
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%D %X [%] [%n] %v", pattern_time_type::utc, "xxxxxx\n");
auto formatter_2 = formatter_1->clone();
std::string logger_name = "test2";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message");
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message", "");
memory_buf_t formatted_1;
memory_buf_t formatted_2;
@ -355,7 +355,7 @@ TEST_CASE("clone-custom_formatter", "[pattern_formatter]")
formatter_1->add_flag<custom_test_flag>('t', "custom_output").set_pattern("[%n] [%t] %v");
auto formatter_2 = formatter_1->clone();
std::string logger_name = "logger-name";
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message");
spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message", "");
memory_buf_t formatted_1;
memory_buf_t formatted_2;
@ -383,7 +383,7 @@ TEST_CASE("short filename formatter-1", "[pattern_formatter]")
memory_buf_t formatted;
std::string logger_name = "logger-name";
spdlog::source_loc source_loc{test_path, 123, "some_func()"};
spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello");
spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello", "");
formatter.format(msg, formatted);
REQUIRE(fmt::to_string(formatted) == "myfile.cpp");
}
@ -394,7 +394,7 @@ TEST_CASE("short filename formatter-2", "[pattern_formatter]")
memory_buf_t formatted;
std::string logger_name = "logger-name";
spdlog::source_loc source_loc{"myfile.cpp", 123, "some_func()"};
spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello");
spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello", "");
formatter.format(msg, formatted);
REQUIRE(fmt::to_string(formatted) == "myfile.cpp:123");
}
@ -405,7 +405,7 @@ TEST_CASE("short filename formatter-3", "[pattern_formatter]")
memory_buf_t formatted;
std::string logger_name = "logger-name";
spdlog::source_loc source_loc{"", 123, "some_func()"};
spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello");
spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello", "");
formatter.format(msg, formatted);
REQUIRE(fmt::to_string(formatted) == " Hello");
}
@ -416,7 +416,7 @@ TEST_CASE("full filename formatter", "[pattern_formatter]")
memory_buf_t formatted;
std::string logger_name = "logger-name";
spdlog::source_loc source_loc{test_path, 123, "some_func()"};
spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello");
spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello", "");
formatter.format(msg, formatted);
REQUIRE(fmt::to_string(formatted) == test_path);
}
@ -428,7 +428,7 @@ TEST_CASE("custom flags", "[pattern_formatter]")
memory_buf_t formatted;
spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message");
spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message", "");
formatter->format(msg, formatted);
auto expected = fmt::format("[logger-name] [custom1] [custom2] some message{}", spdlog::details::os::default_eol);
REQUIRE(fmt::to_string(formatted) == expected);
@ -441,7 +441,7 @@ TEST_CASE("custom flags-padding", "[pattern_formatter]")
memory_buf_t formatted;
spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message");
spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message", "");
formatter->format(msg, formatted);
auto expected = fmt::format("[logger-name] [custom1] [ custom2] some message{}", spdlog::details::os::default_eol);
REQUIRE(fmt::to_string(formatted) == expected);
@ -453,6 +453,18 @@ TEST_CASE("custom flags-exception", "[pattern_formatter]")
formatter->add_flag<custom_test_flag>('t', "throw_me").add_flag<custom_test_flag>('u', "custom2").set_pattern("[%n] [%t] [%u] %v");
memory_buf_t formatted;
spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message");
spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message", "");
CHECK_THROWS_AS(formatter->format(msg, formatted), spdlog::spdlog_ex);
}
TEST_CASE("log with context", "[pattern_formatter]")
{
spdlog::pattern_formatter formatter("[%V] %v", spdlog::pattern_time_type::local, "");
memory_buf_t formatted;
std::string logger_name = "logger-name";
spdlog::source_loc source_loc{"", 123, "some_func()"};
spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello", "key1=val1");
formatter.format(msg, formatted);
REQUIRE(fmt::to_string(formatted) == "[key1=val1] Hello");
}

@ -15,7 +15,7 @@ TEST_CASE("time_point1", "[time_point log_msg]")
test_sink->set_delay(std::chrono::milliseconds(10));
for (int i = 0; i < 5; i++)
{
spdlog::details::log_msg msg{tp, source, "test_logger", spdlog::level::info, "message"};
spdlog::details::log_msg msg{tp, source, "test_logger", spdlog::level::info, "message", ""};
test_sink->log(msg);
}

Loading…
Cancel
Save