Removed backtrace feature

This commit is contained in:
gabime 2023-07-28 17:33:00 +03:00
parent d94830814f
commit 92daf6954b
14 changed files with 13 additions and 396 deletions

View File

@ -45,32 +45,20 @@ void bench_threaded_logging(size_t threads, int iters)
auto basic_mt = spdlog::basic_logger_mt("basic_mt", "logs/basic_mt.log", true); auto basic_mt = spdlog::basic_logger_mt("basic_mt", "logs/basic_mt.log", true);
bench_mt(iters, std::move(basic_mt), threads); bench_mt(iters, std::move(basic_mt), threads);
auto basic_mt_tracing = spdlog::basic_logger_mt("basic_mt/backtrace-on", "logs/basic_mt.log", true);
basic_mt_tracing->enable_backtrace(32);
bench_mt(iters, std::move(basic_mt_tracing), threads);
spdlog::info(""); spdlog::info("");
auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files); auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files);
bench_mt(iters, std::move(rotating_mt), threads); bench_mt(iters, std::move(rotating_mt), threads);
auto rotating_mt_tracing = spdlog::rotating_logger_mt("rotating_mt/backtrace-on", "logs/rotating_mt.log", file_size, rotating_files);
rotating_mt_tracing->enable_backtrace(32);
bench_mt(iters, std::move(rotating_mt_tracing), threads);
spdlog::info(""); spdlog::info("");
auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt.log"); auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt.log");
bench_mt(iters, std::move(daily_mt), threads); bench_mt(iters, std::move(daily_mt), threads);
auto daily_mt_tracing = spdlog::daily_logger_mt("daily_mt/backtrace-on", "logs/daily_mt.log");
daily_mt_tracing->enable_backtrace(32);
bench_mt(iters, std::move(daily_mt_tracing), threads);
spdlog::info(""); spdlog::info("");
auto empty_logger = std::make_shared<spdlog::logger>("level-off"); auto empty_logger = std::make_shared<spdlog::logger>("level-off");
empty_logger->set_level(spdlog::level::off); empty_logger->set_level(spdlog::level::off);
bench(iters, empty_logger); bench(iters, empty_logger);
auto empty_logger_tracing = std::make_shared<spdlog::logger>("level-off/backtrace-on");
empty_logger_tracing->set_level(spdlog::level::off);
empty_logger_tracing->enable_backtrace(32);
bench(iters, empty_logger_tracing);
} }
void bench_single_threaded(int iters) void bench_single_threaded(int iters)
@ -82,32 +70,18 @@ void bench_single_threaded(int iters)
auto basic_st = spdlog::basic_logger_st("basic_st", "logs/basic_st.log", true); auto basic_st = spdlog::basic_logger_st("basic_st", "logs/basic_st.log", true);
bench(iters, std::move(basic_st)); bench(iters, std::move(basic_st));
auto basic_st_tracing = spdlog::basic_logger_st("basic_st/backtrace-on", "logs/basic_st.log", true);
bench(iters, std::move(basic_st_tracing));
spdlog::info(""); spdlog::info("");
auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files); auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files);
bench(iters, std::move(rotating_st)); bench(iters, std::move(rotating_st));
auto rotating_st_tracing = spdlog::rotating_logger_st("rotating_st/backtrace-on", "logs/rotating_st.log", file_size, rotating_files);
rotating_st_tracing->enable_backtrace(32);
bench(iters, std::move(rotating_st_tracing));
spdlog::info(""); spdlog::info("");
auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log"); auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log");
bench(iters, std::move(daily_st)); bench(iters, std::move(daily_st));
auto daily_st_tracing = spdlog::daily_logger_st("daily_st/backtrace-on", "logs/daily_st.log");
daily_st_tracing->enable_backtrace(32);
bench(iters, std::move(daily_st_tracing));
spdlog::info(""); spdlog::info("");
auto empty_logger = std::make_shared<spdlog::logger>("level-off"); auto empty_logger = std::make_shared<spdlog::logger>("level-off");
empty_logger->set_level(spdlog::level::off); empty_logger->set_level(spdlog::level::off);
bench(iters, empty_logger); bench(iters, empty_logger);
auto empty_logger_tracing = std::make_shared<spdlog::logger>("level-off/backtrace-on");
empty_logger_tracing->set_level(spdlog::level::off);
empty_logger_tracing->enable_backtrace(32);
bench(iters, empty_logger_tracing);
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])

View File

@ -102,19 +102,11 @@ int main(int argc, char *argv[])
benchmark::RegisterBenchmark("disabled-at-compile-time (global logger)", bench_disabled_macro_global_logger, disabled_logger); benchmark::RegisterBenchmark("disabled-at-compile-time (global logger)", bench_disabled_macro_global_logger, disabled_logger);
benchmark::RegisterBenchmark("disabled-at-runtime", bench_logger, disabled_logger); benchmark::RegisterBenchmark("disabled-at-runtime", bench_logger, disabled_logger);
benchmark::RegisterBenchmark("disabled-at-runtime (global logger)", bench_global_logger, disabled_logger); benchmark::RegisterBenchmark("disabled-at-runtime (global logger)", bench_global_logger, disabled_logger);
// with backtrace of 64
auto tracing_disabled_logger = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
tracing_disabled_logger->enable_backtrace(64);
benchmark::RegisterBenchmark("disabled-at-runtime/backtrace", bench_logger, tracing_disabled_logger);
auto null_logger_st = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_st>()); auto null_logger_st = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_st>());
benchmark::RegisterBenchmark("null_sink_st (500_bytes c_str)", bench_c_string, std::move(null_logger_st)); benchmark::RegisterBenchmark("null_sink_st (500_bytes c_str)", bench_c_string, std::move(null_logger_st));
benchmark::RegisterBenchmark("null_sink_st", bench_logger, null_logger_st); benchmark::RegisterBenchmark("null_sink_st", bench_logger, null_logger_st);
benchmark::RegisterBenchmark("null_sink_st (global logger)", bench_global_logger, null_logger_st); benchmark::RegisterBenchmark("null_sink_st (global logger)", bench_global_logger, null_logger_st);
// with backtrace of 64
auto tracing_null_logger_st = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_st>());
tracing_null_logger_st->enable_backtrace(64);
benchmark::RegisterBenchmark("null_sink_st/backtrace", bench_logger, tracing_null_logger_st);
#ifdef __linux #ifdef __linux
bench_dev_null(); bench_dev_null();
@ -126,29 +118,16 @@ int main(int argc, char *argv[])
auto basic_st = spdlog::basic_logger_st("basic_st", "latency_logs/basic_st.log", true); auto basic_st = spdlog::basic_logger_st("basic_st", "latency_logs/basic_st.log", true);
benchmark::RegisterBenchmark("basic_st", bench_logger, std::move(basic_st))->UseRealTime(); benchmark::RegisterBenchmark("basic_st", bench_logger, std::move(basic_st))->UseRealTime();
spdlog::drop("basic_st"); spdlog::drop("basic_st");
// with backtrace of 64
auto tracing_basic_st = spdlog::basic_logger_st("tracing_basic_st", "latency_logs/tracing_basic_st.log", true);
tracing_basic_st->enable_backtrace(64);
benchmark::RegisterBenchmark("basic_st/backtrace", bench_logger, std::move(tracing_basic_st))->UseRealTime();
spdlog::drop("tracing_basic_st");
// rotating st // rotating st
auto rotating_st = spdlog::rotating_logger_st("rotating_st", "latency_logs/rotating_st.log", file_size, rotating_files); auto rotating_st = spdlog::rotating_logger_st("rotating_st", "latency_logs/rotating_st.log", file_size, rotating_files);
benchmark::RegisterBenchmark("rotating_st", bench_logger, std::move(rotating_st))->UseRealTime(); benchmark::RegisterBenchmark("rotating_st", bench_logger, std::move(rotating_st))->UseRealTime();
spdlog::drop("rotating_st"); spdlog::drop("rotating_st");
// with backtrace of 64
auto tracing_rotating_st =
spdlog::rotating_logger_st("tracing_rotating_st", "latency_logs/tracing_rotating_st.log", file_size, rotating_files);
benchmark::RegisterBenchmark("rotating_st/backtrace", bench_logger, std::move(tracing_rotating_st))->UseRealTime();
spdlog::drop("tracing_rotating_st");
// daily st // daily st
auto daily_st = spdlog::daily_logger_mt("daily_st", "latency_logs/daily_st.log"); auto daily_st = spdlog::daily_logger_mt("daily_st", "latency_logs/daily_st.log");
benchmark::RegisterBenchmark("daily_st", bench_logger, std::move(daily_st))->UseRealTime(); benchmark::RegisterBenchmark("daily_st", bench_logger, std::move(daily_st))->UseRealTime();
spdlog::drop("daily_st"); spdlog::drop("daily_st");
auto tracing_daily_st = spdlog::daily_logger_mt("tracing_daily_st", "latency_logs/daily_st.log");
benchmark::RegisterBenchmark("daily_st/backtrace", bench_logger, std::move(tracing_daily_st))->UseRealTime();
spdlog::drop("tracing_daily_st");
// //
// Multi threaded bench, 10 loggers using same logger concurrently // Multi threaded bench, 10 loggers using same logger concurrently
@ -178,12 +157,6 @@ int main(int argc, char *argv[])
auto async_logger = std::make_shared<spdlog::async_logger>( auto async_logger = std::make_shared<spdlog::async_logger>(
"async_logger", std::make_shared<null_sink_mt>(), std::move(tp), spdlog::async_overflow_policy::overrun_oldest); "async_logger", std::make_shared<null_sink_mt>(), std::move(tp), spdlog::async_overflow_policy::overrun_oldest);
benchmark::RegisterBenchmark("async_logger", bench_logger, async_logger)->Threads(n_threads)->UseRealTime(); benchmark::RegisterBenchmark("async_logger", bench_logger, async_logger)->Threads(n_threads)->UseRealTime();
auto async_logger_tracing = std::make_shared<spdlog::async_logger>(
"async_logger_tracing", std::make_shared<null_sink_mt>(), std::move(tp), spdlog::async_overflow_policy::overrun_oldest);
async_logger_tracing->enable_backtrace(32);
benchmark::RegisterBenchmark("async_logger/tracing", bench_logger, async_logger_tracing)->Threads(n_threads)->UseRealTime();
benchmark::Initialize(&argc, argv); benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks(); benchmark::RunSpecifiedBenchmarks();
} }

View File

@ -56,17 +56,6 @@ int main(int, char *[])
spdlog::set_pattern("%+"); // back to default format spdlog::set_pattern("%+"); // back to default format
spdlog::set_level(spdlog::level::info); spdlog::set_level(spdlog::level::info);
// Backtrace support
// Loggers can store in a ring buffer all messages (including debug/trace) for later inspection.
// When needed, call dump_backtrace() to see what happened:
spdlog::enable_backtrace(10); // create ring buffer with capacity of 10 messages
for (int i = 0; i < 100; i++)
{
spdlog::debug("Backtrace message {}", i); // not logged..
}
// e.g. if some error happened:
spdlog::dump_backtrace(); // log them now!
try try
{ {
stdout_logger_example(); stdout_logger_example();

View File

@ -1,75 +0,0 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#ifndef SPDLOG_HEADER_ONLY
# include <spdlog/details/backtracer.h>
#endif
namespace spdlog {
namespace details {
SPDLOG_INLINE backtracer::backtracer(const backtracer &other)
{
std::lock_guard<std::mutex> lock(other.mutex_);
enabled_ = other.enabled();
messages_ = other.messages_;
}
SPDLOG_INLINE backtracer::backtracer(backtracer &&other) SPDLOG_NOEXCEPT
{
std::lock_guard<std::mutex> lock(other.mutex_);
enabled_ = other.enabled();
messages_ = std::move(other.messages_);
}
SPDLOG_INLINE backtracer &backtracer::operator=(backtracer other)
{
std::lock_guard<std::mutex> lock(mutex_);
enabled_ = other.enabled();
messages_ = std::move(other.messages_);
return *this;
}
SPDLOG_INLINE void backtracer::enable(size_t size)
{
std::lock_guard<std::mutex> lock{mutex_};
enabled_.store(true, std::memory_order_relaxed);
messages_ = circular_q<log_msg_buffer>{size};
}
SPDLOG_INLINE void backtracer::disable()
{
std::lock_guard<std::mutex> lock{mutex_};
enabled_.store(false, std::memory_order_relaxed);
}
SPDLOG_INLINE bool backtracer::enabled() const
{
return enabled_.load(std::memory_order_relaxed);
}
SPDLOG_INLINE void backtracer::push_back(const log_msg &msg)
{
std::lock_guard<std::mutex> lock{mutex_};
messages_.push_back(log_msg_buffer{msg});
}
SPDLOG_INLINE bool backtracer::empty() const
{
std::lock_guard<std::mutex> lock{mutex_};
return messages_.empty();
}
// pop all items in the q and apply the given fun on each of them.
SPDLOG_INLINE void backtracer::foreach_pop(std::function<void(const details::log_msg &)> fun)
{
std::lock_guard<std::mutex> lock{mutex_};
while (!messages_.empty())
{
auto &front_msg = messages_.front();
fun(front_msg);
messages_.pop_front();
}
}
} // namespace details
} // namespace spdlog

View File

@ -1,46 +0,0 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#include <spdlog/details/log_msg_buffer.h>
#include <spdlog/details/circular_q.h>
#include <atomic>
#include <mutex>
#include <functional>
// Store log messages in circular buffer.
// Useful for storing debug data in case of error/warning happens.
namespace spdlog {
namespace details {
class SPDLOG_API backtracer
{
mutable std::mutex mutex_;
std::atomic<bool> enabled_{false};
circular_q<log_msg_buffer> messages_;
public:
backtracer() = default;
backtracer(const backtracer &other);
backtracer(backtracer &&other) SPDLOG_NOEXCEPT;
backtracer &operator=(backtracer other);
void enable(size_t size);
void disable();
bool enabled() const;
void push_back(const log_msg &msg);
bool empty() const;
// pop all items in the q and apply the given fun on each of them.
void foreach_pop(std::function<void(const details::log_msg &)> fun);
};
} // namespace details
} // namespace spdlog
#ifdef SPDLOG_HEADER_ONLY
# include "backtracer-inl.h"
#endif

View File

@ -74,11 +74,6 @@ SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr<logger> new_logge
new_logger->flush_on(flush_level_); new_logger->flush_on(flush_level_);
if (backtrace_n_messages_ > 0)
{
new_logger->enable_backtrace(backtrace_n_messages_);
}
if (automatic_registration_) if (automatic_registration_)
{ {
register_logger_(std::move(new_logger)); register_logger_(std::move(new_logger));
@ -147,27 +142,6 @@ SPDLOG_INLINE void registry::set_formatter(std::unique_ptr<formatter> formatter)
} }
} }
SPDLOG_INLINE void registry::enable_backtrace(size_t n_messages)
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
backtrace_n_messages_ = n_messages;
for (auto &l : loggers_)
{
l.second->enable_backtrace(n_messages);
}
}
SPDLOG_INLINE void registry::disable_backtrace()
{
std::lock_guard<std::mutex> lock(logger_map_mutex_);
backtrace_n_messages_ = 0;
for (auto &l : loggers_)
{
l.second->disable_backtrace();
}
}
SPDLOG_INLINE void registry::set_level(level::level_enum log_level) SPDLOG_INLINE void registry::set_level(level::level_enum log_level)
{ {
std::lock_guard<std::mutex> lock(logger_map_mutex_); std::lock_guard<std::mutex> lock(logger_map_mutex_);

View File

@ -53,10 +53,6 @@ public:
// 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 enable_backtrace(size_t n_messages);
void disable_backtrace();
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);
@ -112,7 +108,6 @@ private:
std::unique_ptr<periodic_worker> periodic_flusher_; std::unique_ptr<periodic_worker> periodic_flusher_;
std::shared_ptr<logger> default_logger_; std::shared_ptr<logger> default_logger_;
bool automatic_registration_ = true; bool automatic_registration_ = true;
size_t backtrace_n_messages_ = 0;
}; };
} // namespace details } // namespace details

View File

@ -8,7 +8,6 @@
#endif #endif
#include <spdlog/sinks/sink.h> #include <spdlog/sinks/sink.h>
#include <spdlog/details/backtracer.h>
#include <spdlog/pattern_formatter.h> #include <spdlog/pattern_formatter.h>
#include <cstdio> #include <cstdio>
@ -22,15 +21,13 @@ SPDLOG_INLINE logger::logger(const logger &other)
, level_(other.level_.load(std::memory_order_relaxed)) , level_(other.level_.load(std::memory_order_relaxed))
, flush_level_(other.flush_level_.load(std::memory_order_relaxed)) , flush_level_(other.flush_level_.load(std::memory_order_relaxed))
, custom_err_handler_(other.custom_err_handler_) , custom_err_handler_(other.custom_err_handler_)
, tracer_(other.tracer_)
{} {}
SPDLOG_INLINE logger::logger(logger &&other) SPDLOG_NOEXCEPT : name_(std::move(other.name_)), SPDLOG_INLINE logger::logger(logger &&other) SPDLOG_NOEXCEPT : name_(std::move(other.name_)),
sinks_(std::move(other.sinks_)), sinks_(std::move(other.sinks_)),
level_(other.level_.load(std::memory_order_relaxed)), level_(other.level_.load(std::memory_order_relaxed)),
flush_level_(other.flush_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_)), custom_err_handler_(std::move(other.custom_err_handler_))
tracer_(std::move(other.tracer_))
{} {}
@ -56,7 +53,6 @@ SPDLOG_INLINE void logger::swap(spdlog::logger &other) SPDLOG_NOEXCEPT
other.flush_level_.store(my_level); other.flush_level_.store(my_level);
custom_err_handler_.swap(other.custom_err_handler_); custom_err_handler_.swap(other.custom_err_handler_);
std::swap(tracer_, other.tracer_);
} }
SPDLOG_INLINE void swap(logger &a, logger &b) SPDLOG_INLINE void swap(logger &a, logger &b)
@ -104,23 +100,6 @@ SPDLOG_INLINE void logger::set_pattern(std::string pattern, pattern_time_type ti
set_formatter(std::move(new_formatter)); set_formatter(std::move(new_formatter));
} }
// create new backtrace sink and move to it all our child sinks
SPDLOG_INLINE void logger::enable_backtrace(size_t n_messages)
{
tracer_.enable(n_messages);
}
// restore orig sinks and level and delete the backtrace sink
SPDLOG_INLINE void logger::disable_backtrace()
{
tracer_.disable();
}
SPDLOG_INLINE void logger::dump_backtrace()
{
dump_backtrace_();
}
// flush functions // flush functions
SPDLOG_INLINE void logger::flush() SPDLOG_INLINE void logger::flush()
{ {
@ -162,18 +141,6 @@ SPDLOG_INLINE std::shared_ptr<logger> logger::clone(std::string logger_name)
return cloned; return cloned;
} }
// protected methods
SPDLOG_INLINE void logger::log_it_(const spdlog::details::log_msg &log_msg, bool log_enabled, bool traceback_enabled)
{
if (log_enabled)
{
sink_it_(log_msg);
}
if (traceback_enabled)
{
tracer_.push_back(log_msg);
}
}
SPDLOG_INLINE void logger::sink_it_(const details::log_msg &msg) SPDLOG_INLINE void logger::sink_it_(const details::log_msg &msg)
{ {
@ -207,16 +174,6 @@ SPDLOG_INLINE void logger::flush_()
} }
} }
SPDLOG_INLINE void logger::dump_backtrace_()
{
using details::log_msg;
if (tracer_.enabled() && !tracer_.empty())
{
sink_it_(log_msg{name(), level::info, "****************** Backtrace Start ******************"});
tracer_.foreach_pop([this](const log_msg &msg) { this->sink_it_(msg); });
sink_it_(log_msg{name(), level::info, "****************** Backtrace End ********************"});
}
}
SPDLOG_INLINE bool logger::should_flush_(const details::log_msg &msg) SPDLOG_INLINE bool logger::should_flush_(const details::log_msg &msg)
{ {

View File

@ -16,7 +16,6 @@
#include <spdlog/common.h> #include <spdlog/common.h>
#include <spdlog/details/log_msg.h> #include <spdlog/details/log_msg.h>
#include <spdlog/details/backtracer.h>
#include <vector> #include <vector>
@ -105,27 +104,24 @@ public:
void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg) void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg)
{ {
bool log_enabled = should_log(lvl); bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled(); if (!log_enabled)
if (!log_enabled && !traceback_enabled)
{ {
return; return;
} }
details::log_msg log_msg(log_time, loc, name_, lvl, msg); details::log_msg log_msg(log_time, loc, name_, lvl, msg);
log_it_(log_msg, log_enabled, traceback_enabled); sink_it_(log_msg);
} }
void log(source_loc loc, level::level_enum lvl, string_view_t msg) void log(source_loc loc, level::level_enum lvl, string_view_t msg)
{ {
bool log_enabled = should_log(lvl); bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled(); if (!log_enabled)
if (!log_enabled && !traceback_enabled)
{ {
return; return;
} }
details::log_msg log_msg(loc, name_, lvl, msg); sink_it_(details::log_msg(loc, name_, lvl, msg));
log_it_(log_msg, log_enabled, traceback_enabled);
} }
void log(level::level_enum lvl, string_view_t msg) void log(level::level_enum lvl, string_view_t msg)
@ -211,16 +207,13 @@ public:
return msg_level >= level_.load(std::memory_order_relaxed); return msg_level >= level_.load(std::memory_order_relaxed);
} }
// return true if backtrace logging is enabled. // set the level of logging
bool should_backtrace() const
{
return tracer_.enabled();
}
void set_level(level::level_enum log_level); void set_level(level::level_enum log_level);
// return the active log level
level::level_enum level() const; level::level_enum level() const;
// return the name of the logger
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.
@ -233,12 +226,6 @@ public:
// Note: each sink will get a new instance of a formatter object, replacing the old one. // Note: each sink will get a new instance of a formatter object, replacing the old one.
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);
// backtrace support.
// efficiently store all debug/trace messages in a circular buffer until needed for debugging.
void enable_backtrace(size_t n_messages);
void disable_backtrace();
void dump_backtrace();
// flush functions // flush functions
void flush(); void flush();
void flush_on(level::level_enum log_level); void flush_on(level::level_enum log_level);
@ -261,15 +248,13 @@ protected:
spdlog::level_t level_{level::info}; spdlog::level_t level_{level::info};
spdlog::level_t flush_level_{level::off}; spdlog::level_t flush_level_{level::off};
err_handler custom_err_handler_{nullptr}; err_handler custom_err_handler_{nullptr};
details::backtracer tracer_;
// common implementation for after templated public api has been resolved // common implementation for after templated public api has been resolved
template<typename... Args> template<typename... Args>
void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&...args) void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&...args)
{ {
bool log_enabled = should_log(lvl); bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled(); if (!log_enabled)
if (!log_enabled && !traceback_enabled)
{ {
return; return;
} }
@ -281,20 +266,14 @@ protected:
#else #else
fmt::vformat_to(fmt::appender(buf), fmt, fmt::make_format_args(args...)); fmt::vformat_to(fmt::appender(buf), fmt, fmt::make_format_args(args...));
#endif #endif
sink_it_(details::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()));
log_it_(log_msg, log_enabled, traceback_enabled);
} }
SPDLOG_LOGGER_CATCH(loc) SPDLOG_LOGGER_CATCH(loc)
} }
// log the given message (if the given log level is high enough)
// log the given message (if the given log level is high enough),
// and save backtrace (if backtrace is enabled).
void log_it_(const details::log_msg &log_msg, bool log_enabled, bool traceback_enabled);
virtual void sink_it_(const details::log_msg &msg); virtual void sink_it_(const details::log_msg &msg);
virtual void flush_(); virtual void flush_();
void dump_backtrace_();
bool should_flush_(const details::log_msg &msg); bool should_flush_(const details::log_msg &msg);
// handle errors during logging. // handle errors during logging.

View File

@ -32,21 +32,6 @@ SPDLOG_INLINE void set_pattern(std::string pattern, pattern_time_type time_type)
set_formatter(std::unique_ptr<spdlog::formatter>(new pattern_formatter(std::move(pattern), time_type))); set_formatter(std::unique_ptr<spdlog::formatter>(new pattern_formatter(std::move(pattern), time_type)));
} }
SPDLOG_INLINE void enable_backtrace(size_t n_messages)
{
details::registry::instance().enable_backtrace(n_messages);
}
SPDLOG_INLINE void disable_backtrace()
{
details::registry::instance().disable_backtrace();
}
SPDLOG_INLINE void dump_backtrace()
{
default_logger_raw()->dump_backtrace();
}
SPDLOG_INLINE level::level_enum get_level() SPDLOG_INLINE level::level_enum get_level()
{ {
return default_logger_raw()->level(); return default_logger_raw()->level();

View File

@ -58,14 +58,6 @@ SPDLOG_API void set_formatter(std::unique_ptr<spdlog::formatter> formatter);
// example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v"); // example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v");
SPDLOG_API void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local); SPDLOG_API void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
// enable global backtrace support
SPDLOG_API void enable_backtrace(size_t n_messages);
// disable global backtrace support
SPDLOG_API void disable_backtrace();
// call dump backtrace on default logger
SPDLOG_API void dump_backtrace();
// Get global logging level // Get global logging level
SPDLOG_API level::level_enum get_level(); SPDLOG_API level::level_enum get_level();

View File

@ -7,7 +7,6 @@
#include <spdlog/spdlog-inl.h> #include <spdlog/spdlog-inl.h>
#include <spdlog/common-inl.h> #include <spdlog/common-inl.h>
#include <spdlog/details/backtracer-inl.h>
#include <spdlog/details/registry-inl.h> #include <spdlog/details/registry-inl.h>
#include <spdlog/details/os-inl.h> #include <spdlog/details/os-inl.h>
#include <spdlog/pattern_formatter-inl.h> #include <spdlog/pattern_formatter-inl.h>

View File

@ -39,8 +39,7 @@ set(SPDLOG_UTESTS_SOURCES
test_dup_filter.cpp test_dup_filter.cpp
test_fmt_helper.cpp test_fmt_helper.cpp
test_stdout_api.cpp test_stdout_api.cpp
test_backtrace.cpp test_create_dir.cpp
test_create_dir.cpp
test_custom_callbacks.cpp test_custom_callbacks.cpp
test_cfg.cpp test_cfg.cpp
test_time_point.cpp test_time_point.cpp

View File

@ -1,78 +0,0 @@
#include "includes.h"
#include "test_sink.h"
#include "spdlog/async.h"
TEST_CASE("bactrace1", "[bactrace]")
{
using spdlog::sinks::test_sink_st;
auto test_sink = std::make_shared<test_sink_st>();
size_t backtrace_size = 5;
spdlog::logger logger("test-backtrace", test_sink);
logger.set_pattern("%v");
logger.enable_backtrace(backtrace_size);
logger.info("info message");
for (int i = 0; i < 100; i++)
logger.debug("debug message {}", i);
REQUIRE(test_sink->lines().size() == 1);
REQUIRE(test_sink->lines()[0] == "info message");
logger.dump_backtrace();
REQUIRE(test_sink->lines().size() == backtrace_size + 3);
REQUIRE(test_sink->lines()[1] == "****************** Backtrace Start ******************");
REQUIRE(test_sink->lines()[2] == "debug message 95");
REQUIRE(test_sink->lines()[3] == "debug message 96");
REQUIRE(test_sink->lines()[4] == "debug message 97");
REQUIRE(test_sink->lines()[5] == "debug message 98");
REQUIRE(test_sink->lines()[6] == "debug message 99");
REQUIRE(test_sink->lines()[7] == "****************** Backtrace End ********************");
}
TEST_CASE("bactrace-empty", "[bactrace]")
{
using spdlog::sinks::test_sink_st;
auto test_sink = std::make_shared<test_sink_st>();
size_t backtrace_size = 5;
spdlog::logger logger("test-backtrace", test_sink);
logger.set_pattern("%v");
logger.enable_backtrace(backtrace_size);
logger.dump_backtrace();
REQUIRE(test_sink->lines().size() == 0);
}
TEST_CASE("bactrace-async", "[bactrace]")
{
using spdlog::sinks::test_sink_mt;
auto test_sink = std::make_shared<test_sink_mt>();
using spdlog::details::os::sleep_for_millis;
size_t backtrace_size = 5;
spdlog::init_thread_pool(120, 1);
auto logger = std::make_shared<spdlog::async_logger>("test-bactrace-async", test_sink, spdlog::thread_pool());
logger->set_pattern("%v");
logger->enable_backtrace(backtrace_size);
logger->info("info message");
for (int i = 0; i < 100; i++)
logger->debug("debug message {}", i);
sleep_for_millis(100);
REQUIRE(test_sink->lines().size() == 1);
REQUIRE(test_sink->lines()[0] == "info message");
logger->dump_backtrace();
sleep_for_millis(100); // give time for the async dump to complete
REQUIRE(test_sink->lines().size() == backtrace_size + 3);
REQUIRE(test_sink->lines()[1] == "****************** Backtrace Start ******************");
REQUIRE(test_sink->lines()[2] == "debug message 95");
REQUIRE(test_sink->lines()[3] == "debug message 96");
REQUIRE(test_sink->lines()[4] == "debug message 97");
REQUIRE(test_sink->lines()[5] == "debug message 98");
REQUIRE(test_sink->lines()[6] == "debug message 99");
REQUIRE(test_sink->lines()[7] == "****************** Backtrace End ********************");
}