Merge remote-tracking branch 'origin/v1.x' into attributes

pull/2595/head
Bailey Chittle 3 years ago
commit f5bde10533

@ -82,6 +82,7 @@ option(SPDLOG_SANITIZE_ADDRESS "Enable address sanitizer in tests" OFF)
option(SPDLOG_BUILD_WARNINGS "Enable compiler warnings" OFF)
# install options
option(SPDLOG_SYSTEM_INCLUDES "Include as system headers (skip for clang-tidy)." OFF)
option(SPDLOG_INSTALL "Generate the install target" ${SPDLOG_MASTER_PROJECT})
option(SPDLOG_USE_STD_FORMAT "Use std::format instead of fmt library." OFF)
option(SPDLOG_FMT_EXTERNAL "Use external fmt library instead of bundled" OFF)
@ -170,8 +171,14 @@ endif()
add_library(spdlog::spdlog ALIAS spdlog)
set(SPDLOG_INCLUDES_LEVEL "")
if(SPDLOG_SYSTEM_INCLUDES)
set(SPDLOG_INCLUDES_LEVEL "SYSTEM")
endif()
target_compile_definitions(spdlog PUBLIC SPDLOG_COMPILED_LIB)
target_include_directories(spdlog PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
target_include_directories(spdlog ${SPDLOG_INCLUDES_LEVEL} PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
target_link_libraries(spdlog PUBLIC Threads::Threads)
spdlog_enable_warnings(spdlog)
@ -190,7 +197,7 @@ endif()
add_library(spdlog_header_only INTERFACE)
add_library(spdlog::spdlog_header_only ALIAS spdlog_header_only)
target_include_directories(spdlog_header_only INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
target_include_directories(spdlog_header_only ${SPDLOG_INCLUDES_LEVEL} INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
target_link_libraries(spdlog_header_only INTERFACE Threads::Threads)

@ -54,6 +54,12 @@ SPDLOG_INLINE void backtracer::push_back(const log_msg &msg)
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)
{

@ -32,6 +32,7 @@ public:
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);

@ -49,7 +49,7 @@ public:
push_cv_.notify_one();
}
// try to dequeue item. if no item found. wait up to timeout and try again
// dequeue with a timeout.
// Return true, if succeeded dequeue item, false otherwise
bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration)
{
@ -66,6 +66,18 @@ public:
return true;
}
// blocking dequeue without a timeout.
void dequeue(T &popped_item)
{
{
std::unique_lock<std::mutex> lock(queue_mutex_);
push_cv_.wait(lock, [this] { return !this->q_.empty(); });
popped_item = std::move(q_.front());
q_.pop_front();
}
pop_cv_.notify_one();
}
#else
// apparently mingw deadlocks if the mutex is released before cv.notify_one(),
// so release the mutex at the very end each function.
@ -87,7 +99,7 @@ public:
push_cv_.notify_one();
}
// try to dequeue item. if no item found. wait up to timeout and try again
// dequeue with a timeout.
// Return true, if succeeded dequeue item, false otherwise
bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration)
{
@ -102,6 +114,16 @@ public:
return true;
}
// blocking dequeue without a timeout.
void dequeue(T &popped_item)
{
std::unique_lock<std::mutex> lock(queue_mutex_);
push_cv_.wait(lock, [this] { return !this->q_.empty(); });
popped_item = std::move(q_.front());
q_.pop_front();
pop_cv_.notify_one();
}
#endif
size_t overrun_counter()

@ -236,8 +236,8 @@ SPDLOG_INLINE size_t filesize(FILE *f)
# else
int fd = ::fileno(f);
# endif
// 64 bits(but not in osx or cygwin, where fstat64 is deprecated)
# if (defined(__linux__) || defined(__sun) || defined(_AIX)) && (defined(__LP64__) || defined(_LP64))
// 64 bits(but not in osx, linux/musl or cygwin, where fstat64 is deprecated)
# if ((defined(__linux__) && defined(__GLIBC__)) || defined(__sun) || defined(_AIX)) && (defined(__LP64__) || defined(_LP64))
struct stat64 st;
if (::fstat64(fd, &st) == 0)
{

@ -16,6 +16,7 @@
#include <unistd.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <string>

@ -108,11 +108,7 @@ void SPDLOG_INLINE thread_pool::worker_loop_()
bool SPDLOG_INLINE thread_pool::process_next_msg_()
{
async_msg incoming_async_msg;
bool dequeued = q_.dequeue_for(incoming_async_msg, std::chrono::seconds(10));
if (!dequeued)
{
return true;
}
q_.dequeue(incoming_async_msg);
switch (incoming_async_msg.msg_type)
{

@ -210,7 +210,7 @@ SPDLOG_INLINE void logger::flush_()
SPDLOG_INLINE void logger::dump_backtrace_()
{
using details::log_msg;
if (tracer_.enabled())
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); });

@ -20,7 +20,7 @@
// #include <spdlog/sinks/dup_filter_sink.h>
//
// int main() {
// auto dup_filter = std::make_shared<dup_filter_sink_st>(std::chrono::seconds(5));
// auto dup_filter = std::make_shared<dup_filter_sink_st>(std::chrono::seconds(5), level::info);
// dup_filter->add_sink(std::make_shared<stdout_color_sink_mt>());
// spdlog::logger l("logger", dup_filter);
// l.info("Hello");
@ -41,8 +41,9 @@ class dup_filter_sink : public dist_sink<Mutex>
{
public:
template<class Rep, class Period>
explicit dup_filter_sink(std::chrono::duration<Rep, Period> max_skip_duration)
explicit dup_filter_sink(std::chrono::duration<Rep, Period> max_skip_duration, level::level_enum notification_level = level::info)
: max_skip_duration_{max_skip_duration}
, log_level_{notification_level}
{}
protected:
@ -50,6 +51,7 @@ protected:
log_clock::time_point last_msg_time_;
std::string last_msg_payload_;
size_t skip_counter_ = 0;
level::level_enum log_level_;
void sink_it_(const details::log_msg &msg) override
{
@ -67,7 +69,7 @@ protected:
auto msg_size = ::snprintf(buf, sizeof(buf), "Skipped %u duplicate messages..", static_cast<unsigned>(skip_counter_));
if (msg_size > 0 && static_cast<size_t>(msg_size) < sizeof(buf))
{
details::log_msg skipped_msg{msg.source, msg.logger_name, level::info, string_view_t{buf, static_cast<size_t>(msg_size)}};
details::log_msg skipped_msg{msg.source, msg.logger_name, log_level_, string_view_t{buf, static_cast<size_t>(msg_size)}};
dist_sink<Mutex>::sink_it_(skipped_msg);
}
}

@ -26,13 +26,13 @@ class msvc_sink : public base_sink<Mutex>
{
public:
msvc_sink() = default;
msvc_sink(bool check_ebugger_present)
: check_debbugger_present_{check_ebugger_present} {};
msvc_sink(bool check_debugger_present)
: check_debugger_present_{check_debugger_present} {};
protected:
void sink_it_(const details::log_msg &msg) override
{
if (check_debbugger_present_ && !IsDebuggerPresent())
if (check_debugger_present_ && !IsDebuggerPresent())
{
return;
}
@ -44,7 +44,7 @@ protected:
void flush_() override {}
bool check_debbugger_present_ = true;
bool check_debugger_present_ = true;
};
using msvc_sink_mt = msvc_sink<std::mutex>;

@ -32,4 +32,5 @@
#include "spdlog/sinks/ostream_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/msvc_sink.h"
#include "spdlog/pattern_formatter.h"

@ -31,6 +31,19 @@ TEST_CASE("bactrace1", "[bactrace]")
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;

@ -43,6 +43,26 @@ TEST_CASE("dequeue-empty-wait", "[mpmc_blocking_q]")
REQUIRE(delta_ms <= wait_ms + tolerance_wait);
}
TEST_CASE("dequeue-full-nowait", "[mpmc_blocking_q]")
{
spdlog::details::mpmc_blocking_queue<int> q(1);
q.enqueue(42);
int item = 0;
q.dequeue_for(item, milliseconds::zero());
REQUIRE(item == 42);
}
TEST_CASE("dequeue-full-wait", "[mpmc_blocking_q]")
{
spdlog::details::mpmc_blocking_queue<int> q(1);
q.enqueue(42);
int item = 0;
q.dequeue(item);
REQUIRE(item == 42);
}
TEST_CASE("enqueue_nowait", "[mpmc_blocking_q]")
{
@ -95,12 +115,12 @@ TEST_CASE("full_queue", "[mpmc_blocking_q]")
for (int i = 1; i < static_cast<int>(q_size); i++)
{
int item = -1;
q.dequeue_for(item, milliseconds(0));
q.dequeue(item);
REQUIRE(item == i);
}
// last item pushed has overridden the oldest.
int item = -1;
q.dequeue_for(item, milliseconds(0));
q.dequeue(item);
REQUIRE(item == 123456);
}

Loading…
Cancel
Save