mirror of
https://github.com/gabime/spdlog.git
synced 2024-11-16 00:45:48 +08:00
ringbuffer_sink: replaced last_raw() and last_formatted() with drain_raw() and drain_formatted() and added tests
This commit is contained in:
parent
d8829e7714
commit
8f7400731e
@ -11,6 +11,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace sinks {
|
namespace sinks {
|
||||||
@ -25,34 +26,27 @@ public:
|
|||||||
: q_{n_items}
|
: q_{n_items}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::vector<details::log_msg_buffer> last_raw(size_t lim = 0)
|
void drain_raw(std::function<void(const details::log_msg_buffer&)> callback)
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
||||||
auto items_available = q_.size();
|
while (!q_.empty())
|
||||||
auto n_items = lim > 0 ? (std::min)(lim, items_available) : items_available;
|
|
||||||
std::vector<details::log_msg_buffer> ret;
|
|
||||||
ret.reserve(n_items);
|
|
||||||
for (size_t i = (items_available - n_items); i < items_available; i++)
|
|
||||||
{
|
{
|
||||||
ret.push_back(q_.at(i));
|
callback(q_.front());
|
||||||
|
q_.pop_front();
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> last_formatted(size_t lim = 0)
|
void drain(std::function<void(std::string_view)> callback)
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
||||||
auto items_available = q_.size();
|
memory_buf_t formatted;
|
||||||
auto n_items = lim > 0 ? (std::min)(lim, items_available) : items_available;
|
while (!q_.empty())
|
||||||
std::vector<std::string> ret;
|
|
||||||
ret.reserve(n_items);
|
|
||||||
for (size_t i = (items_available - n_items); i < items_available; i++)
|
|
||||||
{
|
{
|
||||||
memory_buf_t formatted;
|
formatted.clear();
|
||||||
base_sink<Mutex>::formatter_->format(q_.at(i), formatted);
|
base_sink<Mutex>::formatter_->format(q_.front(), formatted);
|
||||||
ret.push_back(SPDLOG_BUF_TO_STRING(formatted));
|
callback(std::string_view (formatted.data(), formatted.size()));
|
||||||
|
q_.pop_front();
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -70,5 +64,4 @@ using ringbuffer_sink_mt = ringbuffer_sink<std::mutex>;
|
|||||||
using ringbuffer_sink_st = ringbuffer_sink<details::null_mutex>;
|
using ringbuffer_sink_st = ringbuffer_sink<details::null_mutex>;
|
||||||
|
|
||||||
} // namespace sinks
|
} // namespace sinks
|
||||||
|
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -44,7 +44,9 @@ set(SPDLOG_UTESTS_SOURCES
|
|||||||
test_cfg.cpp
|
test_cfg.cpp
|
||||||
test_time_point.cpp
|
test_time_point.cpp
|
||||||
test_stopwatch.cpp
|
test_stopwatch.cpp
|
||||||
test_circular_q.cpp)
|
test_circular_q.cpp
|
||||||
|
test_ringbuffer_sink.cpp
|
||||||
|
)
|
||||||
|
|
||||||
if(NOT SPDLOG_NO_EXCEPTIONS)
|
if(NOT SPDLOG_NO_EXCEPTIONS)
|
||||||
list(APPEND SPDLOG_UTESTS_SOURCES test_errors.cpp)
|
list(APPEND SPDLOG_UTESTS_SOURCES test_errors.cpp)
|
||||||
|
80
tests/test_ringbuffer_sink.cpp
Normal file
80
tests/test_ringbuffer_sink.cpp
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#include "includes.h"
|
||||||
|
#include "spdlog/sinks/ringbuffer_sink.h"
|
||||||
|
|
||||||
|
TEST_CASE("test_drain", "[ringbuffer_sink]")
|
||||||
|
{
|
||||||
|
const size_t sink_size = 3;
|
||||||
|
auto sink = std::make_shared<spdlog::sinks::ringbuffer_sink_mt>(sink_size);
|
||||||
|
spdlog::logger l("logger", sink);
|
||||||
|
l.set_pattern("*** %v");
|
||||||
|
|
||||||
|
// log more than the sink size by one and test that the first message is dropped
|
||||||
|
// test 3 times to make sure the ringbuffer is working correctly multiple times
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < sink_size + 1; ++i)
|
||||||
|
{
|
||||||
|
l.info("{}", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
sink->drain([&](std::string_view msg) {
|
||||||
|
REQUIRE(msg == fmt::format("*** {}{}", counter + 1, spdlog::details::os::default_eol));
|
||||||
|
counter++;
|
||||||
|
});
|
||||||
|
|
||||||
|
REQUIRE(counter == sink_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("test_drain_raw", "[ringbuffer_sink]")
|
||||||
|
{
|
||||||
|
const size_t sink_size = 3;
|
||||||
|
auto sink = std::make_shared<spdlog::sinks::ringbuffer_sink_mt>(sink_size);
|
||||||
|
spdlog::logger l("logger", sink);
|
||||||
|
|
||||||
|
// log more than the sink size by one and test that the first message is dropped
|
||||||
|
// test 3 times to make sure the ringbuffer is working correctly multiple times
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < sink_size + 1; ++i)
|
||||||
|
{
|
||||||
|
l.info("{}", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
sink->drain_raw([&](const spdlog::details::log_msg_buffer &buffer) {
|
||||||
|
REQUIRE(buffer.payload.data() == std::to_string(counter + 1));
|
||||||
|
counter++;
|
||||||
|
});
|
||||||
|
|
||||||
|
REQUIRE(counter == sink_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("test_empty", "[ringbuffer_sink]")
|
||||||
|
{
|
||||||
|
const size_t sink_size = 3;
|
||||||
|
auto sink = std::make_shared<spdlog::sinks::ringbuffer_sink_mt>(sink_size);
|
||||||
|
spdlog::logger l("logger", sink);
|
||||||
|
|
||||||
|
sink->drain([&](std::string_view msg) {
|
||||||
|
REQUIRE_FALSE(true); // should not be called since the sink is empty
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("test_empty_size", "[ringbuffer_sink]")
|
||||||
|
{
|
||||||
|
const size_t sink_size = 0;
|
||||||
|
auto sink = std::make_shared<spdlog::sinks::ringbuffer_sink_mt>(sink_size);
|
||||||
|
spdlog::logger l("logger", sink);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sink_size + 1; ++i)
|
||||||
|
{
|
||||||
|
l.info("{}", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
sink->drain([&](std::string_view msg) {
|
||||||
|
REQUIRE_FALSE(true); // should not be called since the sink size is 0
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user