mirror of
https://github.com/gabime/spdlog.git
synced 2024-11-15 08:25:43 +08:00
clang format
This commit is contained in:
parent
230e15f499
commit
9d52261185
@ -11,11 +11,11 @@
|
|||||||
#include "spdlog/sinks/basic_file_sink.h"
|
#include "spdlog/sinks/basic_file_sink.h"
|
||||||
|
|
||||||
#if defined(SPDLOG_USE_STD_FORMAT)
|
#if defined(SPDLOG_USE_STD_FORMAT)
|
||||||
# include <format>
|
#include <format>
|
||||||
#elif defined(SPDLOG_FMT_EXTERNAL)
|
#elif defined(SPDLOG_FMT_EXTERNAL)
|
||||||
# include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#else
|
#else
|
||||||
# include "spdlog/fmt/bundled/format.h"
|
#include "spdlog/fmt/bundled/format.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -34,17 +34,15 @@ using namespace utils;
|
|||||||
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);
|
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(push)
|
#pragma warning(push)
|
||||||
# pragma warning(disable : 4996) // disable fopen warning under msvc
|
#pragma warning(disable : 4996) // disable fopen warning under msvc
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
int count_lines(const char *filename)
|
int count_lines(const char *filename) {
|
||||||
{
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
auto *infile = fopen(filename, "r");
|
auto *infile = fopen(filename, "r");
|
||||||
int ch;
|
int ch;
|
||||||
while (EOF != (ch = getc(infile)))
|
while (EOF != (ch = getc(infile))) {
|
||||||
{
|
|
||||||
if ('\n' == ch)
|
if ('\n' == ch)
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
@ -53,35 +51,31 @@ int count_lines(const char *filename)
|
|||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void verify_file(const char *filename, int expected_count)
|
void verify_file(const char *filename, int expected_count) {
|
||||||
{
|
|
||||||
spdlog::info("Verifying {} to contain {} line..", filename, expected_count);
|
spdlog::info("Verifying {} to contain {} line..", filename, expected_count);
|
||||||
auto count = count_lines(filename);
|
auto count = count_lines(filename);
|
||||||
if (count != expected_count)
|
if (count != expected_count) {
|
||||||
{
|
spdlog::error("Test failed. {} has {} lines instead of {}", filename, count,
|
||||||
spdlog::error("Test failed. {} has {} lines instead of {}", filename, count, expected_count);
|
expected_count);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
spdlog::info("Line count OK ({})\n", count);
|
spdlog::info("Line count OK ({})\n", count);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
|
||||||
|
|
||||||
int howmany = 1000000;
|
int howmany = 1000000;
|
||||||
int queue_size = std::min(howmany + 2, 8192);
|
int queue_size = std::min(howmany + 2, 8192);
|
||||||
int threads = 10;
|
int threads = 10;
|
||||||
int iters = 3;
|
int iters = 3;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
spdlog::set_pattern("[%^%l%$] %v");
|
spdlog::set_pattern("[%^%l%$] %v");
|
||||||
if (argc == 1)
|
if (argc == 1) {
|
||||||
{
|
|
||||||
spdlog::info("Usage: {} <message_count> <threads> <q_size> <iterations>", argv[0]);
|
spdlog::info("Usage: {} <message_count> <threads> <q_size> <iterations>", argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -90,11 +84,9 @@ int main(int argc, char *argv[])
|
|||||||
howmany = atoi(argv[1]);
|
howmany = atoi(argv[1]);
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
threads = atoi(argv[2]);
|
threads = atoi(argv[2]);
|
||||||
if (argc > 3)
|
if (argc > 3) {
|
||||||
{
|
|
||||||
queue_size = atoi(argv[3]);
|
queue_size = atoi(argv[3]);
|
||||||
if (queue_size > 500000)
|
if (queue_size > 500000) {
|
||||||
{
|
|
||||||
spdlog::error("Max queue size allowed: 500,000");
|
spdlog::error("Max queue size allowed: 500,000");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -108,7 +100,8 @@ int main(int argc, char *argv[])
|
|||||||
spdlog::info("Messages : {:L}", howmany);
|
spdlog::info("Messages : {:L}", howmany);
|
||||||
spdlog::info("Threads : {:L}", threads);
|
spdlog::info("Threads : {:L}", threads);
|
||||||
spdlog::info("Queue : {:L} slots", queue_size);
|
spdlog::info("Queue : {:L} slots", queue_size);
|
||||||
spdlog::info("Queue memory : {:L} x {:L} = {:L} KB ", queue_size, slot_size, (queue_size * slot_size) / 1024);
|
spdlog::info("Queue memory : {:L} x {:L} = {:L} KB ", queue_size, slot_size,
|
||||||
|
(queue_size * slot_size) / 1024);
|
||||||
spdlog::info("Total iters : {:L}", iters);
|
spdlog::info("Total iters : {:L}", iters);
|
||||||
spdlog::info("-------------------------------------------------");
|
spdlog::info("-------------------------------------------------");
|
||||||
|
|
||||||
@ -117,11 +110,11 @@ int main(int argc, char *argv[])
|
|||||||
spdlog::info("*********************************");
|
spdlog::info("*********************************");
|
||||||
spdlog::info("Queue Overflow Policy: block");
|
spdlog::info("Queue Overflow Policy: block");
|
||||||
spdlog::info("*********************************");
|
spdlog::info("*********************************");
|
||||||
for (int i = 0; i < iters; i++)
|
for (int i = 0; i < iters; i++) {
|
||||||
{
|
|
||||||
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
|
||||||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
|
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
|
||||||
auto logger = std::make_shared<async_logger>("async_logger", std::move(file_sink), std::move(tp), async_overflow_policy::block);
|
auto logger = std::make_shared<async_logger>(
|
||||||
|
"async_logger", std::move(file_sink), std::move(tp), async_overflow_policy::block);
|
||||||
bench_mt(howmany, std::move(logger), threads);
|
bench_mt(howmany, std::move(logger), threads);
|
||||||
// verify_file(filename, howmany);
|
// verify_file(filename, howmany);
|
||||||
}
|
}
|
||||||
@ -132,18 +125,16 @@ int main(int argc, char *argv[])
|
|||||||
spdlog::info("*********************************");
|
spdlog::info("*********************************");
|
||||||
// do same test but discard oldest if queue is full instead of blocking
|
// do same test but discard oldest if queue is full instead of blocking
|
||||||
filename = "logs/basic_async-overrun.log";
|
filename = "logs/basic_async-overrun.log";
|
||||||
for (int i = 0; i < iters; i++)
|
for (int i = 0; i < iters; i++) {
|
||||||
{
|
|
||||||
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
|
||||||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
|
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
|
||||||
auto logger =
|
auto logger =
|
||||||
std::make_shared<async_logger>("async_logger", std::move(file_sink), std::move(tp), async_overflow_policy::overrun_oldest);
|
std::make_shared<async_logger>("async_logger", std::move(file_sink), std::move(tp),
|
||||||
|
async_overflow_policy::overrun_oldest);
|
||||||
bench_mt(howmany, std::move(logger), threads);
|
bench_mt(howmany, std::move(logger), threads);
|
||||||
}
|
}
|
||||||
spdlog::shutdown();
|
spdlog::shutdown();
|
||||||
}
|
} catch (std::exception &ex) {
|
||||||
catch (std::exception &ex)
|
|
||||||
{
|
|
||||||
std::cerr << "Error: " << ex.what() << std::endl;
|
std::cerr << "Error: " << ex.what() << std::endl;
|
||||||
perror("Last error");
|
perror("Last error");
|
||||||
return 1;
|
return 1;
|
||||||
@ -151,32 +142,28 @@ int main(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_fun(std::shared_ptr<spdlog::logger> logger, int howmany)
|
void thread_fun(std::shared_ptr<spdlog::logger> logger, int howmany) {
|
||||||
{
|
for (int i = 0; i < howmany; i++) {
|
||||||
for (int i = 0; i < howmany; i++)
|
|
||||||
{
|
|
||||||
logger->info("Hello logger: msg number {}", i);
|
logger->info("Hello logger: msg number {}", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> logger, int thread_count)
|
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> logger, int thread_count) {
|
||||||
{
|
|
||||||
using std::chrono::high_resolution_clock;
|
using std::chrono::high_resolution_clock;
|
||||||
vector<std::thread> threads;
|
vector<std::thread> threads;
|
||||||
auto start = high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
|
|
||||||
int msgs_per_thread = howmany / thread_count;
|
int msgs_per_thread = howmany / thread_count;
|
||||||
int msgs_per_thread_mod = howmany % thread_count;
|
int msgs_per_thread_mod = howmany % thread_count;
|
||||||
for (int t = 0; t < thread_count; ++t)
|
for (int t = 0; t < thread_count; ++t) {
|
||||||
{
|
|
||||||
if (t == 0 && msgs_per_thread_mod)
|
if (t == 0 && msgs_per_thread_mod)
|
||||||
threads.push_back(std::thread(thread_fun, logger, msgs_per_thread + msgs_per_thread_mod));
|
threads.push_back(
|
||||||
|
std::thread(thread_fun, logger, msgs_per_thread + msgs_per_thread_mod));
|
||||||
else
|
else
|
||||||
threads.push_back(std::thread(thread_fun, logger, msgs_per_thread));
|
threads.push_back(std::thread(thread_fun, logger, msgs_per_thread));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &t : threads)
|
for (auto &t : threads) {
|
||||||
{
|
|
||||||
t.join();
|
t.join();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
103
bench/bench.cpp
103
bench/bench.cpp
@ -13,11 +13,11 @@
|
|||||||
#include "spdlog/sinks/rotating_file_sink.h"
|
#include "spdlog/sinks/rotating_file_sink.h"
|
||||||
|
|
||||||
#if defined(SPDLOG_USE_STD_FORMAT)
|
#if defined(SPDLOG_USE_STD_FORMAT)
|
||||||
# include <format>
|
#include <format>
|
||||||
#elif defined(SPDLOG_FMT_EXTERNAL)
|
#elif defined(SPDLOG_FMT_EXTERNAL)
|
||||||
# include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#else
|
#else
|
||||||
# include "spdlog/fmt/bundled/format.h"
|
#include "spdlog/fmt/bundled/format.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -37,22 +37,25 @@ static const size_t file_size = 30 * 1024 * 1024;
|
|||||||
static const size_t rotating_files = 5;
|
static const size_t rotating_files = 5;
|
||||||
static const int max_threads = 1000;
|
static const int max_threads = 1000;
|
||||||
|
|
||||||
void bench_threaded_logging(size_t threads, int iters)
|
void bench_threaded_logging(size_t threads, int iters) {
|
||||||
{
|
|
||||||
spdlog::info("**************************************************************");
|
spdlog::info("**************************************************************");
|
||||||
spdlog::info(spdlog::fmt_lib::format(std::locale("en_US.UTF-8"), "Multi threaded: {:L} threads, {:L} messages", threads, iters));
|
spdlog::info(spdlog::fmt_lib::format(
|
||||||
|
std::locale("en_US.UTF-8"), "Multi threaded: {:L} threads, {:L} messages", threads, iters));
|
||||||
spdlog::info("**************************************************************");
|
spdlog::info("**************************************************************");
|
||||||
|
|
||||||
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);
|
auto basic_mt_tracing =
|
||||||
|
spdlog::basic_logger_mt("basic_mt/backtrace-on", "logs/basic_mt.log", true);
|
||||||
basic_mt_tracing->enable_backtrace(32);
|
basic_mt_tracing->enable_backtrace(32);
|
||||||
bench_mt(iters, std::move(basic_mt_tracing), threads);
|
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);
|
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);
|
rotating_mt_tracing->enable_backtrace(32);
|
||||||
bench_mt(iters, std::move(rotating_mt_tracing), threads);
|
bench_mt(iters, std::move(rotating_mt_tracing), threads);
|
||||||
|
|
||||||
@ -73,22 +76,25 @@ void bench_threaded_logging(size_t threads, int iters)
|
|||||||
bench(iters, empty_logger_tracing);
|
bench(iters, empty_logger_tracing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bench_single_threaded(int iters)
|
void bench_single_threaded(int iters) {
|
||||||
{
|
|
||||||
spdlog::info("**************************************************************");
|
spdlog::info("**************************************************************");
|
||||||
spdlog::info(spdlog::fmt_lib::format(std::locale("en_US.UTF-8"), "Single threaded: {} messages", iters));
|
spdlog::info(
|
||||||
|
spdlog::fmt_lib::format(std::locale("en_US.UTF-8"), "Single threaded: {} messages", iters));
|
||||||
spdlog::info("**************************************************************");
|
spdlog::info("**************************************************************");
|
||||||
|
|
||||||
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);
|
auto basic_st_tracing =
|
||||||
|
spdlog::basic_logger_st("basic_st/backtrace-on", "logs/basic_st.log", true);
|
||||||
bench(iters, std::move(basic_st_tracing));
|
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);
|
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);
|
rotating_st_tracing->enable_backtrace(32);
|
||||||
bench(iters, std::move(rotating_st_tracing));
|
bench(iters, std::move(rotating_st_tracing));
|
||||||
|
|
||||||
@ -110,63 +116,55 @@ void bench_single_threaded(int iters)
|
|||||||
bench(iters, empty_logger_tracing);
|
bench(iters, empty_logger_tracing);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
|
||||||
spdlog::set_automatic_registration(false);
|
spdlog::set_automatic_registration(false);
|
||||||
spdlog::default_logger()->set_pattern("[%^%l%$] %v");
|
spdlog::default_logger()->set_pattern("[%^%l%$] %v");
|
||||||
int iters = 250000;
|
int iters = 250000;
|
||||||
size_t threads = 4;
|
size_t threads = 4;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1) {
|
||||||
{
|
|
||||||
iters = std::stoi(argv[1]);
|
iters = std::stoi(argv[1]);
|
||||||
}
|
}
|
||||||
if (argc > 2)
|
if (argc > 2) {
|
||||||
{
|
|
||||||
threads = std::stoul(argv[2]);
|
threads = std::stoul(argv[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (threads > max_threads)
|
if (threads > max_threads) {
|
||||||
{
|
throw std::runtime_error(
|
||||||
throw std::runtime_error(spdlog::fmt_lib::format("Number of threads exceeds maximum({})", max_threads));
|
spdlog::fmt_lib::format("Number of threads exceeds maximum({})", max_threads));
|
||||||
}
|
}
|
||||||
|
|
||||||
bench_single_threaded(iters);
|
bench_single_threaded(iters);
|
||||||
bench_threaded_logging(1, iters);
|
bench_threaded_logging(1, iters);
|
||||||
bench_threaded_logging(threads, iters);
|
bench_threaded_logging(threads, iters);
|
||||||
}
|
} catch (std::exception &ex) {
|
||||||
catch (std::exception &ex)
|
|
||||||
{
|
|
||||||
spdlog::error(ex.what());
|
spdlog::error(ex.what());
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bench(int howmany, std::shared_ptr<spdlog::logger> log)
|
void bench(int howmany, std::shared_ptr<spdlog::logger> log) {
|
||||||
{
|
|
||||||
using std::chrono::duration;
|
using std::chrono::duration;
|
||||||
using std::chrono::duration_cast;
|
using std::chrono::duration_cast;
|
||||||
using std::chrono::high_resolution_clock;
|
using std::chrono::high_resolution_clock;
|
||||||
|
|
||||||
auto start = high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
for (auto i = 0; i < howmany; ++i)
|
for (auto i = 0; i < howmany; ++i) {
|
||||||
{
|
|
||||||
log->info("Hello logger: msg number {}", i);
|
log->info("Hello logger: msg number {}", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto delta = high_resolution_clock::now() - start;
|
auto delta = high_resolution_clock::now() - start;
|
||||||
auto delta_d = duration_cast<duration<double>>(delta).count();
|
auto delta_d = duration_cast<duration<double>>(delta).count();
|
||||||
|
|
||||||
spdlog::info(spdlog::fmt_lib::format(
|
spdlog::info(spdlog::fmt_lib::format(std::locale("en_US.UTF-8"),
|
||||||
std::locale("en_US.UTF-8"), "{:<30} Elapsed: {:0.2f} secs {:>16L}/sec", log->name(), delta_d, size_t(howmany / delta_d)));
|
"{:<30} Elapsed: {:0.2f} secs {:>16L}/sec", log->name(),
|
||||||
|
delta_d, size_t(howmany / delta_d)));
|
||||||
spdlog::drop(log->name());
|
spdlog::drop(log->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, size_t thread_count)
|
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, size_t thread_count) {
|
||||||
{
|
|
||||||
using std::chrono::duration;
|
using std::chrono::duration;
|
||||||
using std::chrono::duration_cast;
|
using std::chrono::duration_cast;
|
||||||
using std::chrono::high_resolution_clock;
|
using std::chrono::high_resolution_clock;
|
||||||
@ -174,25 +172,23 @@ void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, size_t thread_co
|
|||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> threads;
|
||||||
threads.reserve(thread_count);
|
threads.reserve(thread_count);
|
||||||
auto start = high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
for (size_t t = 0; t < thread_count; ++t)
|
for (size_t t = 0; t < thread_count; ++t) {
|
||||||
{
|
|
||||||
threads.emplace_back([&]() {
|
threads.emplace_back([&]() {
|
||||||
for (int j = 0; j < howmany / static_cast<int>(thread_count); j++)
|
for (int j = 0; j < howmany / static_cast<int>(thread_count); j++) {
|
||||||
{
|
|
||||||
log->info("Hello logger: msg number {}", j);
|
log->info("Hello logger: msg number {}", j);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &t : threads)
|
for (auto &t : threads) {
|
||||||
{
|
|
||||||
t.join();
|
t.join();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto delta = high_resolution_clock::now() - start;
|
auto delta = high_resolution_clock::now() - start;
|
||||||
auto delta_d = duration_cast<duration<double>>(delta).count();
|
auto delta_d = duration_cast<duration<double>>(delta).count();
|
||||||
spdlog::info(spdlog::fmt_lib::format(
|
spdlog::info(spdlog::fmt_lib::format(std::locale("en_US.UTF-8"),
|
||||||
std::locale("en_US.UTF-8"), "{:<30} Elapsed: {:0.2f} secs {:>16L}/sec", log->name(), delta_d, size_t(howmany / delta_d)));
|
"{:<30} Elapsed: {:0.2f} secs {:>16L}/sec", log->name(),
|
||||||
|
delta_d, size_t(howmany / delta_d)));
|
||||||
spdlog::drop(log->name());
|
spdlog::drop(log->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +211,8 @@ void bench_default_api(int howmany, std::shared_ptr<spdlog::logger> log)
|
|||||||
auto delta_d = duration_cast<duration<double>>(delta).count();
|
auto delta_d = duration_cast<duration<double>>(delta).count();
|
||||||
spdlog::drop(log->name());
|
spdlog::drop(log->name());
|
||||||
spdlog::set_default_logger(std::move(orig_default));
|
spdlog::set_default_logger(std::move(orig_default));
|
||||||
spdlog::info("{:<30} Elapsed: {:0.2f} secs {:>16}/sec", log->name(), delta_d, int(howmany / delta_d));
|
spdlog::info("{:<30} Elapsed: {:0.2f} secs {:>16}/sec", log->name(), delta_d, int(howmany /
|
||||||
|
delta_d));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bench_c_string(int howmany, std::shared_ptr<spdlog::logger> log)
|
void bench_c_string(int howmany, std::shared_ptr<spdlog::logger> log)
|
||||||
@ -224,11 +221,12 @@ void bench_c_string(int howmany, std::shared_ptr<spdlog::logger> log)
|
|||||||
using std::chrono::duration;
|
using std::chrono::duration;
|
||||||
using std::chrono::duration_cast;
|
using std::chrono::duration_cast;
|
||||||
|
|
||||||
const char *msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus "
|
const char *msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra
|
||||||
"lacus placerat congue. Nulla egestas, mauris a tincidunt tempus, enim lectus volutpat mi, eu consequat sem "
|
metus cursus " "lacus placerat congue. Nulla egestas, mauris a tincidunt tempus, enim lectus
|
||||||
"libero nec massa. In dapibus ipsum a diam rhoncus gravida. Etiam non dapibus eros. Donec fringilla dui sed "
|
volutpat mi, eu consequat sem " "libero nec massa. In dapibus ipsum a diam rhoncus gravida. Etiam
|
||||||
"augue pretium, nec scelerisque est maximus. Nullam convallis, sem nec blandit maximus, nisi turpis ornare "
|
non dapibus eros. Donec fringilla dui sed " "augue pretium, nec scelerisque est maximus. Nullam
|
||||||
"nisl, sit amet volutpat neque massa eu odio. Maecenas malesuada quam ex, posuere congue nibh turpis duis.";
|
convallis, sem nec blandit maximus, nisi turpis ornare " "nisl, sit amet volutpat neque massa eu
|
||||||
|
odio. Maecenas malesuada quam ex, posuere congue nibh turpis duis.";
|
||||||
|
|
||||||
auto orig_default = spdlog::default_logger();
|
auto orig_default = spdlog::default_logger();
|
||||||
spdlog::set_default_logger(log);
|
spdlog::set_default_logger(log);
|
||||||
@ -242,7 +240,8 @@ void bench_c_string(int howmany, std::shared_ptr<spdlog::logger> log)
|
|||||||
auto delta_d = duration_cast<duration<double>>(delta).count();
|
auto delta_d = duration_cast<duration<double>>(delta).count();
|
||||||
spdlog::drop(log->name());
|
spdlog::drop(log->name());
|
||||||
spdlog::set_default_logger(std::move(orig_default));
|
spdlog::set_default_logger(std::move(orig_default));
|
||||||
spdlog::info("{:<30} Elapsed: {:0.2f} secs {:>16}/sec", log->name(), delta_d, int(howmany / delta_d));
|
spdlog::info("{:<30} Elapsed: {:0.2f} secs {:>16}/sec", log->name(), delta_d, int(howmany /
|
||||||
|
delta_d));
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
@ -8,31 +8,28 @@
|
|||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
#include "spdlog/pattern_formatter.h"
|
#include "spdlog/pattern_formatter.h"
|
||||||
|
|
||||||
void bench_formatter(benchmark::State &state, std::string pattern)
|
void bench_formatter(benchmark::State &state, std::string pattern) {
|
||||||
{
|
|
||||||
auto formatter = spdlog::details::make_unique<spdlog::pattern_formatter>(pattern);
|
auto formatter = spdlog::details::make_unique<spdlog::pattern_formatter>(pattern);
|
||||||
spdlog::memory_buf_t dest;
|
spdlog::memory_buf_t dest;
|
||||||
std::string logger_name = "logger-name";
|
std::string logger_name = "logger-name";
|
||||||
const char *text = "Hello. This is some message with length of 80 ";
|
const char *text =
|
||||||
|
"Hello. This is some message with length of 80 ";
|
||||||
|
|
||||||
spdlog::source_loc source_loc{"a/b/c/d/myfile.cpp", 123, "some_func()"};
|
spdlog::source_loc source_loc{"a/b/c/d/myfile.cpp", 123, "some_func()"};
|
||||||
spdlog::details::log_msg msg(source_loc, logger_name, spdlog::level::info, text);
|
spdlog::details::log_msg msg(source_loc, logger_name, spdlog::level::info, text);
|
||||||
|
|
||||||
for (auto _ : state)
|
for (auto _ : state) {
|
||||||
{
|
|
||||||
dest.clear();
|
dest.clear();
|
||||||
formatter->format(msg, dest);
|
formatter->format(msg, dest);
|
||||||
benchmark::DoNotOptimize(dest);
|
benchmark::DoNotOptimize(dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bench_formatters()
|
void bench_formatters() {
|
||||||
{
|
|
||||||
// basic patterns(single flag)
|
// basic patterns(single flag)
|
||||||
std::string all_flags = "+vtPnlLaAbBcCYDmdHIMSefFprRTXzEisg@luioO%";
|
std::string all_flags = "+vtPnlLaAbBcCYDmdHIMSefFprRTXzEisg@luioO%";
|
||||||
std::vector<std::string> basic_patterns;
|
std::vector<std::string> basic_patterns;
|
||||||
for (auto &flag : all_flags)
|
for (auto &flag : all_flags) {
|
||||||
{
|
|
||||||
auto pattern = std::string("%") + flag;
|
auto pattern = std::string("%") + flag;
|
||||||
benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern);
|
benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern);
|
||||||
|
|
||||||
@ -50,29 +47,24 @@ void bench_formatters()
|
|||||||
"[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] %v",
|
"[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] %v",
|
||||||
"[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] [%t] %v",
|
"[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] [%t] %v",
|
||||||
};
|
};
|
||||||
for (auto &pattern : patterns)
|
for (auto &pattern : patterns) {
|
||||||
{
|
benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern)
|
||||||
benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern)->Iterations(2500000);
|
->Iterations(2500000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
|
||||||
|
|
||||||
spdlog::set_pattern("[%^%l%$] %v");
|
spdlog::set_pattern("[%^%l%$] %v");
|
||||||
if (argc != 2)
|
if (argc != 2) {
|
||||||
{
|
|
||||||
spdlog::error("Usage: {} <pattern> (or \"all\" to bench all)", argv[0]);
|
spdlog::error("Usage: {} <pattern> (or \"all\" to bench all)", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string pattern = argv[1];
|
std::string pattern = argv[1];
|
||||||
if (pattern == "all")
|
if (pattern == "all") {
|
||||||
{
|
|
||||||
bench_formatters();
|
bench_formatters();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern);
|
benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern);
|
||||||
}
|
}
|
||||||
benchmark::Initialize(&argc, argv);
|
benchmark::Initialize(&argc, argv);
|
||||||
|
@ -16,76 +16,72 @@
|
|||||||
#include "spdlog/sinks/null_sink.h"
|
#include "spdlog/sinks/null_sink.h"
|
||||||
#include "spdlog/sinks/rotating_file_sink.h"
|
#include "spdlog/sinks/rotating_file_sink.h"
|
||||||
|
|
||||||
void bench_c_string(benchmark::State &state, std::shared_ptr<spdlog::logger> logger)
|
void bench_c_string(benchmark::State &state, std::shared_ptr<spdlog::logger> logger) {
|
||||||
{
|
const char *msg =
|
||||||
const char *msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus "
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus "
|
||||||
"lacus placerat congue. Nulla egestas, mauris a tincidunt tempus, enim lectus volutpat mi, eu consequat sem "
|
"lacus placerat congue. Nulla egestas, mauris a tincidunt tempus, enim lectus volutpat mi, "
|
||||||
"libero nec massa. In dapibus ipsum a diam rhoncus gravida. Etiam non dapibus eros. Donec fringilla dui sed "
|
"eu consequat sem "
|
||||||
"augue pretium, nec scelerisque est maximus. Nullam convallis, sem nec blandit maximus, nisi turpis ornare "
|
"libero nec massa. In dapibus ipsum a diam rhoncus gravida. Etiam non dapibus eros. Donec "
|
||||||
"nisl, sit amet volutpat neque massa eu odio. Maecenas malesuada quam ex, posuere congue nibh turpis duis.";
|
"fringilla dui sed "
|
||||||
|
"augue pretium, nec scelerisque est maximus. Nullam convallis, sem nec blandit maximus, "
|
||||||
|
"nisi turpis ornare "
|
||||||
|
"nisl, sit amet volutpat neque massa eu odio. Maecenas malesuada quam ex, posuere congue "
|
||||||
|
"nibh turpis duis.";
|
||||||
|
|
||||||
for (auto _ : state)
|
for (auto _ : state) {
|
||||||
{
|
|
||||||
logger->info(msg);
|
logger->info(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bench_logger(benchmark::State &state, std::shared_ptr<spdlog::logger> logger)
|
void bench_logger(benchmark::State &state, std::shared_ptr<spdlog::logger> logger) {
|
||||||
{
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto _ : state)
|
for (auto _ : state) {
|
||||||
{
|
|
||||||
logger->info("Hello logger: msg number {}...............", ++i);
|
logger->info("Hello logger: msg number {}...............", ++i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void bench_global_logger(benchmark::State &state, std::shared_ptr<spdlog::logger> logger)
|
void bench_global_logger(benchmark::State &state, std::shared_ptr<spdlog::logger> logger) {
|
||||||
{
|
|
||||||
spdlog::set_default_logger(std::move(logger));
|
spdlog::set_default_logger(std::move(logger));
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto _ : state)
|
for (auto _ : state) {
|
||||||
{
|
|
||||||
spdlog::info("Hello logger: msg number {}...............", ++i);
|
spdlog::info("Hello logger: msg number {}...............", ++i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bench_disabled_macro(benchmark::State &state, std::shared_ptr<spdlog::logger> logger)
|
void bench_disabled_macro(benchmark::State &state, std::shared_ptr<spdlog::logger> logger) {
|
||||||
{
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
benchmark::DoNotOptimize(i); // prevent unused warnings
|
benchmark::DoNotOptimize(i); // prevent unused warnings
|
||||||
benchmark::DoNotOptimize(logger); // prevent unused warnings
|
benchmark::DoNotOptimize(logger); // prevent unused warnings
|
||||||
for (auto _ : state)
|
for (auto _ : state) {
|
||||||
{
|
|
||||||
SPDLOG_LOGGER_DEBUG(logger, "Hello logger: msg number {}...............", i++);
|
SPDLOG_LOGGER_DEBUG(logger, "Hello logger: msg number {}...............", i++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bench_disabled_macro_global_logger(benchmark::State &state, std::shared_ptr<spdlog::logger> logger)
|
void bench_disabled_macro_global_logger(benchmark::State &state,
|
||||||
{
|
std::shared_ptr<spdlog::logger> logger) {
|
||||||
spdlog::set_default_logger(std::move(logger));
|
spdlog::set_default_logger(std::move(logger));
|
||||||
int i = 0;
|
int i = 0;
|
||||||
benchmark::DoNotOptimize(i); // prevent unused warnings
|
benchmark::DoNotOptimize(i); // prevent unused warnings
|
||||||
benchmark::DoNotOptimize(logger); // prevent unused warnings
|
benchmark::DoNotOptimize(logger); // prevent unused warnings
|
||||||
for (auto _ : state)
|
for (auto _ : state) {
|
||||||
{
|
|
||||||
SPDLOG_DEBUG("Hello logger: msg number {}...............", i++);
|
SPDLOG_DEBUG("Hello logger: msg number {}...............", i++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
void bench_dev_null()
|
void bench_dev_null() {
|
||||||
{
|
|
||||||
auto dev_null_st = spdlog::basic_logger_st("/dev/null_st", "/dev/null");
|
auto dev_null_st = spdlog::basic_logger_st("/dev/null_st", "/dev/null");
|
||||||
benchmark::RegisterBenchmark("/dev/null_st", bench_logger, std::move(dev_null_st))->UseRealTime();
|
benchmark::RegisterBenchmark("/dev/null_st", bench_logger, std::move(dev_null_st))
|
||||||
|
->UseRealTime();
|
||||||
spdlog::drop("/dev/null_st");
|
spdlog::drop("/dev/null_st");
|
||||||
|
|
||||||
auto dev_null_mt = spdlog::basic_logger_mt("/dev/null_mt", "/dev/null");
|
auto dev_null_mt = spdlog::basic_logger_mt("/dev/null_mt", "/dev/null");
|
||||||
benchmark::RegisterBenchmark("/dev/null_mt", bench_logger, std::move(dev_null_mt))->UseRealTime();
|
benchmark::RegisterBenchmark("/dev/null_mt", bench_logger, std::move(dev_null_mt))
|
||||||
|
->UseRealTime();
|
||||||
spdlog::drop("/dev/null_mt");
|
spdlog::drop("/dev/null_mt");
|
||||||
}
|
}
|
||||||
#endif // __linux__
|
#endif // __linux__
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
|
||||||
using spdlog::sinks::null_sink_mt;
|
using spdlog::sinks::null_sink_mt;
|
||||||
using spdlog::sinks::null_sink_st;
|
using spdlog::sinks::null_sink_st;
|
||||||
|
|
||||||
@ -96,23 +92,32 @@ int main(int argc, char *argv[])
|
|||||||
auto full_bench = argc > 1 && std::string(argv[1]) == "full";
|
auto full_bench = argc > 1 && std::string(argv[1]) == "full";
|
||||||
|
|
||||||
// disabled loggers
|
// disabled loggers
|
||||||
auto disabled_logger = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
|
auto disabled_logger =
|
||||||
|
std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
|
||||||
disabled_logger->set_level(spdlog::level::off);
|
disabled_logger->set_level(spdlog::level::off);
|
||||||
benchmark::RegisterBenchmark("disabled-at-compile-time", bench_disabled_macro, disabled_logger);
|
benchmark::RegisterBenchmark("disabled-at-compile-time", bench_disabled_macro, disabled_logger);
|
||||||
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
|
// with backtrace of 64
|
||||||
auto tracing_disabled_logger = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
|
auto tracing_disabled_logger =
|
||||||
|
std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
|
||||||
tracing_disabled_logger->enable_backtrace(64);
|
tracing_disabled_logger->enable_backtrace(64);
|
||||||
benchmark::RegisterBenchmark("disabled-at-runtime/backtrace", bench_logger, tracing_disabled_logger);
|
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 =
|
||||||
benchmark::RegisterBenchmark("null_sink_st (500_bytes c_str)", bench_c_string, std::move(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", 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
|
// with backtrace of 64
|
||||||
auto tracing_null_logger_st = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_st>());
|
auto tracing_null_logger_st =
|
||||||
|
std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_st>());
|
||||||
tracing_null_logger_st->enable_backtrace(64);
|
tracing_null_logger_st->enable_backtrace(64);
|
||||||
benchmark::RegisterBenchmark("null_sink_st/backtrace", bench_logger, tracing_null_logger_st);
|
benchmark::RegisterBenchmark("null_sink_st/backtrace", bench_logger, tracing_null_logger_st);
|
||||||
|
|
||||||
@ -120,55 +125,75 @@ int main(int argc, char *argv[])
|
|||||||
bench_dev_null();
|
bench_dev_null();
|
||||||
#endif // __linux__
|
#endif // __linux__
|
||||||
|
|
||||||
if (full_bench)
|
if (full_bench) {
|
||||||
{
|
|
||||||
// basic_st
|
// basic_st
|
||||||
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
|
// with backtrace of 64
|
||||||
auto tracing_basic_st = spdlog::basic_logger_st("tracing_basic_st", "latency_logs/tracing_basic_st.log", true);
|
auto tracing_basic_st =
|
||||||
|
spdlog::basic_logger_st("tracing_basic_st", "latency_logs/tracing_basic_st.log", true);
|
||||||
tracing_basic_st->enable_backtrace(64);
|
tracing_basic_st->enable_backtrace(64);
|
||||||
benchmark::RegisterBenchmark("basic_st/backtrace", bench_logger, std::move(tracing_basic_st))->UseRealTime();
|
benchmark::RegisterBenchmark("basic_st/backtrace", bench_logger,
|
||||||
|
std::move(tracing_basic_st))
|
||||||
|
->UseRealTime();
|
||||||
spdlog::drop("tracing_basic_st");
|
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",
|
||||||
benchmark::RegisterBenchmark("rotating_st", bench_logger, std::move(rotating_st))->UseRealTime();
|
file_size, rotating_files);
|
||||||
|
benchmark::RegisterBenchmark("rotating_st", bench_logger, std::move(rotating_st))
|
||||||
|
->UseRealTime();
|
||||||
spdlog::drop("rotating_st");
|
spdlog::drop("rotating_st");
|
||||||
// with backtrace of 64
|
// with backtrace of 64
|
||||||
auto tracing_rotating_st =
|
auto tracing_rotating_st = spdlog::rotating_logger_st(
|
||||||
spdlog::rotating_logger_st("tracing_rotating_st", "latency_logs/tracing_rotating_st.log", file_size, rotating_files);
|
"tracing_rotating_st", "latency_logs/tracing_rotating_st.log", file_size,
|
||||||
benchmark::RegisterBenchmark("rotating_st/backtrace", bench_logger, std::move(tracing_rotating_st))->UseRealTime();
|
rotating_files);
|
||||||
|
benchmark::RegisterBenchmark("rotating_st/backtrace", bench_logger,
|
||||||
|
std::move(tracing_rotating_st))
|
||||||
|
->UseRealTime();
|
||||||
spdlog::drop("tracing_rotating_st");
|
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");
|
auto tracing_daily_st =
|
||||||
benchmark::RegisterBenchmark("daily_st/backtrace", bench_logger, std::move(tracing_daily_st))->UseRealTime();
|
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");
|
spdlog::drop("tracing_daily_st");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Multi threaded bench, 10 loggers using same logger concurrently
|
// Multi threaded bench, 10 loggers using same logger concurrently
|
||||||
//
|
//
|
||||||
auto null_logger_mt = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
|
auto null_logger_mt =
|
||||||
benchmark::RegisterBenchmark("null_sink_mt", bench_logger, null_logger_mt)->Threads(n_threads)->UseRealTime();
|
std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
|
||||||
|
benchmark::RegisterBenchmark("null_sink_mt", bench_logger, null_logger_mt)
|
||||||
|
->Threads(n_threads)
|
||||||
|
->UseRealTime();
|
||||||
|
|
||||||
// basic_mt
|
// basic_mt
|
||||||
auto basic_mt = spdlog::basic_logger_mt("basic_mt", "latency_logs/basic_mt.log", true);
|
auto basic_mt = spdlog::basic_logger_mt("basic_mt", "latency_logs/basic_mt.log", true);
|
||||||
benchmark::RegisterBenchmark("basic_mt", bench_logger, std::move(basic_mt))->Threads(n_threads)->UseRealTime();
|
benchmark::RegisterBenchmark("basic_mt", bench_logger, std::move(basic_mt))
|
||||||
|
->Threads(n_threads)
|
||||||
|
->UseRealTime();
|
||||||
spdlog::drop("basic_mt");
|
spdlog::drop("basic_mt");
|
||||||
|
|
||||||
// rotating mt
|
// rotating mt
|
||||||
auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "latency_logs/rotating_mt.log", file_size, rotating_files);
|
auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "latency_logs/rotating_mt.log",
|
||||||
benchmark::RegisterBenchmark("rotating_mt", bench_logger, std::move(rotating_mt))->Threads(n_threads)->UseRealTime();
|
file_size, rotating_files);
|
||||||
|
benchmark::RegisterBenchmark("rotating_mt", bench_logger, std::move(rotating_mt))
|
||||||
|
->Threads(n_threads)
|
||||||
|
->UseRealTime();
|
||||||
spdlog::drop("rotating_mt");
|
spdlog::drop("rotating_mt");
|
||||||
|
|
||||||
// daily mt
|
// daily mt
|
||||||
auto daily_mt = spdlog::daily_logger_mt("daily_mt", "latency_logs/daily_mt.log");
|
auto daily_mt = spdlog::daily_logger_mt("daily_mt", "latency_logs/daily_mt.log");
|
||||||
benchmark::RegisterBenchmark("daily_mt", bench_logger, std::move(daily_mt))->Threads(n_threads)->UseRealTime();
|
benchmark::RegisterBenchmark("daily_mt", bench_logger, std::move(daily_mt))
|
||||||
|
->Threads(n_threads)
|
||||||
|
->UseRealTime();
|
||||||
spdlog::drop("daily_mt");
|
spdlog::drop("daily_mt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,13 +201,19 @@ int main(int argc, char *argv[])
|
|||||||
auto queue_size = 1024 * 1024 * 3;
|
auto queue_size = 1024 * 1024 * 3;
|
||||||
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
||||||
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),
|
||||||
benchmark::RegisterBenchmark("async_logger", bench_logger, async_logger)->Threads(n_threads)->UseRealTime();
|
spdlog::async_overflow_policy::overrun_oldest);
|
||||||
|
benchmark::RegisterBenchmark("async_logger", bench_logger, async_logger)
|
||||||
|
->Threads(n_threads)
|
||||||
|
->UseRealTime();
|
||||||
|
|
||||||
auto async_logger_tracing = std::make_shared<spdlog::async_logger>(
|
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", std::make_shared<null_sink_mt>(), std::move(tp),
|
||||||
|
spdlog::async_overflow_policy::overrun_oldest);
|
||||||
async_logger_tracing->enable_backtrace(32);
|
async_logger_tracing->enable_backtrace(32);
|
||||||
benchmark::RegisterBenchmark("async_logger/tracing", bench_logger, async_logger_tracing)->Threads(n_threads)->UseRealTime();
|
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();
|
||||||
|
@ -11,9 +11,8 @@
|
|||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
inline std::string format(const T &value)
|
inline std::string format(const T &value) {
|
||||||
{
|
|
||||||
static std::locale loc("");
|
static std::locale loc("");
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss.imbue(loc);
|
ss.imbue(loc);
|
||||||
@ -21,9 +20,8 @@ inline std::string format(const T &value)
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
inline std::string format(const double &value)
|
inline std::string format(const double &value) {
|
||||||
{
|
|
||||||
static std::locale loc("");
|
static std::locale loc("");
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss.imbue(loc);
|
ss.imbue(loc);
|
||||||
|
@ -31,12 +31,12 @@ void replace_default_logger_example();
|
|||||||
#include "spdlog/cfg/env.h" // support for loading levels from the environment variable
|
#include "spdlog/cfg/env.h" // support for loading levels from the environment variable
|
||||||
#include "spdlog/fmt/ostr.h" // support for user defined types
|
#include "spdlog/fmt/ostr.h" // support for user defined types
|
||||||
|
|
||||||
int main(int, char *[])
|
int main(int, char *[]) {
|
||||||
{
|
|
||||||
// Log levels can be loaded from argv/env using "SPDLOG_LEVEL"
|
// Log levels can be loaded from argv/env using "SPDLOG_LEVEL"
|
||||||
load_levels_example();
|
load_levels_example();
|
||||||
|
|
||||||
spdlog::info("Welcome to spdlog version {}.{}.{} !", SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH);
|
spdlog::info("Welcome to spdlog version {}.{}.{} !", SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR,
|
||||||
|
SPDLOG_VER_PATCH);
|
||||||
|
|
||||||
spdlog::warn("Easy padding in numbers like {:08d}", 12);
|
spdlog::warn("Easy padding in numbers like {:08d}", 12);
|
||||||
spdlog::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
|
spdlog::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
|
||||||
@ -60,15 +60,13 @@ int main(int, char *[])
|
|||||||
// Loggers can store in a ring buffer all messages (including debug/trace) for later inspection.
|
// Loggers can store in a ring buffer all messages (including debug/trace) for later inspection.
|
||||||
// When needed, call dump_backtrace() to see what happened:
|
// When needed, call dump_backtrace() to see what happened:
|
||||||
spdlog::enable_backtrace(10); // create ring buffer with capacity of 10 messages
|
spdlog::enable_backtrace(10); // create ring buffer with capacity of 10 messages
|
||||||
for (int i = 0; i < 100; i++)
|
for (int i = 0; i < 100; i++) {
|
||||||
{
|
|
||||||
spdlog::debug("Backtrace message {}", i); // not logged..
|
spdlog::debug("Backtrace message {}", i); // not logged..
|
||||||
}
|
}
|
||||||
// e.g. if some error happened:
|
// e.g. if some error happened:
|
||||||
spdlog::dump_backtrace(); // log them now!
|
spdlog::dump_backtrace(); // log them now!
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
stdout_logger_example();
|
stdout_logger_example();
|
||||||
basic_example();
|
basic_example();
|
||||||
rotating_example();
|
rotating_example();
|
||||||
@ -100,8 +98,7 @@ int main(int, char *[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Exceptions will only be thrown upon failed logger or sink construction (not during logging).
|
// Exceptions will only be thrown upon failed logger or sink construction (not during logging).
|
||||||
catch (const spdlog::spdlog_ex &ex)
|
catch (const spdlog::spdlog_ex &ex) {
|
||||||
{
|
|
||||||
std::printf("Log initialization failed: %s\n", ex.what());
|
std::printf("Log initialization failed: %s\n", ex.what());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -109,8 +106,7 @@ int main(int, char *[])
|
|||||||
|
|
||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
// or #include "spdlog/sinks/stdout_sinks.h" if no colors needed.
|
// or #include "spdlog/sinks/stdout_sinks.h" if no colors needed.
|
||||||
void stdout_logger_example()
|
void stdout_logger_example() {
|
||||||
{
|
|
||||||
// Create color multi threaded logger.
|
// Create color multi threaded logger.
|
||||||
auto console = spdlog::stdout_color_mt("console");
|
auto console = spdlog::stdout_color_mt("console");
|
||||||
// or for stderr:
|
// or for stderr:
|
||||||
@ -118,38 +114,35 @@ void stdout_logger_example()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "spdlog/sinks/basic_file_sink.h"
|
#include "spdlog/sinks/basic_file_sink.h"
|
||||||
void basic_example()
|
void basic_example() {
|
||||||
{
|
|
||||||
// Create basic file logger (not rotated).
|
// Create basic file logger (not rotated).
|
||||||
auto my_logger = spdlog::basic_logger_mt("file_logger", "logs/basic-log.txt", true);
|
auto my_logger = spdlog::basic_logger_mt("file_logger", "logs/basic-log.txt", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "spdlog/sinks/rotating_file_sink.h"
|
#include "spdlog/sinks/rotating_file_sink.h"
|
||||||
void rotating_example()
|
void rotating_example() {
|
||||||
{
|
|
||||||
// Create a file rotating logger with 5mb size max and 3 rotated files.
|
// Create a file rotating logger with 5mb size max and 3 rotated files.
|
||||||
auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3);
|
auto rotating_logger =
|
||||||
|
spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "spdlog/sinks/daily_file_sink.h"
|
#include "spdlog/sinks/daily_file_sink.h"
|
||||||
void daily_example()
|
void daily_example() {
|
||||||
{
|
|
||||||
// Create a daily logger - a new file is created every day on 2:30am.
|
// Create a daily logger - a new file is created every day on 2:30am.
|
||||||
auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
|
auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "spdlog/sinks/callback_sink.h"
|
#include "spdlog/sinks/callback_sink.h"
|
||||||
void callback_example()
|
void callback_example() {
|
||||||
{
|
|
||||||
// Create the logger
|
// Create the logger
|
||||||
auto logger = spdlog::callback_logger_mt("custom_callback_logger", [](const spdlog::details::log_msg & /*msg*/) {
|
auto logger = spdlog::callback_logger_mt("custom_callback_logger",
|
||||||
// do what you need to do with msg
|
[](const spdlog::details::log_msg & /*msg*/) {
|
||||||
});
|
// do what you need to do with msg
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "spdlog/cfg/env.h"
|
#include "spdlog/cfg/env.h"
|
||||||
void load_levels_example()
|
void load_levels_example() {
|
||||||
{
|
|
||||||
// Set the log level to "info" and mylogger to "trace":
|
// Set the log level to "info" and mylogger to "trace":
|
||||||
// SPDLOG_LEVEL=info,mylogger=trace && ./example
|
// SPDLOG_LEVEL=info,mylogger=trace && ./example
|
||||||
spdlog::cfg::load_env_levels();
|
spdlog::cfg::load_env_levels();
|
||||||
@ -160,16 +153,17 @@ void load_levels_example()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "spdlog/async.h"
|
#include "spdlog/async.h"
|
||||||
void async_example()
|
void async_example() {
|
||||||
{
|
|
||||||
// Default thread pool settings can be modified *before* creating the async logger:
|
// Default thread pool settings can be modified *before* creating the async logger:
|
||||||
// spdlog::init_thread_pool(32768, 1); // queue with max 32k items 1 backing thread.
|
// spdlog::init_thread_pool(32768, 1); // queue with max 32k items 1 backing thread.
|
||||||
auto async_file = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/async_log.txt");
|
auto async_file =
|
||||||
|
spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/async_log.txt");
|
||||||
// alternatively:
|
// alternatively:
|
||||||
// auto async_file = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("async_file_logger", "logs/async_log.txt");
|
// auto async_file =
|
||||||
|
// spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("async_file_logger",
|
||||||
|
// "logs/async_log.txt");
|
||||||
|
|
||||||
for (int i = 1; i < 101; ++i)
|
for (int i = 1; i < 101; ++i) {
|
||||||
{
|
|
||||||
async_file->info("Async message #{}", i);
|
async_file->info("Async message #{}", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,16 +178,15 @@ void async_example()
|
|||||||
// {:n} - don't split the output to lines.
|
// {:n} - don't split the output to lines.
|
||||||
|
|
||||||
#if !defined SPDLOG_USE_STD_FORMAT || defined(_MSC_VER)
|
#if !defined SPDLOG_USE_STD_FORMAT || defined(_MSC_VER)
|
||||||
# include "spdlog/fmt/bin_to_hex.h"
|
#include "spdlog/fmt/bin_to_hex.h"
|
||||||
void binary_example()
|
void binary_example() {
|
||||||
{
|
|
||||||
std::vector<char> buf(80);
|
std::vector<char> buf(80);
|
||||||
for (int i = 0; i < 80; i++)
|
for (int i = 0; i < 80; i++) {
|
||||||
{
|
|
||||||
buf.push_back(static_cast<char>(i & 0xff));
|
buf.push_back(static_cast<char>(i & 0xff));
|
||||||
}
|
}
|
||||||
spdlog::info("Binary example: {}", spdlog::to_hex(buf));
|
spdlog::info("Binary example: {}", spdlog::to_hex(buf));
|
||||||
spdlog::info("Another binary example:{:n}", spdlog::to_hex(std::begin(buf), std::begin(buf) + 10));
|
spdlog::info("Another binary example:{:n}",
|
||||||
|
spdlog::to_hex(std::begin(buf), std::begin(buf) + 10));
|
||||||
// more examples:
|
// more examples:
|
||||||
// logger->info("uppercase: {:X}", spdlog::to_hex(buf));
|
// logger->info("uppercase: {:X}", spdlog::to_hex(buf));
|
||||||
// logger->info("uppercase, no delimiters: {:Xs}", spdlog::to_hex(buf));
|
// logger->info("uppercase, no delimiters: {:Xs}", spdlog::to_hex(buf));
|
||||||
@ -202,17 +195,15 @@ void binary_example()
|
|||||||
// logger->info("hexdump style, 20 chars per line {:a}", spdlog::to_hex(buf, 20));
|
// logger->info("hexdump style, 20 chars per line {:a}", spdlog::to_hex(buf, 20));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void binary_example()
|
void binary_example() {
|
||||||
{
|
|
||||||
// not supported with std::format yet
|
// not supported with std::format yet
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Log a vector of numbers
|
// Log a vector of numbers
|
||||||
#ifndef SPDLOG_USE_STD_FORMAT
|
#ifndef SPDLOG_USE_STD_FORMAT
|
||||||
# include "spdlog/fmt/ranges.h"
|
#include "spdlog/fmt/ranges.h"
|
||||||
void vector_example()
|
void vector_example() {
|
||||||
{
|
|
||||||
std::vector<int> vec = {1, 2, 3};
|
std::vector<int> vec = {1, 2, 3};
|
||||||
spdlog::info("Vector example: {}", vec);
|
spdlog::info("Vector example: {}", vec);
|
||||||
}
|
}
|
||||||
@ -225,8 +216,7 @@ void vector_example() {}
|
|||||||
|
|
||||||
// Compile time log levels.
|
// Compile time log levels.
|
||||||
// define SPDLOG_ACTIVE_LEVEL to required level (e.g. SPDLOG_LEVEL_TRACE)
|
// define SPDLOG_ACTIVE_LEVEL to required level (e.g. SPDLOG_LEVEL_TRACE)
|
||||||
void trace_example()
|
void trace_example() {
|
||||||
{
|
|
||||||
// trace from default logger
|
// trace from default logger
|
||||||
SPDLOG_TRACE("Some trace message.. {} ,{}", 1, 3.23);
|
SPDLOG_TRACE("Some trace message.. {} ,{}", 1, 3.23);
|
||||||
// debug from default logger
|
// debug from default logger
|
||||||
@ -240,16 +230,14 @@ void trace_example()
|
|||||||
// stopwatch example
|
// stopwatch example
|
||||||
#include "spdlog/stopwatch.h"
|
#include "spdlog/stopwatch.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
void stopwatch_example()
|
void stopwatch_example() {
|
||||||
{
|
|
||||||
spdlog::stopwatch sw;
|
spdlog::stopwatch sw;
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(123));
|
std::this_thread::sleep_for(std::chrono::milliseconds(123));
|
||||||
spdlog::info("Stopwatch: {} seconds", sw);
|
spdlog::info("Stopwatch: {} seconds", sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "spdlog/sinks/udp_sink.h"
|
#include "spdlog/sinks/udp_sink.h"
|
||||||
void udp_example()
|
void udp_example() {
|
||||||
{
|
|
||||||
spdlog::sinks::udp_sink_config cfg("127.0.0.1", 11091);
|
spdlog::sinks::udp_sink_config cfg("127.0.0.1", 11091);
|
||||||
auto my_logger = spdlog::udp_logger_mt("udplog", cfg);
|
auto my_logger = spdlog::udp_logger_mt("udplog", cfg);
|
||||||
my_logger->set_level(spdlog::level::debug);
|
my_logger->set_level(spdlog::level::debug);
|
||||||
@ -257,13 +245,13 @@ void udp_example()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A logger with multiple sinks (stdout and file) - each with a different format and log level.
|
// A logger with multiple sinks (stdout and file) - each with a different format and log level.
|
||||||
void multi_sink_example()
|
void multi_sink_example() {
|
||||||
{
|
|
||||||
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||||
console_sink->set_level(spdlog::level::warn);
|
console_sink->set_level(spdlog::level::warn);
|
||||||
console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v");
|
console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v");
|
||||||
|
|
||||||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/multisink.txt", true);
|
auto file_sink =
|
||||||
|
std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/multisink.txt", true);
|
||||||
file_sink->set_level(spdlog::level::trace);
|
file_sink->set_level(spdlog::level::trace);
|
||||||
|
|
||||||
spdlog::logger logger("multi_sink", {console_sink, file_sink});
|
spdlog::logger logger("multi_sink", {console_sink, file_sink});
|
||||||
@ -273,51 +261,43 @@ void multi_sink_example()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// User defined types logging
|
// User defined types logging
|
||||||
struct my_type
|
struct my_type {
|
||||||
{
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
explicit my_type(int i)
|
explicit my_type(int i)
|
||||||
: i(i){};
|
: i(i){};
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef SPDLOG_USE_STD_FORMAT // when using fmtlib
|
#ifndef SPDLOG_USE_STD_FORMAT // when using fmtlib
|
||||||
template<>
|
template <>
|
||||||
struct fmt::formatter<my_type> : fmt::formatter<std::string>
|
struct fmt::formatter<my_type> : fmt::formatter<std::string> {
|
||||||
{
|
auto format(my_type my, format_context &ctx) -> decltype(ctx.out()) {
|
||||||
auto format(my_type my, format_context &ctx) -> decltype(ctx.out())
|
|
||||||
{
|
|
||||||
return fmt::format_to(ctx.out(), "[my_type i={}]", my.i);
|
return fmt::format_to(ctx.out(), "[my_type i={}]", my.i);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // when using std::format
|
#else // when using std::format
|
||||||
template<>
|
template <>
|
||||||
struct std::formatter<my_type> : std::formatter<std::string>
|
struct std::formatter<my_type> : std::formatter<std::string> {
|
||||||
{
|
auto format(my_type my, format_context &ctx) const -> decltype(ctx.out()) {
|
||||||
auto format(my_type my, format_context &ctx) const -> decltype(ctx.out())
|
|
||||||
{
|
|
||||||
return format_to(ctx.out(), "[my_type i={}]", my.i);
|
return format_to(ctx.out(), "[my_type i={}]", my.i);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void user_defined_example()
|
void user_defined_example() { spdlog::info("user defined type: {}", my_type(14)); }
|
||||||
{
|
|
||||||
spdlog::info("user defined type: {}", my_type(14));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom error handler. Will be triggered on log failure.
|
// Custom error handler. Will be triggered on log failure.
|
||||||
void err_handler_example()
|
void err_handler_example() {
|
||||||
{
|
|
||||||
// can be set globally or per logger(logger->set_error_handler(..))
|
// can be set globally or per logger(logger->set_error_handler(..))
|
||||||
spdlog::set_error_handler([](const std::string &msg) { printf("*** Custom log error handler: %s ***\n", msg.c_str()); });
|
spdlog::set_error_handler([](const std::string &msg) {
|
||||||
|
printf("*** Custom log error handler: %s ***\n", msg.c_str());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// syslog example (linux/osx/freebsd)
|
// syslog example (linux/osx/freebsd)
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include "spdlog/sinks/syslog_sink.h"
|
#include "spdlog/sinks/syslog_sink.h"
|
||||||
void syslog_example()
|
void syslog_example() {
|
||||||
{
|
|
||||||
std::string ident = "spdlog-example";
|
std::string ident = "spdlog-example";
|
||||||
auto syslog_logger = spdlog::syslog_logger_mt("syslog", ident, LOG_PID);
|
auto syslog_logger = spdlog::syslog_logger_mt("syslog", ident, LOG_PID);
|
||||||
syslog_logger->warn("This is warning that will end up in syslog.");
|
syslog_logger->warn("This is warning that will end up in syslog.");
|
||||||
@ -326,9 +306,8 @@ void syslog_example()
|
|||||||
|
|
||||||
// Android example.
|
// Android example.
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
# include "spdlog/sinks/android_sink.h"
|
#include "spdlog/sinks/android_sink.h"
|
||||||
void android_example()
|
void android_example() {
|
||||||
{
|
|
||||||
std::string tag = "spdlog-android";
|
std::string tag = "spdlog-android";
|
||||||
auto android_logger = spdlog::android_logger_mt("android", tag);
|
auto android_logger = spdlog::android_logger_mt("android", tag);
|
||||||
android_logger->critical("Use \"adb shell logcat\" to view this message.");
|
android_logger->critical("Use \"adb shell logcat\" to view this message.");
|
||||||
@ -338,36 +317,34 @@ void android_example()
|
|||||||
// Log patterns can contain custom flags.
|
// Log patterns can contain custom flags.
|
||||||
// this will add custom flag '%*' which will be bound to a <my_formatter_flag> instance
|
// this will add custom flag '%*' which will be bound to a <my_formatter_flag> instance
|
||||||
#include "spdlog/pattern_formatter.h"
|
#include "spdlog/pattern_formatter.h"
|
||||||
class my_formatter_flag : public spdlog::custom_flag_formatter
|
class my_formatter_flag : public spdlog::custom_flag_formatter {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
void format(const spdlog::details::log_msg &, const std::tm &, spdlog::memory_buf_t &dest) override
|
void
|
||||||
{
|
format(const spdlog::details::log_msg &, const std::tm &, spdlog::memory_buf_t &dest) override {
|
||||||
std::string some_txt = "custom-flag";
|
std::string some_txt = "custom-flag";
|
||||||
dest.append(some_txt.data(), some_txt.data() + some_txt.size());
|
dest.append(some_txt.data(), some_txt.data() + some_txt.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<custom_flag_formatter> clone() const override
|
std::unique_ptr<custom_flag_formatter> clone() const override {
|
||||||
{
|
|
||||||
return spdlog::details::make_unique<my_formatter_flag>();
|
return spdlog::details::make_unique<my_formatter_flag>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void custom_flags_example()
|
void custom_flags_example() {
|
||||||
{
|
|
||||||
|
|
||||||
using spdlog::details::make_unique; // for pre c++14
|
using spdlog::details::make_unique; // for pre c++14
|
||||||
auto formatter = make_unique<spdlog::pattern_formatter>();
|
auto formatter = make_unique<spdlog::pattern_formatter>();
|
||||||
formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v");
|
formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v");
|
||||||
// set the new formatter using spdlog::set_formatter(formatter) or logger->set_formatter(formatter)
|
// set the new formatter using spdlog::set_formatter(formatter) or
|
||||||
// spdlog::set_formatter(std::move(formatter));
|
// logger->set_formatter(formatter) spdlog::set_formatter(std::move(formatter));
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_events_example()
|
void file_events_example() {
|
||||||
{
|
|
||||||
// pass the spdlog::file_event_handlers to file sinks for open/close log file notifications
|
// pass the spdlog::file_event_handlers to file sinks for open/close log file notifications
|
||||||
spdlog::file_event_handlers handlers;
|
spdlog::file_event_handlers handlers;
|
||||||
handlers.before_open = [](spdlog::filename_t filename) { spdlog::info("Before opening {}", filename); };
|
handlers.before_open = [](spdlog::filename_t filename) {
|
||||||
|
spdlog::info("Before opening {}", filename);
|
||||||
|
};
|
||||||
handlers.after_open = [](spdlog::filename_t filename, std::FILE *fstream) {
|
handlers.after_open = [](spdlog::filename_t filename, std::FILE *fstream) {
|
||||||
spdlog::info("After opening {}", filename);
|
spdlog::info("After opening {}", filename);
|
||||||
fputs("After opening\n", fstream);
|
fputs("After opening\n", fstream);
|
||||||
@ -376,18 +353,21 @@ void file_events_example()
|
|||||||
spdlog::info("Before closing {}", filename);
|
spdlog::info("Before closing {}", filename);
|
||||||
fputs("Before closing\n", fstream);
|
fputs("Before closing\n", fstream);
|
||||||
};
|
};
|
||||||
handlers.after_close = [](spdlog::filename_t filename) { spdlog::info("After closing {}", filename); };
|
handlers.after_close = [](spdlog::filename_t filename) {
|
||||||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/events-sample.txt", true, handlers);
|
spdlog::info("After closing {}", filename);
|
||||||
|
};
|
||||||
|
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/events-sample.txt",
|
||||||
|
true, handlers);
|
||||||
spdlog::logger my_logger("some_logger", file_sink);
|
spdlog::logger my_logger("some_logger", file_sink);
|
||||||
my_logger.info("Some log line");
|
my_logger.info("Some log line");
|
||||||
}
|
}
|
||||||
|
|
||||||
void replace_default_logger_example()
|
void replace_default_logger_example() {
|
||||||
{
|
|
||||||
// store the old logger so we don't break other examples.
|
// store the old logger so we don't break other examples.
|
||||||
auto old_logger = spdlog::default_logger();
|
auto old_logger = spdlog::default_logger();
|
||||||
|
|
||||||
auto new_logger = spdlog::basic_logger_mt("new_default_logger", "logs/new-default-log.txt", true);
|
auto new_logger =
|
||||||
|
spdlog::basic_logger_mt("new_default_logger", "logs/new-default-log.txt", true);
|
||||||
spdlog::set_default_logger(new_logger);
|
spdlog::set_default_logger(new_logger);
|
||||||
spdlog::set_level(spdlog::level::info);
|
spdlog::set_level(spdlog::level::info);
|
||||||
spdlog::debug("This message should not be displayed!");
|
spdlog::debug("This message should not be displayed!");
|
||||||
|
@ -48,8 +48,8 @@ struct async_factory_impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
|
auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
|
||||||
auto new_logger =
|
auto new_logger = std::make_shared<async_logger>(std::move(logger_name), std::move(sink),
|
||||||
std::make_shared<async_logger>(std::move(logger_name), std::move(sink), std::move(tp), OverflowPolicy);
|
std::move(tp), OverflowPolicy);
|
||||||
registry_inst.initialize_logger(new_logger);
|
registry_inst.initialize_logger(new_logger);
|
||||||
return new_logger;
|
return new_logger;
|
||||||
}
|
}
|
||||||
@ -59,13 +59,17 @@ using async_factory = async_factory_impl<async_overflow_policy::block>;
|
|||||||
using async_factory_nonblock = async_factory_impl<async_overflow_policy::overrun_oldest>;
|
using async_factory_nonblock = async_factory_impl<async_overflow_policy::overrun_oldest>;
|
||||||
|
|
||||||
template <typename Sink, typename... SinkArgs>
|
template <typename Sink, typename... SinkArgs>
|
||||||
inline std::shared_ptr<spdlog::logger> create_async(std::string logger_name, SinkArgs &&...sink_args) {
|
inline std::shared_ptr<spdlog::logger> create_async(std::string logger_name,
|
||||||
return async_factory::create<Sink>(std::move(logger_name), std::forward<SinkArgs>(sink_args)...);
|
SinkArgs &&...sink_args) {
|
||||||
|
return async_factory::create<Sink>(std::move(logger_name),
|
||||||
|
std::forward<SinkArgs>(sink_args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Sink, typename... SinkArgs>
|
template <typename Sink, typename... SinkArgs>
|
||||||
inline std::shared_ptr<spdlog::logger> create_async_nb(std::string logger_name, SinkArgs &&...sink_args) {
|
inline std::shared_ptr<spdlog::logger> create_async_nb(std::string logger_name,
|
||||||
return async_factory_nonblock::create<Sink>(std::move(logger_name), std::forward<SinkArgs>(sink_args)...);
|
SinkArgs &&...sink_args) {
|
||||||
|
return async_factory_nonblock::create<Sink>(std::move(logger_name),
|
||||||
|
std::forward<SinkArgs>(sink_args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set global thread pool.
|
// set global thread pool.
|
||||||
@ -73,11 +77,13 @@ inline void init_thread_pool(size_t q_size,
|
|||||||
size_t thread_count,
|
size_t thread_count,
|
||||||
std::function<void()> on_thread_start,
|
std::function<void()> on_thread_start,
|
||||||
std::function<void()> on_thread_stop) {
|
std::function<void()> on_thread_stop) {
|
||||||
auto tp = std::make_shared<details::thread_pool>(q_size, thread_count, on_thread_start, on_thread_stop);
|
auto tp = std::make_shared<details::thread_pool>(q_size, thread_count, on_thread_start,
|
||||||
|
on_thread_stop);
|
||||||
details::registry::instance().set_tp(std::move(tp));
|
details::registry::instance().set_tp(std::move(tp));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void init_thread_pool(size_t q_size, size_t thread_count, std::function<void()> on_thread_start) {
|
inline void
|
||||||
|
init_thread_pool(size_t q_size, size_t thread_count, std::function<void()> on_thread_start) {
|
||||||
init_thread_pool(q_size, thread_count, on_thread_start, [] {});
|
init_thread_pool(q_size, thread_count, on_thread_start, [] {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,5 +93,7 @@ inline void init_thread_pool(size_t q_size, size_t thread_count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the global thread pool.
|
// get the global thread pool.
|
||||||
inline std::shared_ptr<spdlog::details::thread_pool> thread_pool() { return details::registry::instance().get_tp(); }
|
inline std::shared_ptr<spdlog::details::thread_pool> thread_pool() {
|
||||||
|
return details::registry::instance().get_tp();
|
||||||
|
}
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -17,17 +17,23 @@ SPDLOG_INLINE spdlog::async_logger::async_logger(std::string logger_name,
|
|||||||
sinks_init_list sinks_list,
|
sinks_init_list sinks_list,
|
||||||
std::weak_ptr<details::thread_pool> tp,
|
std::weak_ptr<details::thread_pool> tp,
|
||||||
async_overflow_policy overflow_policy)
|
async_overflow_policy overflow_policy)
|
||||||
: async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy) {}
|
: async_logger(std::move(logger_name),
|
||||||
|
sinks_list.begin(),
|
||||||
|
sinks_list.end(),
|
||||||
|
std::move(tp),
|
||||||
|
overflow_policy) {}
|
||||||
|
|
||||||
SPDLOG_INLINE spdlog::async_logger::async_logger(std::string logger_name,
|
SPDLOG_INLINE spdlog::async_logger::async_logger(std::string logger_name,
|
||||||
sink_ptr single_sink,
|
sink_ptr single_sink,
|
||||||
std::weak_ptr<details::thread_pool> tp,
|
std::weak_ptr<details::thread_pool> tp,
|
||||||
async_overflow_policy overflow_policy)
|
async_overflow_policy overflow_policy)
|
||||||
: async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy) {}
|
: async_logger(
|
||||||
|
std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy) {}
|
||||||
|
|
||||||
// send the log message to the thread pool
|
// send the log message to the thread pool
|
||||||
SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg){
|
SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg){
|
||||||
SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){pool_ptr->post_log(shared_from_this(), msg, overflow_policy_);
|
SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){
|
||||||
|
pool_ptr->post_log(shared_from_this(), msg, overflow_policy_);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw_spdlog_ex("async log: thread pool doesn't exist anymore");
|
throw_spdlog_ex("async log: thread pool doesn't exist anymore");
|
||||||
@ -38,7 +44,8 @@ SPDLOG_LOGGER_CATCH(msg.source)
|
|||||||
|
|
||||||
// send flush request to the thread pool
|
// send flush request to the thread pool
|
||||||
SPDLOG_INLINE void spdlog::async_logger::flush_(){
|
SPDLOG_INLINE void spdlog::async_logger::flush_(){
|
||||||
SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){pool_ptr->post_flush(shared_from_this(), overflow_policy_);
|
SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){
|
||||||
|
pool_ptr->post_flush(shared_from_this(), overflow_policy_);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw_spdlog_ex("async flush: thread pool doesn't exist anymore");
|
throw_spdlog_ex("async flush: thread pool doesn't exist anymore");
|
||||||
|
@ -30,7 +30,8 @@ namespace details {
|
|||||||
class thread_pool;
|
class thread_pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SPDLOG_API async_logger final : public std::enable_shared_from_this<async_logger>, public logger {
|
class SPDLOG_API async_logger final : public std::enable_shared_from_this<async_logger>,
|
||||||
|
public logger {
|
||||||
friend class details::thread_pool;
|
friend class details::thread_pool;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -40,9 +41,9 @@ public:
|
|||||||
It end,
|
It end,
|
||||||
std::weak_ptr<details::thread_pool> tp,
|
std::weak_ptr<details::thread_pool> tp,
|
||||||
async_overflow_policy overflow_policy = async_overflow_policy::block)
|
async_overflow_policy overflow_policy = async_overflow_policy::block)
|
||||||
: logger(std::move(logger_name), begin, end),
|
: logger(std::move(logger_name), begin, end)
|
||||||
thread_pool_(std::move(tp)),
|
, thread_pool_(std::move(tp))
|
||||||
overflow_policy_(overflow_policy) {}
|
, overflow_policy_(overflow_policy) {}
|
||||||
|
|
||||||
async_logger(std::string logger_name,
|
async_logger(std::string logger_name,
|
||||||
sinks_init_list sinks_list,
|
sinks_init_list sinks_list,
|
||||||
|
@ -32,7 +32,9 @@ inline void load_argv_levels(int argc, const char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void load_argv_levels(int argc, char **argv) { load_argv_levels(argc, const_cast<const char **>(argv)); }
|
inline void load_argv_levels(int argc, char **argv) {
|
||||||
|
load_argv_levels(argc, const_cast<const char **>(argv));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace cfg
|
} // namespace cfg
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -22,8 +22,9 @@ namespace helpers {
|
|||||||
|
|
||||||
// inplace convert to lowercase
|
// inplace convert to lowercase
|
||||||
inline std::string &to_lower_(std::string &str) {
|
inline std::string &to_lower_(std::string &str) {
|
||||||
std::transform(str.begin(), str.end(), str.begin(),
|
std::transform(str.begin(), str.end(), str.begin(), [](char ch) {
|
||||||
[](char ch) { return static_cast<char>((ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch); });
|
return static_cast<char>((ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch);
|
||||||
|
});
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +98,8 @@ SPDLOG_INLINE void load_levels(const std::string &input) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
details::registry::instance().set_levels(std::move(levels), global_level_found ? &global_level : nullptr);
|
details::registry::instance().set_levels(std::move(levels),
|
||||||
|
global_level_found ? &global_level : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace helpers
|
} // namespace helpers
|
||||||
|
@ -24,7 +24,9 @@ SPDLOG_INLINE const string_view_t &to_string_view(spdlog::level::level_enum l) S
|
|||||||
return level_string_views[l];
|
return level_string_views[l];
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT { return short_level_names[l]; }
|
SPDLOG_INLINE const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT {
|
||||||
|
return short_level_names[l];
|
||||||
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT {
|
SPDLOG_INLINE spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT {
|
||||||
auto it = std::find(std::begin(level_string_views), std::end(level_string_views), name);
|
auto it = std::find(std::begin(level_string_views), std::end(level_string_views), name);
|
||||||
@ -57,7 +59,9 @@ SPDLOG_INLINE spdlog_ex::spdlog_ex(const std::string &msg, int last_errno) {
|
|||||||
|
|
||||||
SPDLOG_INLINE const char *spdlog_ex::what() const SPDLOG_NOEXCEPT { return msg_.c_str(); }
|
SPDLOG_INLINE const char *spdlog_ex::what() const SPDLOG_NOEXCEPT { return msg_.c_str(); }
|
||||||
|
|
||||||
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno) { SPDLOG_THROW(spdlog_ex(msg, last_errno)); }
|
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno) {
|
||||||
|
SPDLOG_THROW(spdlog_ex(msg, last_errno));
|
||||||
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void throw_spdlog_ex(std::string msg) { SPDLOG_THROW(spdlog_ex(std::move(msg))); }
|
SPDLOG_INLINE void throw_spdlog_ex(std::string msg) { SPDLOG_THROW(spdlog_ex(std::move(msg))); }
|
||||||
|
|
||||||
|
@ -49,7 +49,8 @@
|
|||||||
|
|
||||||
#include <spdlog/fmt/fmt.h>
|
#include <spdlog/fmt/fmt.h>
|
||||||
|
|
||||||
#if !defined(SPDLOG_USE_STD_FORMAT) && FMT_VERSION >= 80000 // backward compatibility with fmt versions older than 8
|
#if !defined(SPDLOG_USE_STD_FORMAT) && \
|
||||||
|
FMT_VERSION >= 80000 // backward compatibility with fmt versions older than 8
|
||||||
#define SPDLOG_FMT_RUNTIME(format_string) fmt::runtime(format_string)
|
#define SPDLOG_FMT_RUNTIME(format_string) fmt::runtime(format_string)
|
||||||
#define SPDLOG_FMT_STRING(format_string) FMT_STRING(format_string)
|
#define SPDLOG_FMT_STRING(format_string) FMT_STRING(format_string)
|
||||||
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
||||||
@ -180,14 +181,15 @@ using fmt_runtime_string = fmt::runtime_format_string<Char>;
|
|||||||
using fmt_runtime_string = fmt::basic_runtime<Char>;
|
using fmt_runtime_string = fmt::basic_runtime<Char>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// clang doesn't like SFINAE disabled constructor in std::is_convertible<> so have to repeat the condition from
|
// clang doesn't like SFINAE disabled constructor in std::is_convertible<> so have to repeat the
|
||||||
// basic_format_string here, in addition, fmt::basic_runtime<Char> is only convertible to basic_format_string<Char> but
|
// condition from basic_format_string here, in addition, fmt::basic_runtime<Char> is only
|
||||||
// not basic_string_view<Char>
|
// convertible to basic_format_string<Char> but not basic_string_view<Char>
|
||||||
template <class T, class Char = char>
|
template <class T, class Char = char>
|
||||||
struct is_convertible_to_basic_format_string
|
struct is_convertible_to_basic_format_string
|
||||||
: std::integral_constant<bool,
|
: std::integral_constant<bool,
|
||||||
std::is_convertible<T, fmt::basic_string_view<Char>>::value ||
|
std::is_convertible<T, fmt::basic_string_view<Char>>::value ||
|
||||||
std::is_same<remove_cvref_t<T>, fmt_runtime_string<Char>>::value> {};
|
std::is_same<remove_cvref_t<T>, fmt_runtime_string<Char>>::value> {
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
||||||
using wstring_view_t = fmt::basic_string_view<wchar_t>;
|
using wstring_view_t = fmt::basic_string_view<wchar_t>;
|
||||||
@ -251,10 +253,11 @@ enum level_enum : int {
|
|||||||
#define SPDLOG_LEVEL_NAME_OFF spdlog::string_view_t("off", 3)
|
#define SPDLOG_LEVEL_NAME_OFF spdlog::string_view_t("off", 3)
|
||||||
|
|
||||||
#if !defined(SPDLOG_LEVEL_NAMES)
|
#if !defined(SPDLOG_LEVEL_NAMES)
|
||||||
#define SPDLOG_LEVEL_NAMES \
|
#define SPDLOG_LEVEL_NAMES \
|
||||||
{ \
|
{ \
|
||||||
SPDLOG_LEVEL_NAME_TRACE, SPDLOG_LEVEL_NAME_DEBUG, SPDLOG_LEVEL_NAME_INFO, SPDLOG_LEVEL_NAME_WARNING, \
|
SPDLOG_LEVEL_NAME_TRACE, SPDLOG_LEVEL_NAME_DEBUG, SPDLOG_LEVEL_NAME_INFO, \
|
||||||
SPDLOG_LEVEL_NAME_ERROR, SPDLOG_LEVEL_NAME_CRITICAL, SPDLOG_LEVEL_NAME_OFF \
|
SPDLOG_LEVEL_NAME_WARNING, SPDLOG_LEVEL_NAME_ERROR, SPDLOG_LEVEL_NAME_CRITICAL, \
|
||||||
|
SPDLOG_LEVEL_NAME_OFF \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -303,9 +306,9 @@ private:
|
|||||||
struct source_loc {
|
struct source_loc {
|
||||||
SPDLOG_CONSTEXPR source_loc() = default;
|
SPDLOG_CONSTEXPR source_loc() = default;
|
||||||
SPDLOG_CONSTEXPR source_loc(const char *filename_in, int line_in, const char *funcname_in)
|
SPDLOG_CONSTEXPR source_loc(const char *filename_in, int line_in, const char *funcname_in)
|
||||||
: filename{filename_in},
|
: filename{filename_in}
|
||||||
line{line_in},
|
, line{line_in}
|
||||||
funcname{funcname_in} {}
|
, funcname{funcname_in} {}
|
||||||
|
|
||||||
SPDLOG_CONSTEXPR bool empty() const SPDLOG_NOEXCEPT { return line == 0; }
|
SPDLOG_CONSTEXPR bool empty() const SPDLOG_NOEXCEPT { return line == 0; }
|
||||||
const char *filename{nullptr};
|
const char *filename{nullptr};
|
||||||
@ -315,10 +318,10 @@ struct source_loc {
|
|||||||
|
|
||||||
struct file_event_handlers {
|
struct file_event_handlers {
|
||||||
file_event_handlers()
|
file_event_handlers()
|
||||||
: before_open(nullptr),
|
: before_open(nullptr)
|
||||||
after_open(nullptr),
|
, after_open(nullptr)
|
||||||
before_close(nullptr),
|
, before_close(nullptr)
|
||||||
after_close(nullptr) {}
|
, after_close(nullptr) {}
|
||||||
|
|
||||||
std::function<void(const filename_t &filename)> before_open;
|
std::function<void(const filename_t &filename)> before_open;
|
||||||
std::function<void(const filename_t &filename, std::FILE *file_stream)> after_open;
|
std::function<void(const filename_t &filename, std::FILE *file_stream)> after_open;
|
||||||
@ -330,18 +333,26 @@ namespace details {
|
|||||||
|
|
||||||
// to_string_view
|
// to_string_view
|
||||||
|
|
||||||
SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t to_string_view(const memory_buf_t &buf) SPDLOG_NOEXCEPT {
|
SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t
|
||||||
|
to_string_view(const memory_buf_t &buf) SPDLOG_NOEXCEPT {
|
||||||
return spdlog::string_view_t{buf.data(), buf.size()};
|
return spdlog::string_view_t{buf.data(), buf.size()};
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t to_string_view(spdlog::string_view_t str) SPDLOG_NOEXCEPT { return str; }
|
SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t
|
||||||
|
to_string_view(spdlog::string_view_t str) SPDLOG_NOEXCEPT {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
||||||
SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t to_string_view(const wmemory_buf_t &buf) SPDLOG_NOEXCEPT {
|
SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t
|
||||||
|
to_string_view(const wmemory_buf_t &buf) SPDLOG_NOEXCEPT {
|
||||||
return spdlog::wstring_view_t{buf.data(), buf.size()};
|
return spdlog::wstring_view_t{buf.data(), buf.size()};
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t to_string_view(spdlog::wstring_view_t str) SPDLOG_NOEXCEPT { return str; }
|
SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t
|
||||||
|
to_string_view(spdlog::wstring_view_t str) SPDLOG_NOEXCEPT {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SPDLOG_USE_STD_FORMAT
|
#ifndef SPDLOG_USE_STD_FORMAT
|
||||||
|
@ -25,8 +25,7 @@ public:
|
|||||||
|
|
||||||
explicit circular_q(size_t max_items)
|
explicit circular_q(size_t max_items)
|
||||||
: max_items_(max_items + 1) // one item is reserved as marker for full q
|
: max_items_(max_items + 1) // one item is reserved as marker for full q
|
||||||
,
|
, v_(max_items_) {}
|
||||||
v_(max_items_) {}
|
|
||||||
|
|
||||||
circular_q(const circular_q &) = default;
|
circular_q(const circular_q &) = default;
|
||||||
circular_q &operator=(const circular_q &) = default;
|
circular_q &operator=(const circular_q &) = default;
|
||||||
|
@ -59,7 +59,8 @@ SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate) {
|
|||||||
details::os::sleep_for_millis(open_interval_);
|
details::os::sleep_for_millis(open_interval_);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw_spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing", errno);
|
throw_spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing",
|
||||||
|
errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void file_helper::reopen(bool truncate) {
|
SPDLOG_INLINE void file_helper::reopen(bool truncate) {
|
||||||
@ -126,7 +127,8 @@ SPDLOG_INLINE const filename_t &file_helper::filename() const { return filename_
|
|||||||
// ".mylog" => (".mylog". "")
|
// ".mylog" => (".mylog". "")
|
||||||
// "my_folder/.mylog" => ("my_folder/.mylog", "")
|
// "my_folder/.mylog" => ("my_folder/.mylog", "")
|
||||||
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
|
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
|
||||||
SPDLOG_INLINE std::tuple<filename_t, filename_t> file_helper::split_by_extension(const filename_t &fname) {
|
SPDLOG_INLINE std::tuple<filename_t, filename_t>
|
||||||
|
file_helper::split_by_extension(const filename_t &fname) {
|
||||||
auto ext_index = fname.rfind('.');
|
auto ext_index = fname.rfind('.');
|
||||||
|
|
||||||
// no valid extension found - return whole path and empty string as
|
// no valid extension found - return whole path and empty string as
|
||||||
|
@ -68,7 +68,8 @@ SPDLOG_CONSTEXPR_FUNC unsigned int count_digits_fallback(T n) {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline unsigned int count_digits(T n) {
|
inline unsigned int count_digits(T n) {
|
||||||
using count_type = typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type;
|
using count_type =
|
||||||
|
typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type;
|
||||||
#ifdef SPDLOG_USE_STD_FORMAT
|
#ifdef SPDLOG_USE_STD_FORMAT
|
||||||
return count_digits_fallback(static_cast<count_type>(n));
|
return count_digits_fallback(static_cast<count_type>(n));
|
||||||
#else
|
#else
|
||||||
|
@ -17,16 +17,14 @@ SPDLOG_INLINE log_msg::log_msg(spdlog::log_clock::time_point log_time,
|
|||||||
string_view_t a_logger_name,
|
string_view_t a_logger_name,
|
||||||
spdlog::level::level_enum lvl,
|
spdlog::level::level_enum lvl,
|
||||||
spdlog::string_view_t msg)
|
spdlog::string_view_t msg)
|
||||||
: logger_name(a_logger_name),
|
: logger_name(a_logger_name)
|
||||||
level(lvl),
|
, level(lvl)
|
||||||
time(log_time)
|
, time(log_time)
|
||||||
#ifndef SPDLOG_NO_THREAD_ID
|
#ifndef SPDLOG_NO_THREAD_ID
|
||||||
,
|
, thread_id(os::thread_id())
|
||||||
thread_id(os::thread_id())
|
|
||||||
#endif
|
#endif
|
||||||
,
|
, source(loc)
|
||||||
source(loc),
|
, payload(msg) {
|
||||||
payload(msg) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE log_msg::log_msg(spdlog::source_loc loc,
|
SPDLOG_INLINE log_msg::log_msg(spdlog::source_loc loc,
|
||||||
@ -35,7 +33,9 @@ SPDLOG_INLINE log_msg::log_msg(spdlog::source_loc loc,
|
|||||||
spdlog::string_view_t msg)
|
spdlog::string_view_t msg)
|
||||||
: log_msg(os::now(), loc, a_logger_name, lvl, msg) {}
|
: log_msg(os::now(), 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_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) {}
|
: log_msg(os::now(), source_loc{}, a_logger_name, lvl, msg) {}
|
||||||
|
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
@ -24,8 +24,9 @@ SPDLOG_INLINE log_msg_buffer::log_msg_buffer(const log_msg_buffer &other)
|
|||||||
update_string_views();
|
update_string_views();
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE log_msg_buffer::log_msg_buffer(log_msg_buffer &&other) SPDLOG_NOEXCEPT : log_msg{other},
|
SPDLOG_INLINE log_msg_buffer::log_msg_buffer(log_msg_buffer &&other) SPDLOG_NOEXCEPT
|
||||||
buffer{std::move(other.buffer)} {
|
: log_msg{other},
|
||||||
|
buffer{std::move(other.buffer)} {
|
||||||
update_string_views();
|
update_string_views();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +79,8 @@ SPDLOG_INLINE spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT {
|
|||||||
timespec ts;
|
timespec ts;
|
||||||
::clock_gettime(CLOCK_REALTIME_COARSE, &ts);
|
::clock_gettime(CLOCK_REALTIME_COARSE, &ts);
|
||||||
return std::chrono::time_point<log_clock, typename log_clock::duration>(
|
return std::chrono::time_point<log_clock, typename log_clock::duration>(
|
||||||
std::chrono::duration_cast<typename log_clock::duration>(std::chrono::seconds(ts.tv_sec) +
|
std::chrono::duration_cast<typename log_clock::duration>(
|
||||||
std::chrono::nanoseconds(ts.tv_nsec)));
|
std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec)));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
return log_clock::now();
|
return log_clock::now();
|
||||||
@ -140,7 +140,8 @@ SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename
|
|||||||
#else // unix
|
#else // unix
|
||||||
#if defined(SPDLOG_PREVENT_CHILD_FD)
|
#if defined(SPDLOG_PREVENT_CHILD_FD)
|
||||||
const int mode_flag = mode == SPDLOG_FILENAME_T("ab") ? O_APPEND : O_TRUNC;
|
const int mode_flag = mode == SPDLOG_FILENAME_T("ab") ? O_APPEND : O_TRUNC;
|
||||||
const int fd = ::open((filename.c_str()), O_CREAT | O_WRONLY | O_CLOEXEC | mode_flag, mode_t(0644));
|
const int fd =
|
||||||
|
::open((filename.c_str()), O_CREAT | O_WRONLY | O_CLOEXEC | mode_flag, mode_t(0644));
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -269,7 +270,8 @@ SPDLOG_INLINE int utc_minutes_offset(const std::tm &tm) {
|
|||||||
return offset;
|
return offset;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if defined(sun) || defined(__sun) || defined(_AIX) || (defined(__NEWLIB__) && !defined(__TM_GMTOFF)) || \
|
#if defined(sun) || defined(__sun) || defined(_AIX) || \
|
||||||
|
(defined(__NEWLIB__) && !defined(__TM_GMTOFF)) || \
|
||||||
(!defined(_BSD_SOURCE) && !defined(_GNU_SOURCE))
|
(!defined(_BSD_SOURCE) && !defined(_GNU_SOURCE))
|
||||||
// 'tm_gmtoff' field is BSD extension and it's missing on SunOS/Solaris
|
// 'tm_gmtoff' field is BSD extension and it's missing on SunOS/Solaris
|
||||||
struct helper {
|
struct helper {
|
||||||
@ -407,17 +409,18 @@ SPDLOG_INLINE bool is_color_terminal() SPDLOG_NOEXCEPT {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr std::array<const char *, 16> terms = {{"ansi", "color", "console", "cygwin", "gnome",
|
static constexpr std::array<const char *, 16> terms = {
|
||||||
"konsole", "kterm", "linux", "msys", "putty", "rxvt",
|
{"ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", "linux", "msys",
|
||||||
"screen", "vt100", "xterm", "alacritty", "vt102"}};
|
"putty", "rxvt", "screen", "vt100", "xterm", "alacritty", "vt102"}};
|
||||||
|
|
||||||
const char *env_term_p = std::getenv("TERM");
|
const char *env_term_p = std::getenv("TERM");
|
||||||
if (env_term_p == nullptr) {
|
if (env_term_p == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::any_of(terms.begin(), terms.end(),
|
return std::any_of(terms.begin(), terms.end(), [&](const char *term) {
|
||||||
[&](const char *term) { return std::strstr(env_term_p, term) != nullptr; });
|
return std::strstr(env_term_p, term) != nullptr;
|
||||||
|
});
|
||||||
}();
|
}();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -449,12 +452,14 @@ SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target) {
|
|||||||
|
|
||||||
int result_size = static_cast<int>(target.capacity());
|
int result_size = static_cast<int>(target.capacity());
|
||||||
if ((wstr_size + 1) * 2 > result_size) {
|
if ((wstr_size + 1) * 2 > result_size) {
|
||||||
result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, NULL, 0, NULL, NULL);
|
result_size =
|
||||||
|
::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, NULL, 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result_size > 0) {
|
if (result_size > 0) {
|
||||||
target.resize(result_size);
|
target.resize(result_size);
|
||||||
result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, target.data(), result_size, NULL, NULL);
|
result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, target.data(),
|
||||||
|
result_size, NULL, NULL);
|
||||||
|
|
||||||
if (result_size > 0) {
|
if (result_size > 0) {
|
||||||
target.resize(result_size);
|
target.resize(result_size);
|
||||||
@ -462,7 +467,8 @@ SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw_spdlog_ex(fmt_lib::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()));
|
throw_spdlog_ex(
|
||||||
|
fmt_lib::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) {
|
SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) {
|
||||||
@ -477,21 +483,24 @@ SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// find the size to allocate for the result buffer
|
// find the size to allocate for the result buffer
|
||||||
int result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, NULL, 0);
|
int result_size =
|
||||||
|
::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, NULL, 0);
|
||||||
|
|
||||||
if (result_size > 0) {
|
if (result_size > 0) {
|
||||||
target.resize(result_size);
|
target.resize(result_size);
|
||||||
result_size =
|
result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size,
|
||||||
::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, target.data(), result_size);
|
target.data(), result_size);
|
||||||
if (result_size > 0) {
|
if (result_size > 0) {
|
||||||
assert(result_size == target.size());
|
assert(result_size == target.size());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw_spdlog_ex(fmt_lib::format("MultiByteToWideChar failed. Last error: {}", ::GetLastError()));
|
throw_spdlog_ex(
|
||||||
|
fmt_lib::format("MultiByteToWideChar failed. Last error: {}", ::GetLastError()));
|
||||||
}
|
}
|
||||||
#endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
|
#endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) &&
|
||||||
|
// defined(_WIN32)
|
||||||
|
|
||||||
// return true on success
|
// return true on success
|
||||||
static SPDLOG_INLINE bool mkdir_(const filename_t &path) {
|
static SPDLOG_INLINE bool mkdir_(const filename_t &path) {
|
||||||
|
@ -41,7 +41,8 @@ SPDLOG_CONSTEXPR static const char *default_eol = SPDLOG_EOL;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
SPDLOG_CONSTEXPR static const char folder_seps[] = SPDLOG_FOLDER_SEPS;
|
SPDLOG_CONSTEXPR static const char folder_seps[] = SPDLOG_FOLDER_SEPS;
|
||||||
SPDLOG_CONSTEXPR static const filename_t::value_type folder_seps_filename[] = SPDLOG_FILENAME_T(SPDLOG_FOLDER_SEPS);
|
SPDLOG_CONSTEXPR static const filename_t::value_type folder_seps_filename[] =
|
||||||
|
SPDLOG_FILENAME_T(SPDLOG_FOLDER_SEPS);
|
||||||
|
|
||||||
// fopen_s on non windows for writing
|
// fopen_s on non windows for writing
|
||||||
SPDLOG_API bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode);
|
SPDLOG_API bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode);
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
//
|
//
|
||||||
// RAII over the owned thread:
|
// RAII over the owned thread:
|
||||||
// creates the thread on construction.
|
// creates the thread on construction.
|
||||||
// stops and joins the thread on destruction (if the thread is executing a callback, wait for it to finish first).
|
// stops and joins the thread on destruction (if the thread is executing a callback, wait for it
|
||||||
|
// to finish first).
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@ -20,7 +21,8 @@ namespace details {
|
|||||||
class SPDLOG_API periodic_worker {
|
class SPDLOG_API periodic_worker {
|
||||||
public:
|
public:
|
||||||
template <typename Rep, typename Period>
|
template <typename Rep, typename Period>
|
||||||
periodic_worker(const std::function<void()> &callback_fun, std::chrono::duration<Rep, Period> interval) {
|
periodic_worker(const std::function<void()> &callback_fun,
|
||||||
|
std::chrono::duration<Rep, Period> interval) {
|
||||||
active_ = (interval > std::chrono::duration<Rep, Period>::zero());
|
active_ = (interval > std::chrono::duration<Rep, Period>::zero());
|
||||||
if (!active_) {
|
if (!active_) {
|
||||||
return;
|
return;
|
||||||
|
@ -170,7 +170,8 @@ SPDLOG_INLINE void registry::set_error_handler(err_handler handler) {
|
|||||||
err_handler_ = std::move(handler);
|
err_handler_ = std::move(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void registry::apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun) {
|
SPDLOG_INLINE void
|
||||||
|
registry::apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun) {
|
||||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||||
for (auto &l : loggers_) {
|
for (auto &l : loggers_) {
|
||||||
fun(l.second);
|
fun(l.second);
|
||||||
|
@ -38,7 +38,8 @@ public:
|
|||||||
// Return raw ptr to the default logger.
|
// Return raw ptr to the default logger.
|
||||||
// To be used directly by the spdlog default api (e.g. spdlog::info)
|
// To be used directly by the spdlog default api (e.g. spdlog::info)
|
||||||
// This make the default API faster, but cannot be used concurrently with set_default_logger().
|
// This make the default API faster, but cannot be used concurrently with set_default_logger().
|
||||||
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
|
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from
|
||||||
|
// another.
|
||||||
logger *get_default_raw();
|
logger *get_default_raw();
|
||||||
|
|
||||||
// set default logger.
|
// set default logger.
|
||||||
|
@ -34,8 +34,9 @@ class tcp_client {
|
|||||||
|
|
||||||
static void throw_winsock_error_(const std::string &msg, int last_error) {
|
static void throw_winsock_error_(const std::string &msg, int last_error) {
|
||||||
char buf[512];
|
char buf[512];
|
||||||
::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error,
|
::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(char)), NULL);
|
last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf,
|
||||||
|
(sizeof(buf) / sizeof(char)), NULL);
|
||||||
|
|
||||||
throw_spdlog_ex(fmt_lib::format("tcp_sink - {}: {}", msg, buf));
|
throw_spdlog_ex(fmt_lib::format("tcp_sink - {}: {}", msg, buf));
|
||||||
}
|
}
|
||||||
@ -104,7 +105,8 @@ public:
|
|||||||
|
|
||||||
// set TCP_NODELAY
|
// set TCP_NODELAY
|
||||||
int enable_flag = 1;
|
int enable_flag = 1;
|
||||||
::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&enable_flag), sizeof(enable_flag));
|
::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&enable_flag),
|
||||||
|
sizeof(enable_flag));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send exactly n_bytes of the given data.
|
// Send exactly n_bytes of the given data.
|
||||||
@ -113,7 +115,8 @@ public:
|
|||||||
size_t bytes_sent = 0;
|
size_t bytes_sent = 0;
|
||||||
while (bytes_sent < n_bytes) {
|
while (bytes_sent < n_bytes) {
|
||||||
const int send_flags = 0;
|
const int send_flags = 0;
|
||||||
auto write_result = ::send(socket_, data + bytes_sent, (int)(n_bytes - bytes_sent), send_flags);
|
auto write_result =
|
||||||
|
::send(socket_, data + bytes_sent, (int)(n_bytes - bytes_sent), send_flags);
|
||||||
if (write_result == SOCKET_ERROR) {
|
if (write_result == SOCKET_ERROR) {
|
||||||
int last_error = ::WSAGetLastError();
|
int last_error = ::WSAGetLastError();
|
||||||
close();
|
close();
|
||||||
|
@ -84,11 +84,13 @@ public:
|
|||||||
|
|
||||||
// set TCP_NODELAY
|
// set TCP_NODELAY
|
||||||
int enable_flag = 1;
|
int enable_flag = 1;
|
||||||
::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&enable_flag), sizeof(enable_flag));
|
::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&enable_flag),
|
||||||
|
sizeof(enable_flag));
|
||||||
|
|
||||||
// prevent sigpipe on systems where MSG_NOSIGNAL is not available
|
// prevent sigpipe on systems where MSG_NOSIGNAL is not available
|
||||||
#if defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
|
#if defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
|
||||||
::setsockopt(socket_, SOL_SOCKET, SO_NOSIGPIPE, reinterpret_cast<char *>(&enable_flag), sizeof(enable_flag));
|
::setsockopt(socket_, SOL_SOCKET, SO_NOSIGPIPE, reinterpret_cast<char *>(&enable_flag),
|
||||||
|
sizeof(enable_flag));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
|
#if !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
|
||||||
@ -106,7 +108,8 @@ public:
|
|||||||
#else
|
#else
|
||||||
const int send_flags = 0;
|
const int send_flags = 0;
|
||||||
#endif
|
#endif
|
||||||
auto write_result = ::send(socket_, data + bytes_sent, n_bytes - bytes_sent, send_flags);
|
auto write_result =
|
||||||
|
::send(socket_, data + bytes_sent, n_bytes - bytes_sent, send_flags);
|
||||||
if (write_result < 0) {
|
if (write_result < 0) {
|
||||||
close();
|
close();
|
||||||
throw_spdlog_ex("write(2) failed", errno);
|
throw_spdlog_ex("write(2) failed", errno);
|
||||||
|
@ -31,7 +31,9 @@ SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n, std::function<void()> on_thread_start)
|
SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items,
|
||||||
|
size_t threads_n,
|
||||||
|
std::function<void()> on_thread_start)
|
||||||
: thread_pool(q_max_items, threads_n, on_thread_start, [] {}) {}
|
: thread_pool(q_max_items, threads_n, on_thread_start, [] {}) {}
|
||||||
|
|
||||||
SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n)
|
SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n)
|
||||||
@ -59,7 +61,8 @@ void SPDLOG_INLINE thread_pool::post_log(async_logger_ptr &&worker_ptr,
|
|||||||
post_async_msg_(std::move(async_m), overflow_policy);
|
post_async_msg_(std::move(async_m), overflow_policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPDLOG_INLINE thread_pool::post_flush(async_logger_ptr &&worker_ptr, async_overflow_policy overflow_policy) {
|
void SPDLOG_INLINE thread_pool::post_flush(async_logger_ptr &&worker_ptr,
|
||||||
|
async_overflow_policy overflow_policy) {
|
||||||
post_async_msg_(async_msg(std::move(worker_ptr), async_msg_type::flush), overflow_policy);
|
post_async_msg_(async_msg(std::move(worker_ptr), async_msg_type::flush), overflow_policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +76,8 @@ void SPDLOG_INLINE thread_pool::reset_discard_counter() { q_.reset_discard_count
|
|||||||
|
|
||||||
size_t SPDLOG_INLINE thread_pool::queue_size() { return q_.size(); }
|
size_t SPDLOG_INLINE thread_pool::queue_size() { return q_.size(); }
|
||||||
|
|
||||||
void SPDLOG_INLINE thread_pool::post_async_msg_(async_msg &&new_msg, async_overflow_policy overflow_policy) {
|
void SPDLOG_INLINE thread_pool::post_async_msg_(async_msg &&new_msg,
|
||||||
|
async_overflow_policy overflow_policy) {
|
||||||
if (overflow_policy == async_overflow_policy::block) {
|
if (overflow_policy == async_overflow_policy::block) {
|
||||||
q_.enqueue(std::move(new_msg));
|
q_.enqueue(std::move(new_msg));
|
||||||
} else if (overflow_policy == async_overflow_policy::overrun_oldest) {
|
} else if (overflow_policy == async_overflow_policy::overrun_oldest) {
|
||||||
|
@ -37,9 +37,9 @@ struct async_msg : log_msg_buffer {
|
|||||||
// support for vs2013 move
|
// support for vs2013 move
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
||||||
async_msg(async_msg &&other)
|
async_msg(async_msg &&other)
|
||||||
: log_msg_buffer(std::move(other)),
|
: log_msg_buffer(std::move(other))
|
||||||
msg_type(other.msg_type),
|
, msg_type(other.msg_type)
|
||||||
worker_ptr(std::move(other.worker_ptr)) {}
|
, worker_ptr(std::move(other.worker_ptr)) {}
|
||||||
|
|
||||||
async_msg &operator=(async_msg &&other) {
|
async_msg &operator=(async_msg &&other) {
|
||||||
*static_cast<log_msg_buffer *>(this) = std::move(other);
|
*static_cast<log_msg_buffer *>(this) = std::move(other);
|
||||||
@ -54,14 +54,14 @@ struct async_msg : log_msg_buffer {
|
|||||||
|
|
||||||
// construct from log_msg with given type
|
// construct from log_msg with given type
|
||||||
async_msg(async_logger_ptr &&worker, async_msg_type the_type, const details::log_msg &m)
|
async_msg(async_logger_ptr &&worker, async_msg_type the_type, const details::log_msg &m)
|
||||||
: log_msg_buffer{m},
|
: log_msg_buffer{m}
|
||||||
msg_type{the_type},
|
, msg_type{the_type}
|
||||||
worker_ptr{std::move(worker)} {}
|
, worker_ptr{std::move(worker)} {}
|
||||||
|
|
||||||
async_msg(async_logger_ptr &&worker, async_msg_type the_type)
|
async_msg(async_logger_ptr &&worker, async_msg_type the_type)
|
||||||
: log_msg_buffer{},
|
: log_msg_buffer{}
|
||||||
msg_type{the_type},
|
, msg_type{the_type}
|
||||||
worker_ptr{std::move(worker)} {}
|
, worker_ptr{std::move(worker)} {}
|
||||||
|
|
||||||
explicit async_msg(async_msg_type the_type)
|
explicit async_msg(async_msg_type the_type)
|
||||||
: async_msg{nullptr, the_type} {}
|
: async_msg{nullptr, the_type} {}
|
||||||
@ -85,7 +85,9 @@ public:
|
|||||||
thread_pool(const thread_pool &) = delete;
|
thread_pool(const thread_pool &) = delete;
|
||||||
thread_pool &operator=(thread_pool &&) = delete;
|
thread_pool &operator=(thread_pool &&) = delete;
|
||||||
|
|
||||||
void post_log(async_logger_ptr &&worker_ptr, const details::log_msg &msg, async_overflow_policy overflow_policy);
|
void post_log(async_logger_ptr &&worker_ptr,
|
||||||
|
const details::log_msg &msg,
|
||||||
|
async_overflow_policy overflow_policy);
|
||||||
void post_flush(async_logger_ptr &&worker_ptr, async_overflow_policy overflow_policy);
|
void post_flush(async_logger_ptr &&worker_ptr, async_overflow_policy overflow_policy);
|
||||||
size_t overrun_counter();
|
size_t overrun_counter();
|
||||||
void reset_overrun_counter();
|
void reset_overrun_counter();
|
||||||
|
@ -38,8 +38,9 @@ class udp_client {
|
|||||||
|
|
||||||
static void throw_winsock_error_(const std::string &msg, int last_error) {
|
static void throw_winsock_error_(const std::string &msg, int last_error) {
|
||||||
char buf[512];
|
char buf[512];
|
||||||
::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error,
|
::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(char)), NULL);
|
last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf,
|
||||||
|
(sizeof(buf) / sizeof(char)), NULL);
|
||||||
|
|
||||||
throw_spdlog_ex(fmt_lib::format("udp_sink - {}: {}", msg, buf));
|
throw_spdlog_ex(fmt_lib::format("udp_sink - {}: {}", msg, buf));
|
||||||
}
|
}
|
||||||
@ -73,8 +74,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int option_value = TX_BUFFER_SIZE;
|
int option_value = TX_BUFFER_SIZE;
|
||||||
if (::setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<const char *>(&option_value),
|
if (::setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
|
||||||
sizeof(option_value)) < 0) {
|
reinterpret_cast<const char *>(&option_value), sizeof(option_value)) < 0) {
|
||||||
int last_error = ::WSAGetLastError();
|
int last_error = ::WSAGetLastError();
|
||||||
cleanup_();
|
cleanup_();
|
||||||
throw_winsock_error_("error: setsockopt(SO_SNDBUF) Failed!", last_error);
|
throw_winsock_error_("error: setsockopt(SO_SNDBUF) Failed!", last_error);
|
||||||
@ -87,7 +88,8 @@ public:
|
|||||||
|
|
||||||
void send(const char *data, size_t n_bytes) {
|
void send(const char *data, size_t n_bytes) {
|
||||||
socklen_t tolen = sizeof(struct sockaddr);
|
socklen_t tolen = sizeof(struct sockaddr);
|
||||||
if (::sendto(socket_, data, static_cast<int>(n_bytes), 0, (struct sockaddr *)&addr_, tolen) == -1) {
|
if (::sendto(socket_, data, static_cast<int>(n_bytes), 0, (struct sockaddr *)&addr_,
|
||||||
|
tolen) == -1) {
|
||||||
throw_spdlog_ex("sendto(2) failed", errno);
|
throw_spdlog_ex("sendto(2) failed", errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int option_value = TX_BUFFER_SIZE;
|
int option_value = TX_BUFFER_SIZE;
|
||||||
if (::setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<const char *>(&option_value),
|
if (::setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
|
||||||
sizeof(option_value)) < 0) {
|
reinterpret_cast<const char *>(&option_value), sizeof(option_value)) < 0) {
|
||||||
cleanup_();
|
cleanup_();
|
||||||
throw_spdlog_ex("error: setsockopt(SO_SNDBUF) Failed!");
|
throw_spdlog_ex("error: setsockopt(SO_SNDBUF) Failed!");
|
||||||
}
|
}
|
||||||
@ -71,7 +71,8 @@ public:
|
|||||||
void send(const char *data, size_t n_bytes) {
|
void send(const char *data, size_t n_bytes) {
|
||||||
ssize_t toslen = 0;
|
ssize_t toslen = 0;
|
||||||
socklen_t tolen = sizeof(struct sockaddr);
|
socklen_t tolen = sizeof(struct sockaddr);
|
||||||
if ((toslen = ::sendto(socket_, data, n_bytes, 0, (struct sockaddr *)&sockAddr_, tolen)) == -1) {
|
if ((toslen = ::sendto(socket_, data, n_bytes, 0, (struct sockaddr *)&sockAddr_, tolen)) ==
|
||||||
|
-1) {
|
||||||
throw_spdlog_ex("sendto(2) failed", errno);
|
throw_spdlog_ex("sendto(2) failed", errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ template <typename It>
|
|||||||
class dump_info {
|
class dump_info {
|
||||||
public:
|
public:
|
||||||
dump_info(It range_begin, It range_end, size_t size_per_line)
|
dump_info(It range_begin, It range_end, size_t size_per_line)
|
||||||
: begin_(range_begin),
|
: begin_(range_begin)
|
||||||
end_(range_end),
|
, end_(range_end)
|
||||||
size_per_line_(size_per_line) {}
|
, size_per_line_(size_per_line) {}
|
||||||
|
|
||||||
// do not use begin() and end() to avoid collision with fmt/ranges
|
// do not use begin() and end() to avoid collision with fmt/ranges
|
||||||
It get_begin() const { return begin_; }
|
It get_begin() const { return begin_; }
|
||||||
@ -62,7 +62,8 @@ private:
|
|||||||
template <typename Container>
|
template <typename Container>
|
||||||
inline details::dump_info<typename Container::const_iterator> to_hex(const Container &container,
|
inline details::dump_info<typename Container::const_iterator> to_hex(const Container &container,
|
||||||
size_t size_per_line = 32) {
|
size_t size_per_line = 32) {
|
||||||
static_assert(sizeof(typename Container::value_type) == 1, "sizeof(Container::value_type) != 1");
|
static_assert(sizeof(typename Container::value_type) == 1,
|
||||||
|
"sizeof(Container::value_type) != 1");
|
||||||
using Iter = typename Container::const_iterator;
|
using Iter = typename Container::const_iterator;
|
||||||
return details::dump_info<Iter>(std::begin(container), std::end(container), size_per_line);
|
return details::dump_info<Iter>(std::begin(container), std::end(container), size_per_line);
|
||||||
}
|
}
|
||||||
@ -70,10 +71,11 @@ inline details::dump_info<typename Container::const_iterator> to_hex(const Conta
|
|||||||
#if __cpp_lib_span >= 202002L
|
#if __cpp_lib_span >= 202002L
|
||||||
|
|
||||||
template <typename Value, size_t Extent>
|
template <typename Value, size_t Extent>
|
||||||
inline details::dump_info<typename std::span<Value, Extent>::iterator> to_hex(const std::span<Value, Extent> &container,
|
inline details::dump_info<typename std::span<Value, Extent>::iterator>
|
||||||
size_t size_per_line = 32) {
|
to_hex(const std::span<Value, Extent> &container, size_t size_per_line = 32) {
|
||||||
using Container = std::span<Value, Extent>;
|
using Container = std::span<Value, Extent>;
|
||||||
static_assert(sizeof(typename Container::value_type) == 1, "sizeof(Container::value_type) != 1");
|
static_assert(sizeof(typename Container::value_type) == 1,
|
||||||
|
"sizeof(Container::value_type) != 1");
|
||||||
using Iter = typename Container::iterator;
|
using Iter = typename Container::iterator;
|
||||||
return details::dump_info<Iter>(std::begin(container), std::end(container), size_per_line);
|
return details::dump_info<Iter>(std::begin(container), std::end(container), size_per_line);
|
||||||
}
|
}
|
||||||
@ -82,7 +84,8 @@ inline details::dump_info<typename std::span<Value, Extent>::iterator> to_hex(co
|
|||||||
|
|
||||||
// create dump_info from ranges
|
// create dump_info from ranges
|
||||||
template <typename It>
|
template <typename It>
|
||||||
inline details::dump_info<It> to_hex(const It range_begin, const It range_end, size_t size_per_line = 32) {
|
inline details::dump_info<It>
|
||||||
|
to_hex(const It range_begin, const It range_end, size_t size_per_line = 32) {
|
||||||
return details::dump_info<It>(range_begin, range_end, size_per_line);
|
return details::dump_info<It>(range_begin, range_end, size_per_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +158,8 @@ struct formatter<spdlog::details::dump_info<T>, char> {
|
|||||||
for (auto i = the_range.get_begin(); i != the_range.get_end(); i++) {
|
for (auto i = the_range.get_begin(); i != the_range.get_end(); i++) {
|
||||||
auto ch = static_cast<unsigned char>(*i);
|
auto ch = static_cast<unsigned char>(*i);
|
||||||
|
|
||||||
if (put_newlines && (i == the_range.get_begin() || i - start_of_line >= size_per_line)) {
|
if (put_newlines &&
|
||||||
|
(i == the_range.get_begin() || i - start_of_line >= size_per_line)) {
|
||||||
if (show_ascii && i != the_range.get_begin()) {
|
if (show_ascii && i != the_range.get_begin()) {
|
||||||
*inserter++ = delimiter;
|
*inserter++ = delimiter;
|
||||||
*inserter++ = delimiter;
|
*inserter++ = delimiter;
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
//
|
//
|
||||||
// include bundled or external copy of fmtlib's std support (for formatting e.g. std::filesystem::path, std::thread::id,
|
// include bundled or external copy of fmtlib's std support (for formatting e.g.
|
||||||
// std::monostate, std::variant, ...)
|
// std::filesystem::path, std::thread::id, std::monostate, std::variant, ...)
|
||||||
//
|
//
|
||||||
|
|
||||||
#if !defined(SPDLOG_USE_STD_FORMAT)
|
#if !defined(SPDLOG_USE_STD_FORMAT)
|
||||||
|
@ -17,12 +17,12 @@ namespace spdlog {
|
|||||||
|
|
||||||
// public methods
|
// public methods
|
||||||
SPDLOG_INLINE logger::logger(const logger &other)
|
SPDLOG_INLINE logger::logger(const logger &other)
|
||||||
: name_(other.name_),
|
: name_(other.name_)
|
||||||
sinks_(other.sinks_),
|
, sinks_(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_(other.custom_err_handler_),
|
, custom_err_handler_(other.custom_err_handler_)
|
||||||
tracer_(other.tracer_) {}
|
, tracer_(other.tracer_) {}
|
||||||
|
|
||||||
SPDLOG_INLINE logger::logger(logger &&other) SPDLOG_NOEXCEPT
|
SPDLOG_INLINE logger::logger(logger &&other) SPDLOG_NOEXCEPT
|
||||||
: name_(std::move(other.name_)),
|
: name_(std::move(other.name_)),
|
||||||
@ -109,7 +109,9 @@ SPDLOG_INLINE const std::vector<sink_ptr> &logger::sinks() const { return sinks_
|
|||||||
SPDLOG_INLINE std::vector<sink_ptr> &logger::sinks() { return sinks_; }
|
SPDLOG_INLINE std::vector<sink_ptr> &logger::sinks() { return sinks_; }
|
||||||
|
|
||||||
// error handler
|
// error handler
|
||||||
SPDLOG_INLINE void logger::set_error_handler(err_handler handler) { custom_err_handler_ = std::move(handler); }
|
SPDLOG_INLINE void logger::set_error_handler(err_handler handler) {
|
||||||
|
custom_err_handler_ = std::move(handler);
|
||||||
|
}
|
||||||
|
|
||||||
// create new logger with same sinks and configuration.
|
// create new logger with same sinks and configuration.
|
||||||
SPDLOG_INLINE std::shared_ptr<logger> logger::clone(std::string logger_name) {
|
SPDLOG_INLINE std::shared_ptr<logger> logger::clone(std::string logger_name) {
|
||||||
@ -119,7 +121,8 @@ SPDLOG_INLINE std::shared_ptr<logger> logger::clone(std::string logger_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// protected methods
|
// protected methods
|
||||||
SPDLOG_INLINE void logger::log_it_(const spdlog::details::log_msg &log_msg, bool log_enabled, bool traceback_enabled) {
|
SPDLOG_INLINE void
|
||||||
|
logger::log_it_(const spdlog::details::log_msg &log_msg, bool log_enabled, bool traceback_enabled) {
|
||||||
if (log_enabled) {
|
if (log_enabled) {
|
||||||
sink_it_(log_msg);
|
sink_it_(log_msg);
|
||||||
}
|
}
|
||||||
@ -151,9 +154,11 @@ SPDLOG_INLINE void logger::flush_() {
|
|||||||
SPDLOG_INLINE void logger::dump_backtrace_() {
|
SPDLOG_INLINE void logger::dump_backtrace_() {
|
||||||
using details::log_msg;
|
using details::log_msg;
|
||||||
if (tracer_.enabled() && !tracer_.empty()) {
|
if (tracer_.enabled() && !tracer_.empty()) {
|
||||||
sink_it_(log_msg{name(), level::info, "****************** Backtrace Start ******************"});
|
sink_it_(
|
||||||
|
log_msg{name(), level::info, "****************** Backtrace Start ******************"});
|
||||||
tracer_.foreach_pop([this](const log_msg &msg) { this->sink_it_(msg); });
|
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 ********************"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,10 +186,11 @@ SPDLOG_INLINE void logger::err_handler_(const std::string &msg) {
|
|||||||
char date_buf[64];
|
char date_buf[64];
|
||||||
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
|
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
|
||||||
#if defined(USING_R) && defined(R_R_H) // if in R environment
|
#if defined(USING_R) && defined(R_R_H) // if in R environment
|
||||||
REprintf("[*** LOG ERROR #%04zu ***] [%s] [%s] %s\n", err_counter, date_buf, name().c_str(), msg.c_str());
|
REprintf("[*** LOG ERROR #%04zu ***] [%s] [%s] %s\n", err_counter, date_buf, name().c_str(),
|
||||||
|
msg.c_str());
|
||||||
#else
|
#else
|
||||||
std::fprintf(stderr, "[*** LOG ERROR #%04zu ***] [%s] [%s] %s\n", err_counter, date_buf, name().c_str(),
|
std::fprintf(stderr, "[*** LOG ERROR #%04zu ***] [%s] [%s] %s\n", err_counter, date_buf,
|
||||||
msg.c_str());
|
name().c_str(), msg.c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,18 +28,18 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifndef SPDLOG_NO_EXCEPTIONS
|
#ifndef SPDLOG_NO_EXCEPTIONS
|
||||||
#define SPDLOG_LOGGER_CATCH(location) \
|
#define SPDLOG_LOGGER_CATCH(location) \
|
||||||
catch (const std::exception &ex) { \
|
catch (const std::exception &ex) { \
|
||||||
if (location.filename) { \
|
if (location.filename) { \
|
||||||
err_handler_( \
|
err_handler_(fmt_lib::format(SPDLOG_FMT_STRING("{} [{}({})]"), ex.what(), \
|
||||||
fmt_lib::format(SPDLOG_FMT_STRING("{} [{}({})]"), ex.what(), location.filename, location.line)); \
|
location.filename, location.line)); \
|
||||||
} else { \
|
} else { \
|
||||||
err_handler_(ex.what()); \
|
err_handler_(ex.what()); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
catch (...) { \
|
catch (...) { \
|
||||||
err_handler_("Rethrowing unknown exception in logger"); \
|
err_handler_("Rethrowing unknown exception in logger"); \
|
||||||
throw; \
|
throw; \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define SPDLOG_LOGGER_CATCH(location)
|
#define SPDLOG_LOGGER_CATCH(location)
|
||||||
@ -51,14 +51,14 @@ class SPDLOG_API logger {
|
|||||||
public:
|
public:
|
||||||
// Empty logger
|
// Empty logger
|
||||||
explicit logger(std::string name)
|
explicit logger(std::string name)
|
||||||
: name_(std::move(name)),
|
: name_(std::move(name))
|
||||||
sinks_() {}
|
, sinks_() {}
|
||||||
|
|
||||||
// Logger with range on sinks
|
// Logger with range on sinks
|
||||||
template <typename It>
|
template <typename It>
|
||||||
logger(std::string name, It begin, It end)
|
logger(std::string name, It begin, It end)
|
||||||
: name_(std::move(name)),
|
: name_(std::move(name))
|
||||||
sinks_(begin, end) {}
|
, sinks_(begin, end) {}
|
||||||
|
|
||||||
// Logger with single sink
|
// Logger with single sink
|
||||||
logger(std::string name, sink_ptr single_sink)
|
logger(std::string name, sink_ptr single_sink)
|
||||||
@ -91,12 +91,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// T cannot be statically converted to format string (including string_view/wstring_view)
|
// T cannot be statically converted to format string (including string_view/wstring_view)
|
||||||
template <class T, typename std::enable_if<!is_convertible_to_any_format_string<const T &>::value, int>::type = 0>
|
template <class T,
|
||||||
|
typename std::enable_if<!is_convertible_to_any_format_string<const T &>::value,
|
||||||
|
int>::type = 0>
|
||||||
void log(source_loc loc, level::level_enum lvl, const T &msg) {
|
void log(source_loc loc, level::level_enum lvl, const T &msg) {
|
||||||
log(loc, lvl, "{}", msg);
|
log(loc, lvl, "{}", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
bool traceback_enabled = tracer_.enabled();
|
||||||
if (!log_enabled && !traceback_enabled) {
|
if (!log_enabled && !traceback_enabled) {
|
||||||
@ -161,7 +164,8 @@ public:
|
|||||||
log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
|
log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, wstring_view_t msg) {
|
void
|
||||||
|
log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, wstring_view_t msg) {
|
||||||
bool log_enabled = should_log(lvl);
|
bool log_enabled = should_log(lvl);
|
||||||
bool traceback_enabled = tracer_.enabled();
|
bool traceback_enabled = tracer_.enabled();
|
||||||
if (!log_enabled && !traceback_enabled) {
|
if (!log_enabled && !traceback_enabled) {
|
||||||
@ -251,7 +255,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return true logging is enabled for the given level.
|
// return true logging is enabled for the given level.
|
||||||
bool should_log(level::level_enum msg_level) const { return msg_level >= level_.load(std::memory_order_relaxed); }
|
bool should_log(level::level_enum msg_level) const {
|
||||||
|
return msg_level >= level_.load(std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
// return true if backtrace logging is enabled.
|
// return true if backtrace logging is enabled.
|
||||||
bool should_backtrace() const { return tracer_.enabled(); }
|
bool should_backtrace() const { return tracer_.enabled(); }
|
||||||
|
@ -37,8 +37,8 @@ namespace details {
|
|||||||
class scoped_padder {
|
class scoped_padder {
|
||||||
public:
|
public:
|
||||||
scoped_padder(size_t wrapped_size, const padding_info &padinfo, memory_buf_t &dest)
|
scoped_padder(size_t wrapped_size, const padding_info &padinfo, memory_buf_t &dest)
|
||||||
: padinfo_(padinfo),
|
: padinfo_(padinfo)
|
||||||
dest_(dest) {
|
, dest_(dest) {
|
||||||
remaining_pad_ = static_cast<long>(padinfo.width_) - static_cast<long>(wrapped_size);
|
remaining_pad_ = static_cast<long>(padinfo.width_) - static_cast<long>(wrapped_size);
|
||||||
if (remaining_pad_ <= 0) {
|
if (remaining_pad_ <= 0) {
|
||||||
return;
|
return;
|
||||||
@ -71,7 +71,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void pad_it(long count) {
|
void pad_it(long count) {
|
||||||
fmt_helper::append_string_view(string_view_t(spaces_.data(), static_cast<size_t>(count)), dest_);
|
fmt_helper::append_string_view(string_view_t(spaces_.data(), static_cast<size_t>(count)),
|
||||||
|
dest_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const padding_info &padinfo_;
|
const padding_info &padinfo_;
|
||||||
@ -81,7 +82,9 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct null_scoped_padder {
|
struct null_scoped_padder {
|
||||||
null_scoped_padder(size_t /*wrapped_size*/, const padding_info & /*padinfo*/, memory_buf_t & /*dest*/) {}
|
null_scoped_padder(size_t /*wrapped_size*/,
|
||||||
|
const padding_info & /*padinfo*/,
|
||||||
|
memory_buf_t & /*dest*/) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static unsigned int count_digits(T /* number */) {
|
static unsigned int count_digits(T /* number */) {
|
||||||
@ -188,8 +191,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Full month name
|
// Full month name
|
||||||
static const std::array<const char *, 12> full_months{{"January", "February", "March", "April", "May", "June", "July",
|
static const std::array<const char *, 12> full_months{{"January", "February", "March", "April",
|
||||||
"August", "September", "October", "November", "December"}};
|
"May", "June", "July", "August", "September",
|
||||||
|
"October", "November", "December"}};
|
||||||
|
|
||||||
template <typename ScopedPadder>
|
template <typename ScopedPadder>
|
||||||
class B_formatter final : public flag_formatter {
|
class B_formatter final : public flag_formatter {
|
||||||
@ -586,7 +590,9 @@ public:
|
|||||||
explicit ch_formatter(char ch)
|
explicit ch_formatter(char ch)
|
||||||
: ch_(ch) {}
|
: ch_(ch) {}
|
||||||
|
|
||||||
void format(const details::log_msg &, const std::tm &, memory_buf_t &dest) override { dest.push_back(ch_); }
|
void format(const details::log_msg &, const std::tm &, memory_buf_t &dest) override {
|
||||||
|
dest.push_back(ch_);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char ch_;
|
char ch_;
|
||||||
@ -643,8 +649,8 @@ public:
|
|||||||
size_t text_size;
|
size_t text_size;
|
||||||
if (padinfo_.enabled()) {
|
if (padinfo_.enabled()) {
|
||||||
// calc text size for padding based on "filename:line"
|
// calc text size for padding based on "filename:line"
|
||||||
text_size =
|
text_size = std::char_traits<char>::length(msg.source.filename) +
|
||||||
std::char_traits<char>::length(msg.source.filename) + ScopedPadder::count_digits(msg.source.line) + 1;
|
ScopedPadder::count_digits(msg.source.line) + 1;
|
||||||
} else {
|
} else {
|
||||||
text_size = 0;
|
text_size = 0;
|
||||||
}
|
}
|
||||||
@ -668,7 +674,8 @@ public:
|
|||||||
ScopedPadder p(0, padinfo_, dest);
|
ScopedPadder p(0, padinfo_, dest);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t text_size = padinfo_.enabled() ? std::char_traits<char>::length(msg.source.filename) : 0;
|
size_t text_size =
|
||||||
|
padinfo_.enabled() ? std::char_traits<char>::length(msg.source.filename) : 0;
|
||||||
ScopedPadder p(text_size, padinfo_, dest);
|
ScopedPadder p(text_size, padinfo_, dest);
|
||||||
fmt_helper::append_string_view(msg.source.filename, dest);
|
fmt_helper::append_string_view(msg.source.filename, dest);
|
||||||
}
|
}
|
||||||
@ -694,7 +701,8 @@ public:
|
|||||||
const std::reverse_iterator<const char *> begin(filename + std::strlen(filename));
|
const std::reverse_iterator<const char *> begin(filename + std::strlen(filename));
|
||||||
const std::reverse_iterator<const char *> end(filename);
|
const std::reverse_iterator<const char *> end(filename);
|
||||||
|
|
||||||
const auto it = std::find_first_of(begin, end, std::begin(os::folder_seps), std::end(os::folder_seps) - 1);
|
const auto it = std::find_first_of(begin, end, std::begin(os::folder_seps),
|
||||||
|
std::end(os::folder_seps) - 1);
|
||||||
return it != end ? it.base() : filename;
|
return it != end ? it.base() : filename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -744,7 +752,8 @@ public:
|
|||||||
ScopedPadder p(0, padinfo_, dest);
|
ScopedPadder p(0, padinfo_, dest);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t text_size = padinfo_.enabled() ? std::char_traits<char>::length(msg.source.funcname) : 0;
|
size_t text_size =
|
||||||
|
padinfo_.enabled() ? std::char_traits<char>::length(msg.source.funcname) : 0;
|
||||||
ScopedPadder p(text_size, padinfo_, dest);
|
ScopedPadder p(text_size, padinfo_, dest);
|
||||||
fmt_helper::append_string_view(msg.source.funcname, dest);
|
fmt_helper::append_string_view(msg.source.funcname, dest);
|
||||||
}
|
}
|
||||||
@ -757,8 +766,8 @@ public:
|
|||||||
using DurationUnits = Units;
|
using DurationUnits = Units;
|
||||||
|
|
||||||
explicit elapsed_formatter(padding_info padinfo)
|
explicit elapsed_formatter(padding_info padinfo)
|
||||||
: flag_formatter(padinfo),
|
: flag_formatter(padinfo)
|
||||||
last_message_time_(log_clock::now()) {}
|
, last_message_time_(log_clock::now()) {}
|
||||||
|
|
||||||
void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override {
|
void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override {
|
||||||
auto delta = (std::max)(msg.time - last_message_time_, log_clock::duration::zero());
|
auto delta = (std::max)(msg.time - last_message_time_, log_clock::duration::zero());
|
||||||
@ -841,7 +850,8 @@ public:
|
|||||||
if (!msg.source.empty()) {
|
if (!msg.source.empty()) {
|
||||||
dest.push_back('[');
|
dest.push_back('[');
|
||||||
const char *filename =
|
const char *filename =
|
||||||
details::short_filename_formatter<details::null_scoped_padder>::basename(msg.source.filename);
|
details::short_filename_formatter<details::null_scoped_padder>::basename(
|
||||||
|
msg.source.filename);
|
||||||
fmt_helper::append_string_view(filename, dest);
|
fmt_helper::append_string_view(filename, dest);
|
||||||
dest.push_back(':');
|
dest.push_back(':');
|
||||||
fmt_helper::append_int(msg.source.line, dest);
|
fmt_helper::append_int(msg.source.line, dest);
|
||||||
@ -863,23 +873,23 @@ SPDLOG_INLINE pattern_formatter::pattern_formatter(std::string pattern,
|
|||||||
pattern_time_type time_type,
|
pattern_time_type time_type,
|
||||||
std::string eol,
|
std::string eol,
|
||||||
custom_flags custom_user_flags)
|
custom_flags custom_user_flags)
|
||||||
: pattern_(std::move(pattern)),
|
: pattern_(std::move(pattern))
|
||||||
eol_(std::move(eol)),
|
, eol_(std::move(eol))
|
||||||
pattern_time_type_(time_type),
|
, pattern_time_type_(time_type)
|
||||||
need_localtime_(false),
|
, need_localtime_(false)
|
||||||
last_log_secs_(0),
|
, last_log_secs_(0)
|
||||||
custom_handlers_(std::move(custom_user_flags)) {
|
, custom_handlers_(std::move(custom_user_flags)) {
|
||||||
std::memset(&cached_tm_, 0, sizeof(cached_tm_));
|
std::memset(&cached_tm_, 0, sizeof(cached_tm_));
|
||||||
compile_pattern_(pattern_);
|
compile_pattern_(pattern_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// use by default full formatter for if pattern is not given
|
// use by default full formatter for if pattern is not given
|
||||||
SPDLOG_INLINE pattern_formatter::pattern_formatter(pattern_time_type time_type, std::string eol)
|
SPDLOG_INLINE pattern_formatter::pattern_formatter(pattern_time_type time_type, std::string eol)
|
||||||
: pattern_("%+"),
|
: pattern_("%+")
|
||||||
eol_(std::move(eol)),
|
, eol_(std::move(eol))
|
||||||
pattern_time_type_(time_type),
|
, pattern_time_type_(time_type)
|
||||||
need_localtime_(true),
|
, need_localtime_(true)
|
||||||
last_log_secs_(0) {
|
, last_log_secs_(0) {
|
||||||
std::memset(&cached_tm_, 0, sizeof(cached_tm_));
|
std::memset(&cached_tm_, 0, sizeof(cached_tm_));
|
||||||
formatters_.push_back(details::make_unique<details::full_formatter>(details::padding_info{}));
|
formatters_.push_back(details::make_unique<details::full_formatter>(details::padding_info{}));
|
||||||
}
|
}
|
||||||
@ -901,7 +911,8 @@ SPDLOG_INLINE std::unique_ptr<formatter> pattern_formatter::clone() const {
|
|||||||
|
|
||||||
SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory_buf_t &dest) {
|
SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory_buf_t &dest) {
|
||||||
if (need_localtime_) {
|
if (need_localtime_) {
|
||||||
const auto secs = std::chrono::duration_cast<std::chrono::seconds>(msg.time.time_since_epoch());
|
const auto secs =
|
||||||
|
std::chrono::duration_cast<std::chrono::seconds>(msg.time.time_since_epoch());
|
||||||
if (secs != last_log_secs_) {
|
if (secs != last_log_secs_) {
|
||||||
cached_tm_ = get_time_(msg);
|
cached_tm_ = get_time_(msg);
|
||||||
last_log_secs_ = secs;
|
last_log_secs_ = secs;
|
||||||
@ -957,7 +968,8 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'L': // short level
|
case 'L': // short level
|
||||||
formatters_.push_back(details::make_unique<details::short_level_formatter<Padder>>(padding));
|
formatters_.push_back(
|
||||||
|
details::make_unique<details::short_level_formatter<Padder>>(padding));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ('t'): // thread id
|
case ('t'): // thread id
|
||||||
@ -1095,23 +1107,28 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ('@'): // source location (filename:filenumber)
|
case ('@'): // source location (filename:filenumber)
|
||||||
formatters_.push_back(details::make_unique<details::source_location_formatter<Padder>>(padding));
|
formatters_.push_back(
|
||||||
|
details::make_unique<details::source_location_formatter<Padder>>(padding));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ('s'): // short source filename - without directory name
|
case ('s'): // short source filename - without directory name
|
||||||
formatters_.push_back(details::make_unique<details::short_filename_formatter<Padder>>(padding));
|
formatters_.push_back(
|
||||||
|
details::make_unique<details::short_filename_formatter<Padder>>(padding));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ('g'): // full source filename
|
case ('g'): // full source filename
|
||||||
formatters_.push_back(details::make_unique<details::source_filename_formatter<Padder>>(padding));
|
formatters_.push_back(
|
||||||
|
details::make_unique<details::source_filename_formatter<Padder>>(padding));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ('#'): // source line number
|
case ('#'): // source line number
|
||||||
formatters_.push_back(details::make_unique<details::source_linenum_formatter<Padder>>(padding));
|
formatters_.push_back(
|
||||||
|
details::make_unique<details::source_linenum_formatter<Padder>>(padding));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ('!'): // source funcname
|
case ('!'): // source funcname
|
||||||
formatters_.push_back(details::make_unique<details::source_funcname_formatter<Padder>>(padding));
|
formatters_.push_back(
|
||||||
|
details::make_unique<details::source_funcname_formatter<Padder>>(padding));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ('%'): // % char
|
case ('%'): // % char
|
||||||
@ -1120,21 +1137,26 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i
|
|||||||
|
|
||||||
case ('u'): // elapsed time since last log message in nanos
|
case ('u'): // elapsed time since last log message in nanos
|
||||||
formatters_.push_back(
|
formatters_.push_back(
|
||||||
details::make_unique<details::elapsed_formatter<Padder, std::chrono::nanoseconds>>(padding));
|
details::make_unique<details::elapsed_formatter<Padder, std::chrono::nanoseconds>>(
|
||||||
|
padding));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ('i'): // elapsed time since last log message in micros
|
case ('i'): // elapsed time since last log message in micros
|
||||||
formatters_.push_back(
|
formatters_.push_back(
|
||||||
details::make_unique<details::elapsed_formatter<Padder, std::chrono::microseconds>>(padding));
|
details::make_unique<details::elapsed_formatter<Padder, std::chrono::microseconds>>(
|
||||||
|
padding));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ('o'): // elapsed time since last log message in millis
|
case ('o'): // elapsed time since last log message in millis
|
||||||
formatters_.push_back(
|
formatters_.push_back(
|
||||||
details::make_unique<details::elapsed_formatter<Padder, std::chrono::milliseconds>>(padding));
|
details::make_unique<details::elapsed_formatter<Padder, std::chrono::milliseconds>>(
|
||||||
|
padding));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ('O'): // elapsed time since last log message in seconds
|
case ('O'): // elapsed time since last log message in seconds
|
||||||
formatters_.push_back(details::make_unique<details::elapsed_formatter<Padder, std::chrono::seconds>>(padding));
|
formatters_.push_back(
|
||||||
|
details::make_unique<details::elapsed_formatter<Padder, std::chrono::seconds>>(
|
||||||
|
padding));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // Unknown flag appears as is
|
default: // Unknown flag appears as is
|
||||||
@ -1145,12 +1167,13 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i
|
|||||||
unknown_flag->add_ch(flag);
|
unknown_flag->add_ch(flag);
|
||||||
formatters_.push_back((std::move(unknown_flag)));
|
formatters_.push_back((std::move(unknown_flag)));
|
||||||
}
|
}
|
||||||
// fix issue #1617 (prev char was '!' and should have been treated as funcname flag instead of truncating flag)
|
// fix issue #1617 (prev char was '!' and should have been treated as funcname flag instead
|
||||||
// spdlog::set_pattern("[%10!] %v") => "[ main] some message"
|
// of truncating flag) spdlog::set_pattern("[%10!] %v") => "[ main] some message"
|
||||||
// spdlog::set_pattern("[%3!!] %v") => "[mai] some message"
|
// spdlog::set_pattern("[%3!!] %v") => "[mai] some message"
|
||||||
else {
|
else {
|
||||||
padding.truncate_ = false;
|
padding.truncate_ = false;
|
||||||
formatters_.push_back(details::make_unique<details::source_funcname_formatter<Padder>>(padding));
|
formatters_.push_back(
|
||||||
|
details::make_unique<details::source_funcname_formatter<Padder>>(padding));
|
||||||
unknown_flag->add_ch(flag);
|
unknown_flag->add_ch(flag);
|
||||||
formatters_.push_back((std::move(unknown_flag)));
|
formatters_.push_back((std::move(unknown_flag)));
|
||||||
}
|
}
|
||||||
@ -1162,8 +1185,9 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i
|
|||||||
// Extract given pad spec (e.g. %8X, %=8X, %-8!X, %8!X, %=8!X, %-8!X, %+8!X)
|
// Extract given pad spec (e.g. %8X, %=8X, %-8!X, %8!X, %=8!X, %-8!X, %+8!X)
|
||||||
// Advance the given it pass the end of the padding spec found (if any)
|
// Advance the given it pass the end of the padding spec found (if any)
|
||||||
// Return padding.
|
// Return padding.
|
||||||
SPDLOG_INLINE details::padding_info pattern_formatter::handle_padspec_(std::string::const_iterator &it,
|
SPDLOG_INLINE details::padding_info
|
||||||
std::string::const_iterator end) {
|
pattern_formatter::handle_padspec_(std::string::const_iterator &it,
|
||||||
|
std::string::const_iterator end) {
|
||||||
using details::padding_info;
|
using details::padding_info;
|
||||||
using details::scoped_padder;
|
using details::scoped_padder;
|
||||||
const size_t max_width = 64;
|
const size_t max_width = 64;
|
||||||
|
@ -25,10 +25,10 @@ struct padding_info {
|
|||||||
|
|
||||||
padding_info() = default;
|
padding_info() = default;
|
||||||
padding_info(size_t width, padding_info::pad_side side, bool truncate)
|
padding_info(size_t width, padding_info::pad_side side, bool truncate)
|
||||||
: width_(width),
|
: width_(width)
|
||||||
side_(side),
|
, side_(side)
|
||||||
truncate_(truncate),
|
, truncate_(truncate)
|
||||||
enabled_(true) {}
|
, enabled_(true) {}
|
||||||
|
|
||||||
bool enabled() const { return enabled_; }
|
bool enabled() const { return enabled_; }
|
||||||
size_t width_ = 0;
|
size_t width_ = 0;
|
||||||
@ -43,7 +43,8 @@ public:
|
|||||||
: padinfo_(padinfo) {}
|
: padinfo_(padinfo) {}
|
||||||
flag_formatter() = default;
|
flag_formatter() = default;
|
||||||
virtual ~flag_formatter() = default;
|
virtual ~flag_formatter() = default;
|
||||||
virtual void format(const details::log_msg &msg, const std::tm &tm_time, memory_buf_t &dest) = 0;
|
virtual void
|
||||||
|
format(const details::log_msg &msg, const std::tm &tm_time, memory_buf_t &dest) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
padding_info padinfo_;
|
padding_info padinfo_;
|
||||||
@ -55,7 +56,9 @@ class SPDLOG_API custom_flag_formatter : public details::flag_formatter {
|
|||||||
public:
|
public:
|
||||||
virtual std::unique_ptr<custom_flag_formatter> clone() const = 0;
|
virtual std::unique_ptr<custom_flag_formatter> clone() const = 0;
|
||||||
|
|
||||||
void set_padding_info(const details::padding_info &padding) { flag_formatter::padinfo_ = padding; }
|
void set_padding_info(const details::padding_info &padding) {
|
||||||
|
flag_formatter::padinfo_ = padding;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SPDLOG_API pattern_formatter final : public formatter {
|
class SPDLOG_API pattern_formatter final : public formatter {
|
||||||
@ -102,7 +105,8 @@ private:
|
|||||||
// Extract given pad spec (e.g. %8X)
|
// Extract given pad spec (e.g. %8X)
|
||||||
// Advance the given it pass the end of the padding spec found (if any)
|
// Advance the given it pass the end of the padding spec found (if any)
|
||||||
// Return padding.
|
// Return padding.
|
||||||
static details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end);
|
static details::padding_info handle_padspec_(std::string::const_iterator &it,
|
||||||
|
std::string::const_iterator end);
|
||||||
|
|
||||||
void compile_pattern_(const std::string &pattern);
|
void compile_pattern_(const std::string &pattern);
|
||||||
};
|
};
|
||||||
|
@ -27,14 +27,15 @@ namespace sinks {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Android sink
|
* Android sink
|
||||||
* (logging using __android_log_write or __android_log_buf_write depending on the specified BufferID)
|
* (logging using __android_log_write or __android_log_buf_write depending on the specified
|
||||||
|
* BufferID)
|
||||||
*/
|
*/
|
||||||
template <typename Mutex, int BufferID = log_id::LOG_ID_MAIN>
|
template <typename Mutex, int BufferID = log_id::LOG_ID_MAIN>
|
||||||
class android_sink final : public base_sink<Mutex> {
|
class android_sink final : public base_sink<Mutex> {
|
||||||
public:
|
public:
|
||||||
explicit android_sink(std::string tag = "spdlog", bool use_raw_msg = false)
|
explicit android_sink(std::string tag = "spdlog", bool use_raw_msg = false)
|
||||||
: tag_(std::move(tag)),
|
: tag_(std::move(tag))
|
||||||
use_raw_msg_(use_raw_msg) {}
|
, use_raw_msg_(use_raw_msg) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void sink_it_(const details::log_msg &msg) override {
|
void sink_it_(const details::log_msg &msg) override {
|
||||||
@ -68,10 +69,10 @@ protected:
|
|||||||
void flush_() override {}
|
void flush_() override {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// There might be liblog versions used, that do not support __android_log_buf_write. So we only compile and link
|
// There might be liblog versions used, that do not support __android_log_buf_write. So we only
|
||||||
// against
|
// compile and link against
|
||||||
// __android_log_buf_write, if user explicitly provides a non-default log buffer. Otherwise, when using the default
|
// __android_log_buf_write, if user explicitly provides a non-default log buffer. Otherwise,
|
||||||
// log buffer, always log via __android_log_write.
|
// when using the default log buffer, always log via __android_log_write.
|
||||||
template <int ID = BufferID>
|
template <int ID = BufferID>
|
||||||
typename std::enable_if<ID == static_cast<int>(log_id::LOG_ID_MAIN), int>::type
|
typename std::enable_if<ID == static_cast<int>(log_id::LOG_ID_MAIN), int>::type
|
||||||
android_log(int prio, const char *tag, const char *text) {
|
android_log(int prio, const char *tag, const char *text) {
|
||||||
@ -120,12 +121,14 @@ using android_sink_buf_st = android_sink<details::null_mutex, BufferId>;
|
|||||||
// Create and register android syslog logger
|
// Create and register android syslog logger
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> android_logger_mt(const std::string &logger_name, const std::string &tag = "spdlog") {
|
inline std::shared_ptr<logger> android_logger_mt(const std::string &logger_name,
|
||||||
|
const std::string &tag = "spdlog") {
|
||||||
return Factory::template create<sinks::android_sink_mt>(logger_name, tag);
|
return Factory::template create<sinks::android_sink_mt>(logger_name, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> android_logger_st(const std::string &logger_name, const std::string &tag = "spdlog") {
|
inline std::shared_ptr<logger> android_logger_st(const std::string &logger_name,
|
||||||
|
const std::string &tag = "spdlog") {
|
||||||
return Factory::template create<sinks::android_sink_st>(logger_name, tag);
|
return Factory::template create<sinks::android_sink_st>(logger_name, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@ namespace sinks {
|
|||||||
|
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
SPDLOG_INLINE ansicolor_sink<ConsoleMutex>::ansicolor_sink(FILE *target_file, color_mode mode)
|
SPDLOG_INLINE ansicolor_sink<ConsoleMutex>::ansicolor_sink(FILE *target_file, color_mode mode)
|
||||||
: target_file_(target_file),
|
: target_file_(target_file)
|
||||||
mutex_(ConsoleMutex::mutex()),
|
, mutex_(ConsoleMutex::mutex())
|
||||||
formatter_(details::make_unique<spdlog::pattern_formatter>())
|
, formatter_(details::make_unique<spdlog::pattern_formatter>())
|
||||||
|
|
||||||
{
|
{
|
||||||
set_color_mode(mode);
|
set_color_mode(mode);
|
||||||
@ -31,7 +31,8 @@ SPDLOG_INLINE ansicolor_sink<ConsoleMutex>::ansicolor_sink(FILE *target_file, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_color(level::level_enum color_level, string_view_t color) {
|
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_color(level::level_enum color_level,
|
||||||
|
string_view_t color) {
|
||||||
std::lock_guard<mutex_t> lock(mutex_);
|
std::lock_guard<mutex_t> lock(mutex_);
|
||||||
colors_.at(static_cast<size_t>(color_level)) = to_string_(color);
|
colors_.at(static_cast<size_t>(color_level)) = to_string_(color);
|
||||||
}
|
}
|
||||||
@ -74,7 +75,8 @@ SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_pattern(const std::string &
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
SPDLOG_INLINE void
|
||||||
|
ansicolor_sink<ConsoleMutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
||||||
std::lock_guard<mutex_t> lock(mutex_);
|
std::lock_guard<mutex_t> lock(mutex_);
|
||||||
formatter_ = std::move(sink_formatter);
|
formatter_ = std::move(sink_formatter);
|
||||||
}
|
}
|
||||||
@ -91,7 +93,8 @@ SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_color_mode(color_mode mode)
|
|||||||
should_do_colors_ = true;
|
should_do_colors_ = true;
|
||||||
return;
|
return;
|
||||||
case color_mode::automatic:
|
case color_mode::automatic:
|
||||||
should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal();
|
should_do_colors_ =
|
||||||
|
details::os::in_terminal(target_file_) && details::os::is_color_terminal();
|
||||||
return;
|
return;
|
||||||
case color_mode::never:
|
case color_mode::never:
|
||||||
should_do_colors_ = false;
|
should_do_colors_ = false;
|
||||||
@ -107,7 +110,9 @@ SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::print_ccode_(const string_view_
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::print_range_(const memory_buf_t &formatted, size_t start, size_t end) {
|
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::print_range_(const memory_buf_t &formatted,
|
||||||
|
size_t start,
|
||||||
|
size_t end) {
|
||||||
fwrite(formatted.data() + start, sizeof(char), end - start, target_file_);
|
fwrite(formatted.data() + start, sizeof(char), end - start, target_file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@ SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::base_sink()
|
|||||||
: formatter_{details::make_unique<spdlog::pattern_formatter>()} {}
|
: formatter_{details::make_unique<spdlog::pattern_formatter>()} {}
|
||||||
|
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::base_sink(std::unique_ptr<spdlog::formatter> formatter)
|
SPDLOG_INLINE
|
||||||
|
spdlog::sinks::base_sink<Mutex>::base_sink(std::unique_ptr<spdlog::formatter> formatter)
|
||||||
: formatter_{std::move(formatter)} {}
|
: formatter_{std::move(formatter)} {}
|
||||||
|
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
@ -40,7 +41,8 @@ void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::set_pattern(const std::strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
void SPDLOG_INLINE
|
||||||
|
spdlog::sinks::base_sink<Mutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
||||||
std::lock_guard<Mutex> lock(mutex_);
|
std::lock_guard<Mutex> lock(mutex_);
|
||||||
set_formatter_(std::move(sink_formatter));
|
set_formatter_(std::move(sink_formatter));
|
||||||
}
|
}
|
||||||
@ -51,6 +53,7 @@ void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::set_pattern_(const std::stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::set_formatter_(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
void SPDLOG_INLINE
|
||||||
|
spdlog::sinks::base_sink<Mutex>::set_formatter_(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
||||||
formatter_ = std::move(sink_formatter);
|
formatter_ = std::move(sink_formatter);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,8 @@ inline std::shared_ptr<logger> basic_logger_mt(const std::string &logger_name,
|
|||||||
const filename_t &filename,
|
const filename_t &filename,
|
||||||
bool truncate = false,
|
bool truncate = false,
|
||||||
const file_event_handlers &event_handlers = {}) {
|
const file_event_handlers &event_handlers = {}) {
|
||||||
return Factory::template create<sinks::basic_file_sink_mt>(logger_name, filename, truncate, event_handlers);
|
return Factory::template create<sinks::basic_file_sink_mt>(logger_name, filename, truncate,
|
||||||
|
event_handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
@ -53,7 +54,8 @@ inline std::shared_ptr<logger> basic_logger_st(const std::string &logger_name,
|
|||||||
const filename_t &filename,
|
const filename_t &filename,
|
||||||
bool truncate = false,
|
bool truncate = false,
|
||||||
const file_event_handlers &event_handlers = {}) {
|
const file_event_handlers &event_handlers = {}) {
|
||||||
return Factory::template create<sinks::basic_file_sink_st>(logger_name, filename, truncate, event_handlers);
|
return Factory::template create<sinks::basic_file_sink_st>(logger_name, filename, truncate,
|
||||||
|
event_handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -42,12 +42,14 @@ using callback_sink_st = callback_sink<details::null_mutex>;
|
|||||||
// factory functions
|
// factory functions
|
||||||
//
|
//
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> callback_logger_mt(const std::string &logger_name, const custom_log_callback &callback) {
|
inline std::shared_ptr<logger> callback_logger_mt(const std::string &logger_name,
|
||||||
|
const custom_log_callback &callback) {
|
||||||
return Factory::template create<sinks::callback_sink_mt>(logger_name, callback);
|
return Factory::template create<sinks::callback_sink_mt>(logger_name, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> callback_logger_st(const std::string &logger_name, const custom_log_callback &callback) {
|
inline std::shared_ptr<logger> callback_logger_st(const std::string &logger_name,
|
||||||
|
const custom_log_callback &callback) {
|
||||||
return Factory::template create<sinks::callback_sink_st>(logger_name, callback);
|
return Factory::template create<sinks::callback_sink_st>(logger_name, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,16 +31,19 @@ struct daily_filename_calculator {
|
|||||||
static filename_t calc_filename(const filename_t &filename, const tm &now_tm) {
|
static filename_t calc_filename(const filename_t &filename, const tm &now_tm) {
|
||||||
filename_t basename, ext;
|
filename_t basename, ext;
|
||||||
std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
|
std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
|
||||||
return fmt_lib::format(SPDLOG_FMT_STRING(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}{}")), basename,
|
return fmt_lib::format(SPDLOG_FMT_STRING(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}{}")),
|
||||||
now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday, ext);
|
basename, now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday,
|
||||||
|
ext);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generator of daily log file names with strftime format.
|
* Generator of daily log file names with strftime format.
|
||||||
* Usages:
|
* Usages:
|
||||||
* auto sink = std::make_shared<spdlog::sinks::daily_file_format_sink_mt>("myapp-%Y-%m-%d:%H:%M:%S.log", hour,
|
* auto sink =
|
||||||
* minute);" auto logger = spdlog::daily_logger_format_mt("loggername, "myapp-%Y-%m-%d:%X.log", hour, minute)"
|
* std::make_shared<spdlog::sinks::daily_file_format_sink_mt>("myapp-%Y-%m-%d:%H:%M:%S.log", hour,
|
||||||
|
* minute);" auto logger = spdlog::daily_logger_format_mt("loggername, "myapp-%Y-%m-%d:%X.log",
|
||||||
|
* hour, minute)"
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct daily_filename_format_calculator {
|
struct daily_filename_format_calculator {
|
||||||
@ -70,14 +73,15 @@ public:
|
|||||||
bool truncate = false,
|
bool truncate = false,
|
||||||
uint16_t max_files = 0,
|
uint16_t max_files = 0,
|
||||||
const file_event_handlers &event_handlers = {})
|
const file_event_handlers &event_handlers = {})
|
||||||
: base_filename_(std::move(base_filename)),
|
: base_filename_(std::move(base_filename))
|
||||||
rotation_h_(rotation_hour),
|
, rotation_h_(rotation_hour)
|
||||||
rotation_m_(rotation_minute),
|
, rotation_m_(rotation_minute)
|
||||||
file_helper_{event_handlers},
|
, file_helper_{event_handlers}
|
||||||
truncate_(truncate),
|
, truncate_(truncate)
|
||||||
max_files_(max_files),
|
, max_files_(max_files)
|
||||||
filenames_q_() {
|
, filenames_q_() {
|
||||||
if (rotation_hour < 0 || rotation_hour > 23 || rotation_minute < 0 || rotation_minute > 59) {
|
if (rotation_hour < 0 || rotation_hour > 23 || rotation_minute < 0 ||
|
||||||
|
rotation_minute > 59) {
|
||||||
throw_spdlog_ex("daily_file_sink: Invalid rotation time in ctor");
|
throw_spdlog_ex("daily_file_sink: Invalid rotation time in ctor");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +172,8 @@ private:
|
|||||||
bool ok = remove_if_exists(old_filename) == 0;
|
bool ok = remove_if_exists(old_filename) == 0;
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
filenames_q_.push_back(std::move(current_file));
|
filenames_q_.push_back(std::move(current_file));
|
||||||
throw_spdlog_ex("Failed removing daily file " + filename_to_str(old_filename), errno);
|
throw_spdlog_ex("Failed removing daily file " + filename_to_str(old_filename),
|
||||||
|
errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filenames_q_.push_back(std::move(current_file));
|
filenames_q_.push_back(std::move(current_file));
|
||||||
@ -187,7 +192,8 @@ private:
|
|||||||
using daily_file_sink_mt = daily_file_sink<std::mutex>;
|
using daily_file_sink_mt = daily_file_sink<std::mutex>;
|
||||||
using daily_file_sink_st = daily_file_sink<details::null_mutex>;
|
using daily_file_sink_st = daily_file_sink<details::null_mutex>;
|
||||||
using daily_file_format_sink_mt = daily_file_sink<std::mutex, daily_filename_format_calculator>;
|
using daily_file_format_sink_mt = daily_file_sink<std::mutex, daily_filename_format_calculator>;
|
||||||
using daily_file_format_sink_st = daily_file_sink<details::null_mutex, daily_filename_format_calculator>;
|
using daily_file_format_sink_st =
|
||||||
|
daily_file_sink<details::null_mutex, daily_filename_format_calculator>;
|
||||||
|
|
||||||
} // namespace sinks
|
} // namespace sinks
|
||||||
|
|
||||||
@ -202,20 +208,21 @@ inline std::shared_ptr<logger> daily_logger_mt(const std::string &logger_name,
|
|||||||
bool truncate = false,
|
bool truncate = false,
|
||||||
uint16_t max_files = 0,
|
uint16_t max_files = 0,
|
||||||
const file_event_handlers &event_handlers = {}) {
|
const file_event_handlers &event_handlers = {}) {
|
||||||
return Factory::template create<sinks::daily_file_sink_mt>(logger_name, filename, hour, minute, truncate, max_files,
|
return Factory::template create<sinks::daily_file_sink_mt>(logger_name, filename, hour, minute,
|
||||||
event_handlers);
|
truncate, max_files, event_handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> daily_logger_format_mt(const std::string &logger_name,
|
inline std::shared_ptr<logger>
|
||||||
const filename_t &filename,
|
daily_logger_format_mt(const std::string &logger_name,
|
||||||
int hour = 0,
|
const filename_t &filename,
|
||||||
int minute = 0,
|
int hour = 0,
|
||||||
bool truncate = false,
|
int minute = 0,
|
||||||
uint16_t max_files = 0,
|
bool truncate = false,
|
||||||
const file_event_handlers &event_handlers = {}) {
|
uint16_t max_files = 0,
|
||||||
return Factory::template create<sinks::daily_file_format_sink_mt>(logger_name, filename, hour, minute, truncate,
|
const file_event_handlers &event_handlers = {}) {
|
||||||
max_files, event_handlers);
|
return Factory::template create<sinks::daily_file_format_sink_mt>(
|
||||||
|
logger_name, filename, hour, minute, truncate, max_files, event_handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
@ -226,19 +233,20 @@ inline std::shared_ptr<logger> daily_logger_st(const std::string &logger_name,
|
|||||||
bool truncate = false,
|
bool truncate = false,
|
||||||
uint16_t max_files = 0,
|
uint16_t max_files = 0,
|
||||||
const file_event_handlers &event_handlers = {}) {
|
const file_event_handlers &event_handlers = {}) {
|
||||||
return Factory::template create<sinks::daily_file_sink_st>(logger_name, filename, hour, minute, truncate, max_files,
|
return Factory::template create<sinks::daily_file_sink_st>(logger_name, filename, hour, minute,
|
||||||
event_handlers);
|
truncate, max_files, event_handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> daily_logger_format_st(const std::string &logger_name,
|
inline std::shared_ptr<logger>
|
||||||
const filename_t &filename,
|
daily_logger_format_st(const std::string &logger_name,
|
||||||
int hour = 0,
|
const filename_t &filename,
|
||||||
int minute = 0,
|
int hour = 0,
|
||||||
bool truncate = false,
|
int minute = 0,
|
||||||
uint16_t max_files = 0,
|
bool truncate = false,
|
||||||
const file_event_handlers &event_handlers = {}) {
|
uint16_t max_files = 0,
|
||||||
return Factory::template create<sinks::daily_file_format_sink_st>(logger_name, filename, hour, minute, truncate,
|
const file_event_handlers &event_handlers = {}) {
|
||||||
max_files, event_handlers);
|
return Factory::template create<sinks::daily_file_format_sink_st>(
|
||||||
|
logger_name, filename, hour, minute, truncate, max_files, event_handlers);
|
||||||
}
|
}
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
// #include <spdlog/sinks/dup_filter_sink.h>
|
// #include <spdlog/sinks/dup_filter_sink.h>
|
||||||
//
|
//
|
||||||
// int main() {
|
// int main() {
|
||||||
// auto dup_filter = std::make_shared<dup_filter_sink_st>(std::chrono::seconds(5), level::info);
|
// auto dup_filter = std::make_shared<dup_filter_sink_st>(std::chrono::seconds(5),
|
||||||
// dup_filter->add_sink(std::make_shared<stdout_color_sink_mt>());
|
// level::info); dup_filter->add_sink(std::make_shared<stdout_color_sink_mt>());
|
||||||
// spdlog::logger l("logger", dup_filter);
|
// spdlog::logger l("logger", dup_filter);
|
||||||
// l.info("Hello");
|
// l.info("Hello");
|
||||||
// l.info("Hello");
|
// l.info("Hello");
|
||||||
@ -42,8 +42,8 @@ public:
|
|||||||
template <class Rep, class Period>
|
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)
|
level::level_enum notification_level = level::info)
|
||||||
: max_skip_duration_{max_skip_duration},
|
: max_skip_duration_{max_skip_duration}
|
||||||
log_level_{notification_level} {}
|
, log_level_{notification_level} {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::chrono::microseconds max_skip_duration_;
|
std::chrono::microseconds max_skip_duration_;
|
||||||
@ -62,8 +62,8 @@ protected:
|
|||||||
// log the "skipped.." message
|
// log the "skipped.." message
|
||||||
if (skip_counter_ > 0) {
|
if (skip_counter_ > 0) {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
auto msg_size =
|
auto msg_size = ::snprintf(buf, sizeof(buf), "Skipped %u duplicate messages..",
|
||||||
::snprintf(buf, sizeof(buf), "Skipped %u duplicate messages..", static_cast<unsigned>(skip_counter_));
|
static_cast<unsigned>(skip_counter_));
|
||||||
if (msg_size > 0 && static_cast<size_t>(msg_size) < sizeof(buf)) {
|
if (msg_size > 0 && static_cast<size_t>(msg_size) < sizeof(buf)) {
|
||||||
details::log_msg skipped_msg{msg.source, msg.logger_name, log_level_,
|
details::log_msg skipped_msg{msg.source, msg.logger_name, log_level_,
|
||||||
string_view_t{buf, static_cast<size_t>(msg_size)}};
|
string_view_t{buf, static_cast<size_t>(msg_size)}};
|
||||||
|
@ -29,8 +29,9 @@ struct hourly_filename_calculator {
|
|||||||
static filename_t calc_filename(const filename_t &filename, const tm &now_tm) {
|
static filename_t calc_filename(const filename_t &filename, const tm &now_tm) {
|
||||||
filename_t basename, ext;
|
filename_t basename, ext;
|
||||||
std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
|
std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
|
||||||
return fmt_lib::format(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}_{:02d}{}"), basename, now_tm.tm_year + 1900,
|
return fmt_lib::format(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}_{:02d}{}"), basename,
|
||||||
now_tm.tm_mon + 1, now_tm.tm_mday, now_tm.tm_hour, ext);
|
now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday,
|
||||||
|
now_tm.tm_hour, ext);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,11 +48,11 @@ public:
|
|||||||
bool truncate = false,
|
bool truncate = false,
|
||||||
uint16_t max_files = 0,
|
uint16_t max_files = 0,
|
||||||
const file_event_handlers &event_handlers = {})
|
const file_event_handlers &event_handlers = {})
|
||||||
: base_filename_(std::move(base_filename)),
|
: base_filename_(std::move(base_filename))
|
||||||
file_helper_{event_handlers},
|
, file_helper_{event_handlers}
|
||||||
truncate_(truncate),
|
, truncate_(truncate)
|
||||||
max_files_(max_files),
|
, max_files_(max_files)
|
||||||
filenames_q_() {
|
, filenames_q_() {
|
||||||
auto now = log_clock::now();
|
auto now = log_clock::now();
|
||||||
auto filename = FileNameCalc::calc_filename(base_filename_, now_tm(now));
|
auto filename = FileNameCalc::calc_filename(base_filename_, now_tm(now));
|
||||||
file_helper_.open(filename, truncate_);
|
file_helper_.open(filename, truncate_);
|
||||||
@ -144,7 +145,8 @@ private:
|
|||||||
bool ok = remove_if_exists(old_filename) == 0;
|
bool ok = remove_if_exists(old_filename) == 0;
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
filenames_q_.push_back(std::move(current_file));
|
filenames_q_.push_back(std::move(current_file));
|
||||||
SPDLOG_THROW(spdlog_ex("Failed removing hourly file " + filename_to_str(old_filename), errno));
|
SPDLOG_THROW(spdlog_ex(
|
||||||
|
"Failed removing hourly file " + filename_to_str(old_filename), errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filenames_q_.push_back(std::move(current_file));
|
filenames_q_.push_back(std::move(current_file));
|
||||||
@ -173,8 +175,8 @@ inline std::shared_ptr<logger> hourly_logger_mt(const std::string &logger_name,
|
|||||||
bool truncate = false,
|
bool truncate = false,
|
||||||
uint16_t max_files = 0,
|
uint16_t max_files = 0,
|
||||||
const file_event_handlers &event_handlers = {}) {
|
const file_event_handlers &event_handlers = {}) {
|
||||||
return Factory::template create<sinks::hourly_file_sink_mt>(logger_name, filename, truncate, max_files,
|
return Factory::template create<sinks::hourly_file_sink_mt>(logger_name, filename, truncate,
|
||||||
event_handlers);
|
max_files, event_handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
@ -183,7 +185,7 @@ inline std::shared_ptr<logger> hourly_logger_st(const std::string &logger_name,
|
|||||||
bool truncate = false,
|
bool truncate = false,
|
||||||
uint16_t max_files = 0,
|
uint16_t max_files = 0,
|
||||||
const file_event_handlers &event_handlers = {}) {
|
const file_event_handlers &event_handlers = {}) {
|
||||||
return Factory::template create<sinks::hourly_file_sink_st>(logger_name, filename, truncate, max_files,
|
return Factory::template create<sinks::hourly_file_sink_st>(logger_name, filename, truncate,
|
||||||
event_handlers);
|
max_files, event_handlers);
|
||||||
}
|
}
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -30,9 +30,9 @@ struct kafka_sink_config {
|
|||||||
int32_t flush_timeout_ms = 1000;
|
int32_t flush_timeout_ms = 1000;
|
||||||
|
|
||||||
kafka_sink_config(std::string addr, std::string topic, int flush_timeout_ms = 1000)
|
kafka_sink_config(std::string addr, std::string topic, int flush_timeout_ms = 1000)
|
||||||
: server_addr{std::move(addr)},
|
: server_addr{std::move(addr)}
|
||||||
produce_topic{std::move(topic)},
|
, produce_topic{std::move(topic)}
|
||||||
flush_timeout_ms(flush_timeout_ms) {}
|
, flush_timeout_ms(flush_timeout_ms) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
@ -43,9 +43,11 @@ public:
|
|||||||
try {
|
try {
|
||||||
std::string errstr;
|
std::string errstr;
|
||||||
conf_.reset(RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL));
|
conf_.reset(RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL));
|
||||||
RdKafka::Conf::ConfResult confRes = conf_->set("bootstrap.servers", config_.server_addr, errstr);
|
RdKafka::Conf::ConfResult confRes =
|
||||||
|
conf_->set("bootstrap.servers", config_.server_addr, errstr);
|
||||||
if (confRes != RdKafka::Conf::CONF_OK) {
|
if (confRes != RdKafka::Conf::CONF_OK) {
|
||||||
throw_spdlog_ex(fmt_lib::format("conf set bootstrap.servers failed err:{}", errstr));
|
throw_spdlog_ex(
|
||||||
|
fmt_lib::format("conf set bootstrap.servers failed err:{}", errstr));
|
||||||
}
|
}
|
||||||
|
|
||||||
tconf_.reset(RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC));
|
tconf_.reset(RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC));
|
||||||
@ -57,7 +59,8 @@ public:
|
|||||||
if (producer_ == nullptr) {
|
if (producer_ == nullptr) {
|
||||||
throw_spdlog_ex(fmt_lib::format("create producer failed err:{}", errstr));
|
throw_spdlog_ex(fmt_lib::format("create producer failed err:{}", errstr));
|
||||||
}
|
}
|
||||||
topic_.reset(RdKafka::Topic::create(producer_.get(), config_.produce_topic, tconf_.get(), errstr));
|
topic_.reset(RdKafka::Topic::create(producer_.get(), config_.produce_topic,
|
||||||
|
tconf_.get(), errstr));
|
||||||
if (topic_ == nullptr) {
|
if (topic_ == nullptr) {
|
||||||
throw_spdlog_ex(fmt_lib::format("create topic failed err:{}", errstr));
|
throw_spdlog_ex(fmt_lib::format("create topic failed err:{}", errstr));
|
||||||
}
|
}
|
||||||
@ -70,8 +73,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void sink_it_(const details::log_msg &msg) override {
|
void sink_it_(const details::log_msg &msg) override {
|
||||||
producer_->produce(topic_.get(), 0, RdKafka::Producer::RK_MSG_COPY, (void *)msg.payload.data(),
|
producer_->produce(topic_.get(), 0, RdKafka::Producer::RK_MSG_COPY,
|
||||||
msg.payload.size(), NULL, NULL);
|
(void *)msg.payload.data(), msg.payload.size(), NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_() override { producer_->flush(config_.flush_timeout_ms); }
|
void flush_() override { producer_->flush(config_.flush_timeout_ms); }
|
||||||
@ -102,14 +105,14 @@ inline std::shared_ptr<logger> kafka_logger_st(const std::string &logger_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::async_factory>
|
template <typename Factory = spdlog::async_factory>
|
||||||
inline std::shared_ptr<spdlog::logger> kafka_logger_async_mt(std::string logger_name,
|
inline std::shared_ptr<spdlog::logger>
|
||||||
spdlog::sinks::kafka_sink_config config) {
|
kafka_logger_async_mt(std::string logger_name, spdlog::sinks::kafka_sink_config config) {
|
||||||
return Factory::template create<sinks::kafka_sink_mt>(logger_name, config);
|
return Factory::template create<sinks::kafka_sink_mt>(logger_name, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::async_factory>
|
template <typename Factory = spdlog::async_factory>
|
||||||
inline std::shared_ptr<spdlog::logger> kafka_logger_async_st(std::string logger_name,
|
inline std::shared_ptr<spdlog::logger>
|
||||||
spdlog::sinks::kafka_sink_config config) {
|
kafka_logger_async_st(std::string logger_name, spdlog::sinks::kafka_sink_config config) {
|
||||||
return Factory::template create<sinks::kafka_sink_st>(logger_name, config);
|
return Factory::template create<sinks::kafka_sink_st>(logger_name, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,9 +40,9 @@ public:
|
|||||||
const std::string &db_name,
|
const std::string &db_name,
|
||||||
const std::string &collection_name,
|
const std::string &collection_name,
|
||||||
const std::string &uri = "mongodb://localhost:27017")
|
const std::string &uri = "mongodb://localhost:27017")
|
||||||
: instance_(std::move(instance)),
|
: instance_(std::move(instance))
|
||||||
db_name_(db_name),
|
, db_name_(db_name)
|
||||||
coll_name_(collection_name) {
|
, coll_name_(collection_name) {
|
||||||
try {
|
try {
|
||||||
client_ = spdlog::details::make_unique<mongocxx::client>(mongocxx::uri{uri});
|
client_ = spdlog::details::make_unique<mongocxx::client>(mongocxx::uri{uri});
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
@ -59,10 +59,12 @@ protected:
|
|||||||
|
|
||||||
if (client_ != nullptr) {
|
if (client_ != nullptr) {
|
||||||
auto doc = document{} << "timestamp" << bsoncxx::types::b_date(msg.time) << "level"
|
auto doc = document{} << "timestamp" << bsoncxx::types::b_date(msg.time) << "level"
|
||||||
<< level::to_string_view(msg.level).data() << "level_num" << msg.level << "message"
|
<< level::to_string_view(msg.level).data() << "level_num"
|
||||||
<< std::string(msg.payload.begin(), msg.payload.end()) << "logger_name"
|
<< msg.level << "message"
|
||||||
<< std::string(msg.logger_name.begin(), msg.logger_name.end()) << "thread_id"
|
<< std::string(msg.payload.begin(), msg.payload.end())
|
||||||
<< static_cast<int>(msg.thread_id) << finalize;
|
<< "logger_name"
|
||||||
|
<< std::string(msg.logger_name.begin(), msg.logger_name.end())
|
||||||
|
<< "thread_id" << static_cast<int>(msg.thread_id) << finalize;
|
||||||
client_->database(db_name_).collection(coll_name_).insert_one(doc.view());
|
client_->database(db_name_).collection(coll_name_).insert_one(doc.view());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,19 +86,23 @@ using mongo_sink_st = mongo_sink<spdlog::details::null_mutex>;
|
|||||||
} // namespace sinks
|
} // namespace sinks
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> mongo_logger_mt(const std::string &logger_name,
|
inline std::shared_ptr<logger>
|
||||||
const std::string &db_name,
|
mongo_logger_mt(const std::string &logger_name,
|
||||||
const std::string &collection_name,
|
const std::string &db_name,
|
||||||
const std::string &uri = "mongodb://localhost:27017") {
|
const std::string &collection_name,
|
||||||
return Factory::template create<sinks::mongo_sink_mt>(logger_name, db_name, collection_name, uri);
|
const std::string &uri = "mongodb://localhost:27017") {
|
||||||
|
return Factory::template create<sinks::mongo_sink_mt>(logger_name, db_name, collection_name,
|
||||||
|
uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> mongo_logger_st(const std::string &logger_name,
|
inline std::shared_ptr<logger>
|
||||||
const std::string &db_name,
|
mongo_logger_st(const std::string &logger_name,
|
||||||
const std::string &collection_name,
|
const std::string &db_name,
|
||||||
const std::string &uri = "mongodb://localhost:27017") {
|
const std::string &collection_name,
|
||||||
return Factory::template create<sinks::mongo_sink_st>(logger_name, db_name, collection_name, uri);
|
const std::string &uri = "mongodb://localhost:27017") {
|
||||||
|
return Factory::template create<sinks::mongo_sink_st>(logger_name, db_name, collection_name,
|
||||||
|
uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -15,8 +15,8 @@ template <typename Mutex>
|
|||||||
class ostream_sink final : public base_sink<Mutex> {
|
class ostream_sink final : public base_sink<Mutex> {
|
||||||
public:
|
public:
|
||||||
explicit ostream_sink(std::ostream &os, bool force_flush = false)
|
explicit ostream_sink(std::ostream &os, bool force_flush = false)
|
||||||
: ostream_(os),
|
: ostream_(os)
|
||||||
force_flush_(force_flush) {}
|
, force_flush_(force_flush) {}
|
||||||
ostream_sink(const ostream_sink &) = delete;
|
ostream_sink(const ostream_sink &) = delete;
|
||||||
ostream_sink &operator=(const ostream_sink &) = delete;
|
ostream_sink &operator=(const ostream_sink &) = delete;
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
// etc) Building and using requires Qt library.
|
// etc) Building and using requires Qt library.
|
||||||
//
|
//
|
||||||
// Warning: the qt_sink won't be notified if the target widget is destroyed.
|
// Warning: the qt_sink won't be notified if the target widget is destroyed.
|
||||||
// If the widget's lifetime can be shorter than the logger's one, you should provide some permanent QObject,
|
// If the widget's lifetime can be shorter than the logger's one, you should provide some permanent
|
||||||
// and then use a standard signal/slot.
|
// QObject, and then use a standard signal/slot.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "spdlog/common.h"
|
#include "spdlog/common.h"
|
||||||
@ -30,8 +30,8 @@ template <typename Mutex>
|
|||||||
class qt_sink : public base_sink<Mutex> {
|
class qt_sink : public base_sink<Mutex> {
|
||||||
public:
|
public:
|
||||||
qt_sink(QObject *qt_object, std::string meta_method)
|
qt_sink(QObject *qt_object, std::string meta_method)
|
||||||
: qt_object_(qt_object),
|
: qt_object_(qt_object)
|
||||||
meta_method_(std::move(meta_method)) {
|
, meta_method_(std::move(meta_method)) {
|
||||||
if (!qt_object_) {
|
if (!qt_object_) {
|
||||||
throw_spdlog_ex("qt_sink: qt_object is null");
|
throw_spdlog_ex("qt_sink: qt_object is null");
|
||||||
}
|
}
|
||||||
@ -59,15 +59,19 @@ private:
|
|||||||
// QT color sink to QTextEdit.
|
// QT color sink to QTextEdit.
|
||||||
// Color location is determined by the sink log pattern like in the rest of spdlog sinks.
|
// Color location is determined by the sink log pattern like in the rest of spdlog sinks.
|
||||||
// Colors can be modified if needed using sink->set_color(level, qtTextCharFormat).
|
// Colors can be modified if needed using sink->set_color(level, qtTextCharFormat).
|
||||||
// max_lines is the maximum number of lines that the sink will hold before removing the oldest lines.
|
// max_lines is the maximum number of lines that the sink will hold before removing the oldest
|
||||||
// By default, only ascii (latin1) is supported by this sink. Set is_utf8 to true if utf8 support is needed.
|
// lines. By default, only ascii (latin1) is supported by this sink. Set is_utf8 to true if utf8
|
||||||
|
// support is needed.
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
class qt_color_sink : public base_sink<Mutex> {
|
class qt_color_sink : public base_sink<Mutex> {
|
||||||
public:
|
public:
|
||||||
qt_color_sink(QTextEdit *qt_text_edit, int max_lines, bool dark_colors = false, bool is_utf8 = false)
|
qt_color_sink(QTextEdit *qt_text_edit,
|
||||||
: qt_text_edit_(qt_text_edit),
|
int max_lines,
|
||||||
max_lines_(max_lines),
|
bool dark_colors = false,
|
||||||
is_utf8_(is_utf8) {
|
bool is_utf8 = false)
|
||||||
|
: qt_text_edit_(qt_text_edit)
|
||||||
|
, max_lines_(max_lines)
|
||||||
|
, is_utf8_(is_utf8) {
|
||||||
if (!qt_text_edit_) {
|
if (!qt_text_edit_) {
|
||||||
throw_spdlog_ex("qt_color_text_sink: text_edit is null");
|
throw_spdlog_ex("qt_color_text_sink: text_edit is null");
|
||||||
}
|
}
|
||||||
@ -127,13 +131,13 @@ protected:
|
|||||||
QTextCharFormat level_color,
|
QTextCharFormat level_color,
|
||||||
int color_range_start,
|
int color_range_start,
|
||||||
int color_range_end)
|
int color_range_end)
|
||||||
: max_lines(max_lines),
|
: max_lines(max_lines)
|
||||||
q_text_edit(q_text_edit),
|
, q_text_edit(q_text_edit)
|
||||||
payload(std::move(payload)),
|
, payload(std::move(payload))
|
||||||
default_color(default_color),
|
, default_color(default_color)
|
||||||
level_color(level_color),
|
, level_color(level_color)
|
||||||
color_range_start(color_range_start),
|
, color_range_start(color_range_start)
|
||||||
color_range_end(color_range_end) {}
|
, color_range_end(color_range_end) {}
|
||||||
int max_lines;
|
int max_lines;
|
||||||
QTextEdit *q_text_edit;
|
QTextEdit *q_text_edit;
|
||||||
QString payload;
|
QString payload;
|
||||||
@ -178,8 +182,8 @@ protected:
|
|||||||
void flush_() override {}
|
void flush_() override {}
|
||||||
|
|
||||||
// Add colored text to the text edit widget. This method is invoked in the GUI thread.
|
// Add colored text to the text edit widget. This method is invoked in the GUI thread.
|
||||||
// It is a static method to ensure that it is handled correctly even if the sink is destroyed prematurely
|
// It is a static method to ensure that it is handled correctly even if the sink is destroyed
|
||||||
// before it is invoked.
|
// prematurely before it is invoked.
|
||||||
|
|
||||||
static void invoke_method_(invoke_params params) {
|
static void invoke_method_(invoke_params params) {
|
||||||
auto *document = params.q_text_edit->document();
|
auto *document = params.q_text_edit->document();
|
||||||
@ -206,8 +210,8 @@ protected:
|
|||||||
|
|
||||||
// insert the colorized text
|
// insert the colorized text
|
||||||
cursor.setCharFormat(params.level_color);
|
cursor.setCharFormat(params.level_color);
|
||||||
cursor.insertText(
|
cursor.insertText(params.payload.mid(params.color_range_start,
|
||||||
params.payload.mid(params.color_range_start, params.color_range_end - params.color_range_start));
|
params.color_range_end - params.color_range_start));
|
||||||
|
|
||||||
// insert the text after the color range with default format
|
// insert the text after the color range with default format
|
||||||
cursor.setCharFormat(params.default_color);
|
cursor.setCharFormat(params.default_color);
|
||||||
@ -236,14 +240,16 @@ using qt_color_sink_st = qt_color_sink<details::null_mutex>;
|
|||||||
|
|
||||||
// log to QTextEdit
|
// log to QTextEdit
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger>
|
inline std::shared_ptr<logger> qt_logger_mt(const std::string &logger_name,
|
||||||
qt_logger_mt(const std::string &logger_name, QTextEdit *qt_object, const std::string &meta_method = "append") {
|
QTextEdit *qt_object,
|
||||||
|
const std::string &meta_method = "append") {
|
||||||
return Factory::template create<sinks::qt_sink_mt>(logger_name, qt_object, meta_method);
|
return Factory::template create<sinks::qt_sink_mt>(logger_name, qt_object, meta_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger>
|
inline std::shared_ptr<logger> qt_logger_st(const std::string &logger_name,
|
||||||
qt_logger_st(const std::string &logger_name, QTextEdit *qt_object, const std::string &meta_method = "append") {
|
QTextEdit *qt_object,
|
||||||
|
const std::string &meta_method = "append") {
|
||||||
return Factory::template create<sinks::qt_sink_st>(logger_name, qt_object, meta_method);
|
return Factory::template create<sinks::qt_sink_st>(logger_name, qt_object, meta_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,15 +282,21 @@ qt_logger_st(const std::string &logger_name, QObject *qt_object, const std::stri
|
|||||||
|
|
||||||
// log to QTextEdit with colorize output
|
// log to QTextEdit with colorize output
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger>
|
inline std::shared_ptr<logger> qt_color_logger_mt(const std::string &logger_name,
|
||||||
qt_color_logger_mt(const std::string &logger_name, QTextEdit *qt_text_edit, int max_lines, bool is_utf8 = false) {
|
QTextEdit *qt_text_edit,
|
||||||
return Factory::template create<sinks::qt_color_sink_mt>(logger_name, qt_text_edit, max_lines, false, is_utf8);
|
int max_lines,
|
||||||
|
bool is_utf8 = false) {
|
||||||
|
return Factory::template create<sinks::qt_color_sink_mt>(logger_name, qt_text_edit, max_lines,
|
||||||
|
false, is_utf8);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger>
|
inline std::shared_ptr<logger> qt_color_logger_st(const std::string &logger_name,
|
||||||
qt_color_logger_st(const std::string &logger_name, QTextEdit *qt_text_edit, int max_lines, bool is_utf8 = false) {
|
QTextEdit *qt_text_edit,
|
||||||
return Factory::template create<sinks::qt_color_sink_st>(logger_name, qt_text_edit, max_lines, false, is_utf8);
|
int max_lines,
|
||||||
|
bool is_utf8 = false) {
|
||||||
|
return Factory::template create<sinks::qt_color_sink_st>(logger_name, qt_text_edit, max_lines,
|
||||||
|
false, is_utf8);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -50,7 +50,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void sink_it_(const details::log_msg &msg) override { q_.push_back(details::log_msg_buffer{msg}); }
|
void sink_it_(const details::log_msg &msg) override {
|
||||||
|
q_.push_back(details::log_msg_buffer{msg});
|
||||||
|
}
|
||||||
void flush_() override {}
|
void flush_() override {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -24,15 +24,16 @@ namespace spdlog {
|
|||||||
namespace sinks {
|
namespace sinks {
|
||||||
|
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
SPDLOG_INLINE rotating_file_sink<Mutex>::rotating_file_sink(filename_t base_filename,
|
SPDLOG_INLINE
|
||||||
std::size_t max_size,
|
rotating_file_sink<Mutex>::rotating_file_sink(filename_t base_filename,
|
||||||
std::size_t max_files,
|
std::size_t max_size,
|
||||||
bool rotate_on_open,
|
std::size_t max_files,
|
||||||
const file_event_handlers &event_handlers)
|
bool rotate_on_open,
|
||||||
: base_filename_(std::move(base_filename)),
|
const file_event_handlers &event_handlers)
|
||||||
max_size_(max_size),
|
: base_filename_(std::move(base_filename))
|
||||||
max_files_(max_files),
|
, max_size_(max_size)
|
||||||
file_helper_{event_handlers} {
|
, max_files_(max_files)
|
||||||
|
, file_helper_{event_handlers} {
|
||||||
if (max_size == 0) {
|
if (max_size == 0) {
|
||||||
throw_spdlog_ex("rotating sink constructor: max_size arg cannot be zero");
|
throw_spdlog_ex("rotating sink constructor: max_size arg cannot be zero");
|
||||||
}
|
}
|
||||||
@ -51,7 +52,8 @@ SPDLOG_INLINE rotating_file_sink<Mutex>::rotating_file_sink(filename_t base_file
|
|||||||
// calc filename according to index and file extension if exists.
|
// calc filename according to index and file extension if exists.
|
||||||
// e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt".
|
// e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt".
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
SPDLOG_INLINE filename_t rotating_file_sink<Mutex>::calc_filename(const filename_t &filename, std::size_t index) {
|
SPDLOG_INLINE filename_t rotating_file_sink<Mutex>::calc_filename(const filename_t &filename,
|
||||||
|
std::size_t index) {
|
||||||
if (index == 0u) {
|
if (index == 0u) {
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
@ -116,10 +118,11 @@ SPDLOG_INLINE void rotating_file_sink<Mutex>::rotate_() {
|
|||||||
// rates can cause the rename to fail with permission denied (because of antivirus?).
|
// rates can cause the rename to fail with permission denied (because of antivirus?).
|
||||||
details::os::sleep_for_millis(100);
|
details::os::sleep_for_millis(100);
|
||||||
if (!rename_file_(src, target)) {
|
if (!rename_file_(src, target)) {
|
||||||
file_helper_.reopen(true); // truncate the log file anyway to prevent it to grow beyond its limit!
|
file_helper_.reopen(
|
||||||
|
true); // truncate the log file anyway to prevent it to grow beyond its limit!
|
||||||
current_size_ = 0;
|
current_size_ = 0;
|
||||||
throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " +
|
throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) +
|
||||||
filename_to_str(target),
|
" to " + filename_to_str(target),
|
||||||
errno);
|
errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,8 @@ inline std::shared_ptr<logger> rotating_logger_mt(const std::string &logger_name
|
|||||||
size_t max_files,
|
size_t max_files,
|
||||||
bool rotate_on_open = false,
|
bool rotate_on_open = false,
|
||||||
const file_event_handlers &event_handlers = {}) {
|
const file_event_handlers &event_handlers = {}) {
|
||||||
return Factory::template create<sinks::rotating_file_sink_mt>(logger_name, filename, max_file_size, max_files,
|
return Factory::template create<sinks::rotating_file_sink_mt>(
|
||||||
rotate_on_open, event_handlers);
|
logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
@ -79,8 +79,8 @@ inline std::shared_ptr<logger> rotating_logger_st(const std::string &logger_name
|
|||||||
size_t max_files,
|
size_t max_files,
|
||||||
bool rotate_on_open = false,
|
bool rotate_on_open = false,
|
||||||
const file_event_handlers &event_handlers = {}) {
|
const file_event_handlers &event_handlers = {}) {
|
||||||
return Factory::template create<sinks::rotating_file_sink_st>(logger_name, filename, max_file_size, max_files,
|
return Factory::template create<sinks::rotating_file_sink_st>(
|
||||||
rotate_on_open, event_handlers);
|
logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers);
|
||||||
}
|
}
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
|
||||||
|
@ -13,22 +13,26 @@
|
|||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
|
|
||||||
template <typename Factory>
|
template <typename Factory>
|
||||||
SPDLOG_INLINE std::shared_ptr<logger> stdout_color_mt(const std::string &logger_name, color_mode mode) {
|
SPDLOG_INLINE std::shared_ptr<logger> stdout_color_mt(const std::string &logger_name,
|
||||||
|
color_mode mode) {
|
||||||
return Factory::template create<sinks::stdout_color_sink_mt>(logger_name, mode);
|
return Factory::template create<sinks::stdout_color_sink_mt>(logger_name, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory>
|
template <typename Factory>
|
||||||
SPDLOG_INLINE std::shared_ptr<logger> stdout_color_st(const std::string &logger_name, color_mode mode) {
|
SPDLOG_INLINE std::shared_ptr<logger> stdout_color_st(const std::string &logger_name,
|
||||||
|
color_mode mode) {
|
||||||
return Factory::template create<sinks::stdout_color_sink_st>(logger_name, mode);
|
return Factory::template create<sinks::stdout_color_sink_st>(logger_name, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory>
|
template <typename Factory>
|
||||||
SPDLOG_INLINE std::shared_ptr<logger> stderr_color_mt(const std::string &logger_name, color_mode mode) {
|
SPDLOG_INLINE std::shared_ptr<logger> stderr_color_mt(const std::string &logger_name,
|
||||||
|
color_mode mode) {
|
||||||
return Factory::template create<sinks::stderr_color_sink_mt>(logger_name, mode);
|
return Factory::template create<sinks::stderr_color_sink_mt>(logger_name, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory>
|
template <typename Factory>
|
||||||
SPDLOG_INLINE std::shared_ptr<logger> stderr_color_st(const std::string &logger_name, color_mode mode) {
|
SPDLOG_INLINE std::shared_ptr<logger> stderr_color_st(const std::string &logger_name,
|
||||||
|
color_mode mode) {
|
||||||
return Factory::template create<sinks::stderr_color_sink_st>(logger_name, mode);
|
return Factory::template create<sinks::stderr_color_sink_st>(logger_name, mode);
|
||||||
}
|
}
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -27,16 +27,20 @@ using stderr_color_sink_st = ansicolor_stderr_sink_st;
|
|||||||
} // namespace sinks
|
} // namespace sinks
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
std::shared_ptr<logger> stdout_color_mt(const std::string &logger_name, color_mode mode = color_mode::automatic);
|
std::shared_ptr<logger> stdout_color_mt(const std::string &logger_name,
|
||||||
|
color_mode mode = color_mode::automatic);
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
std::shared_ptr<logger> stdout_color_st(const std::string &logger_name, color_mode mode = color_mode::automatic);
|
std::shared_ptr<logger> stdout_color_st(const std::string &logger_name,
|
||||||
|
color_mode mode = color_mode::automatic);
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
std::shared_ptr<logger> stderr_color_mt(const std::string &logger_name, color_mode mode = color_mode::automatic);
|
std::shared_ptr<logger> stderr_color_mt(const std::string &logger_name,
|
||||||
|
color_mode mode = color_mode::automatic);
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
std::shared_ptr<logger> stderr_color_st(const std::string &logger_name, color_mode mode = color_mode::automatic);
|
std::shared_ptr<logger> stderr_color_st(const std::string &logger_name,
|
||||||
|
color_mode mode = color_mode::automatic);
|
||||||
|
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ namespace sinks {
|
|||||||
|
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
SPDLOG_INLINE stdout_sink_base<ConsoleMutex>::stdout_sink_base(FILE *file)
|
SPDLOG_INLINE stdout_sink_base<ConsoleMutex>::stdout_sink_base(FILE *file)
|
||||||
: mutex_(ConsoleMutex::mutex()),
|
: mutex_(ConsoleMutex::mutex())
|
||||||
file_(file),
|
, file_(file)
|
||||||
formatter_(details::make_unique<spdlog::pattern_formatter>()) {
|
, formatter_(details::make_unique<spdlog::pattern_formatter>()) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// get windows handle from the FILE* object
|
// get windows handle from the FILE* object
|
||||||
|
|
||||||
@ -60,7 +60,8 @@ SPDLOG_INLINE void stdout_sink_base<ConsoleMutex>::log(const details::log_msg &m
|
|||||||
DWORD bytes_written = 0;
|
DWORD bytes_written = 0;
|
||||||
bool ok = ::WriteFile(handle_, formatted.data(), size, &bytes_written, nullptr) != 0;
|
bool ok = ::WriteFile(handle_, formatted.data(), size, &bytes_written, nullptr) != 0;
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
throw_spdlog_ex("stdout_sink_base: WriteFile() failed. GetLastError(): " + std::to_string(::GetLastError()));
|
throw_spdlog_ex("stdout_sink_base: WriteFile() failed. GetLastError(): " +
|
||||||
|
std::to_string(::GetLastError()));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
std::lock_guard<mutex_t> lock(mutex_);
|
std::lock_guard<mutex_t> lock(mutex_);
|
||||||
@ -84,7 +85,8 @@ SPDLOG_INLINE void stdout_sink_base<ConsoleMutex>::set_pattern(const std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
SPDLOG_INLINE void stdout_sink_base<ConsoleMutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
SPDLOG_INLINE void
|
||||||
|
stdout_sink_base<ConsoleMutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
||||||
std::lock_guard<mutex_t> lock(mutex_);
|
std::lock_guard<mutex_t> lock(mutex_);
|
||||||
formatter_ = std::move(sink_formatter);
|
formatter_ = std::move(sink_formatter);
|
||||||
}
|
}
|
||||||
|
@ -21,15 +21,15 @@ class syslog_sink : public base_sink<Mutex> {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
syslog_sink(std::string ident, int syslog_option, int syslog_facility, bool enable_formatting)
|
syslog_sink(std::string ident, int syslog_option, int syslog_facility, bool enable_formatting)
|
||||||
: enable_formatting_{enable_formatting},
|
: enable_formatting_{enable_formatting}
|
||||||
syslog_levels_{{/* spdlog::level::trace */ LOG_DEBUG,
|
, syslog_levels_{{/* spdlog::level::trace */ LOG_DEBUG,
|
||||||
/* spdlog::level::debug */ LOG_DEBUG,
|
/* spdlog::level::debug */ LOG_DEBUG,
|
||||||
/* spdlog::level::info */ LOG_INFO,
|
/* spdlog::level::info */ LOG_INFO,
|
||||||
/* spdlog::level::warn */ LOG_WARNING,
|
/* spdlog::level::warn */ LOG_WARNING,
|
||||||
/* spdlog::level::err */ LOG_ERR,
|
/* spdlog::level::err */ LOG_ERR,
|
||||||
/* spdlog::level::critical */ LOG_CRIT,
|
/* spdlog::level::critical */ LOG_CRIT,
|
||||||
/* spdlog::level::off */ LOG_INFO}},
|
/* spdlog::level::off */ LOG_INFO}}
|
||||||
ident_{std::move(ident)} {
|
, ident_{std::move(ident)} {
|
||||||
// set ident to be program name if empty
|
// set ident to be program name if empty
|
||||||
::openlog(ident_.empty() ? nullptr : ident_.c_str(), syslog_option, syslog_facility);
|
::openlog(ident_.empty() ? nullptr : ident_.c_str(), syslog_option, syslog_facility);
|
||||||
}
|
}
|
||||||
@ -88,8 +88,8 @@ inline std::shared_ptr<logger> syslog_logger_mt(const std::string &logger_name,
|
|||||||
int syslog_option = 0,
|
int syslog_option = 0,
|
||||||
int syslog_facility = LOG_USER,
|
int syslog_facility = LOG_USER,
|
||||||
bool enable_formatting = false) {
|
bool enable_formatting = false) {
|
||||||
return Factory::template create<sinks::syslog_sink_mt>(logger_name, syslog_ident, syslog_option, syslog_facility,
|
return Factory::template create<sinks::syslog_sink_mt>(logger_name, syslog_ident, syslog_option,
|
||||||
enable_formatting);
|
syslog_facility, enable_formatting);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
@ -98,7 +98,7 @@ inline std::shared_ptr<logger> syslog_logger_st(const std::string &logger_name,
|
|||||||
int syslog_option = 0,
|
int syslog_option = 0,
|
||||||
int syslog_facility = LOG_USER,
|
int syslog_facility = LOG_USER,
|
||||||
bool enable_formatting = false) {
|
bool enable_formatting = false) {
|
||||||
return Factory::template create<sinks::syslog_sink_st>(logger_name, syslog_ident, syslog_option, syslog_facility,
|
return Factory::template create<sinks::syslog_sink_st>(logger_name, syslog_ident, syslog_option,
|
||||||
enable_formatting);
|
syslog_facility, enable_formatting);
|
||||||
}
|
}
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -24,9 +24,9 @@ template <typename Mutex>
|
|||||||
class systemd_sink : public base_sink<Mutex> {
|
class systemd_sink : public base_sink<Mutex> {
|
||||||
public:
|
public:
|
||||||
systemd_sink(std::string ident = "", bool enable_formatting = false)
|
systemd_sink(std::string ident = "", bool enable_formatting = false)
|
||||||
: ident_{std::move(ident)},
|
: ident_{std::move(ident)}
|
||||||
enable_formatting_{enable_formatting},
|
, enable_formatting_{enable_formatting}
|
||||||
syslog_levels_{{/* spdlog::level::trace */ LOG_DEBUG,
|
, syslog_levels_{{/* spdlog::level::trace */ LOG_DEBUG,
|
||||||
/* spdlog::level::debug */ LOG_DEBUG,
|
/* spdlog::level::debug */ LOG_DEBUG,
|
||||||
/* spdlog::level::info */ LOG_INFO,
|
/* spdlog::level::info */ LOG_INFO,
|
||||||
/* spdlog::level::warn */ LOG_WARNING,
|
/* spdlog::level::warn */ LOG_WARNING,
|
||||||
@ -67,22 +67,25 @@ protected:
|
|||||||
// Do not send source location if not available
|
// Do not send source location if not available
|
||||||
if (msg.source.empty()) {
|
if (msg.source.empty()) {
|
||||||
// Note: function call inside '()' to avoid macro expansion
|
// Note: function call inside '()' to avoid macro expansion
|
||||||
err = (sd_journal_send)("MESSAGE=%.*s", static_cast<int>(length), payload.data(), "PRIORITY=%d",
|
err = (sd_journal_send)("MESSAGE=%.*s", static_cast<int>(length), payload.data(),
|
||||||
syslog_level(msg.level),
|
"PRIORITY=%d", syslog_level(msg.level),
|
||||||
#ifndef SPDLOG_NO_THREAD_ID
|
#ifndef SPDLOG_NO_THREAD_ID
|
||||||
"TID=%zu", details::os::thread_id(),
|
"TID=%zu", details::os::thread_id(),
|
||||||
#endif
|
#endif
|
||||||
"SYSLOG_IDENTIFIER=%.*s", static_cast<int>(syslog_identifier.size()),
|
"SYSLOG_IDENTIFIER=%.*s",
|
||||||
|
static_cast<int>(syslog_identifier.size()),
|
||||||
syslog_identifier.data(), nullptr);
|
syslog_identifier.data(), nullptr);
|
||||||
} else {
|
} else {
|
||||||
err = (sd_journal_send)("MESSAGE=%.*s", static_cast<int>(length), payload.data(), "PRIORITY=%d",
|
err = (sd_journal_send)("MESSAGE=%.*s", static_cast<int>(length), payload.data(),
|
||||||
syslog_level(msg.level),
|
"PRIORITY=%d", syslog_level(msg.level),
|
||||||
#ifndef SPDLOG_NO_THREAD_ID
|
#ifndef SPDLOG_NO_THREAD_ID
|
||||||
"TID=%zu", details::os::thread_id(),
|
"TID=%zu", details::os::thread_id(),
|
||||||
#endif
|
#endif
|
||||||
"SYSLOG_IDENTIFIER=%.*s", static_cast<int>(syslog_identifier.size()),
|
"SYSLOG_IDENTIFIER=%.*s",
|
||||||
syslog_identifier.data(), "CODE_FILE=%s", msg.source.filename, "CODE_LINE=%d",
|
static_cast<int>(syslog_identifier.size()),
|
||||||
msg.source.line, "CODE_FUNC=%s", msg.source.funcname, nullptr);
|
syslog_identifier.data(), "CODE_FILE=%s", msg.source.filename,
|
||||||
|
"CODE_LINE=%d", msg.source.line, "CODE_FUNC=%s",
|
||||||
|
msg.source.funcname, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -90,7 +93,9 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int syslog_level(level::level_enum l) { return syslog_levels_.at(static_cast<levels_array::size_type>(l)); }
|
int syslog_level(level::level_enum l) {
|
||||||
|
return syslog_levels_.at(static_cast<levels_array::size_type>(l));
|
||||||
|
}
|
||||||
|
|
||||||
void flush_() override {}
|
void flush_() override {}
|
||||||
};
|
};
|
||||||
@ -101,14 +106,16 @@ using systemd_sink_st = systemd_sink<details::null_mutex>;
|
|||||||
|
|
||||||
// Create and register a syslog logger
|
// Create and register a syslog logger
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger>
|
inline std::shared_ptr<logger> systemd_logger_mt(const std::string &logger_name,
|
||||||
systemd_logger_mt(const std::string &logger_name, const std::string &ident = "", bool enable_formatting = false) {
|
const std::string &ident = "",
|
||||||
|
bool enable_formatting = false) {
|
||||||
return Factory::template create<sinks::systemd_sink_mt>(logger_name, ident, enable_formatting);
|
return Factory::template create<sinks::systemd_sink_mt>(logger_name, ident, enable_formatting);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger>
|
inline std::shared_ptr<logger> systemd_logger_st(const std::string &logger_name,
|
||||||
systemd_logger_st(const std::string &logger_name, const std::string &ident = "", bool enable_formatting = false) {
|
const std::string &ident = "",
|
||||||
|
bool enable_formatting = false) {
|
||||||
return Factory::template create<sinks::systemd_sink_st>(logger_name, ident, enable_formatting);
|
return Factory::template create<sinks::systemd_sink_st>(logger_name, ident, enable_formatting);
|
||||||
}
|
}
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
// Simple tcp client sink
|
// Simple tcp client sink
|
||||||
// Connects to remote address and send the formatted log.
|
// Connects to remote address and send the formatted log.
|
||||||
// Will attempt to reconnect if connection drops.
|
// Will attempt to reconnect if connection drops.
|
||||||
// If more complicated behaviour is needed (i.e get responses), you can inherit it and override the sink_it_ method.
|
// If more complicated behaviour is needed (i.e get responses), you can inherit it and override the
|
||||||
|
// sink_it_ method.
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace sinks {
|
namespace sinks {
|
||||||
@ -33,8 +34,8 @@ struct tcp_sink_config {
|
|||||||
bool lazy_connect = false; // if true connect on first log call instead of on construction
|
bool lazy_connect = false; // if true connect on first log call instead of on construction
|
||||||
|
|
||||||
tcp_sink_config(std::string host, int port)
|
tcp_sink_config(std::string host, int port)
|
||||||
: server_host{std::move(host)},
|
: server_host{std::move(host)}
|
||||||
server_port{port} {}
|
, server_port{port} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
|
@ -28,8 +28,8 @@ struct udp_sink_config {
|
|||||||
uint16_t server_port;
|
uint16_t server_port;
|
||||||
|
|
||||||
udp_sink_config(std::string host, uint16_t port)
|
udp_sink_config(std::string host, uint16_t port)
|
||||||
: server_host{std::move(host)},
|
: server_host{std::move(host)}
|
||||||
server_port{port} {}
|
, server_port{port} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
@ -61,7 +61,8 @@ using udp_sink_st = udp_sink<spdlog::details::null_mutex>;
|
|||||||
// factory functions
|
// factory functions
|
||||||
//
|
//
|
||||||
template <typename Factory = spdlog::synchronous_factory>
|
template <typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> udp_logger_mt(const std::string &logger_name, sinks::udp_sink_config skin_config) {
|
inline std::shared_ptr<logger> udp_logger_mt(const std::string &logger_name,
|
||||||
|
sinks::udp_sink_config skin_config) {
|
||||||
return Factory::template create<sinks::udp_sink_mt>(logger_name, skin_config);
|
return Factory::template create<sinks::udp_sink_mt>(logger_name, skin_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
// Writing to Windows Event Log requires the registry entries below to be present, with the following modifications:
|
// Writing to Windows Event Log requires the registry entries below to be present, with the
|
||||||
|
// following modifications:
|
||||||
// 1. <log_name> should be replaced with your log name (e.g. your application name)
|
// 1. <log_name> should be replaced with your log name (e.g. your application name)
|
||||||
// 2. <source_name> should be replaced with the specific source name and the key should be duplicated for
|
// 2. <source_name> should be replaced with the specific source name and the key should be
|
||||||
|
// duplicated for
|
||||||
// each source used in the application
|
// each source used in the application
|
||||||
//
|
//
|
||||||
// Since typically modifications of this kind require elevation, it's better to do it as a part of setup procedure.
|
// Since typically modifications of this kind require elevation, it's better to do it as a part of
|
||||||
// The snippet below uses mscoree.dll as the message file as it exists on most of the Windows systems anyway and
|
// setup procedure. The snippet below uses mscoree.dll as the message file as it exists on most of
|
||||||
// happens to contain the needed resource.
|
// the Windows systems anyway and happens to contain the needed resource.
|
||||||
//
|
//
|
||||||
// You can also specify a custom message file if needed.
|
// You can also specify a custom message file if needed.
|
||||||
// Please refer to Event Log functions descriptions in MSDN for more details on custom message files.
|
// Please refer to Event Log functions descriptions in MSDN for more details on custom message
|
||||||
|
// files.
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -69,9 +72,11 @@ struct win32_error : public spdlog_ex {
|
|||||||
std::string system_message;
|
std::string system_message;
|
||||||
|
|
||||||
local_alloc_t format_message_result{};
|
local_alloc_t format_message_result{};
|
||||||
auto format_message_succeeded = ::FormatMessageA(
|
auto format_message_succeeded =
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
|
::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&format_message_result.hlocal_, 0, nullptr);
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPSTR)&format_message_result.hlocal_, 0, nullptr);
|
||||||
|
|
||||||
if (format_message_succeeded && format_message_result.hlocal_) {
|
if (format_message_succeeded && format_message_result.hlocal_) {
|
||||||
system_message = fmt_lib::format(" ({})", (LPSTR)format_message_result.hlocal_);
|
system_message = fmt_lib::format(" ({})", (LPSTR)format_message_result.hlocal_);
|
||||||
@ -124,18 +129,21 @@ public:
|
|||||||
|
|
||||||
~process_token_t() { ::CloseHandle(token_handle_); }
|
~process_token_t() { ::CloseHandle(token_handle_); }
|
||||||
|
|
||||||
} current_process_token(::GetCurrentProcess()); // GetCurrentProcess returns pseudohandle, no leak here!
|
} current_process_token(
|
||||||
|
::GetCurrentProcess()); // GetCurrentProcess returns pseudohandle, no leak here!
|
||||||
|
|
||||||
// Get the required size, this is expected to fail with ERROR_INSUFFICIENT_BUFFER and return the token size
|
// Get the required size, this is expected to fail with ERROR_INSUFFICIENT_BUFFER and return
|
||||||
|
// the token size
|
||||||
DWORD tusize = 0;
|
DWORD tusize = 0;
|
||||||
if (::GetTokenInformation(current_process_token.token_handle_, TokenUser, NULL, 0, &tusize)) {
|
if (::GetTokenInformation(current_process_token.token_handle_, TokenUser, NULL, 0,
|
||||||
|
&tusize)) {
|
||||||
SPDLOG_THROW(win32_error("GetTokenInformation should fail"));
|
SPDLOG_THROW(win32_error("GetTokenInformation should fail"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// get user token
|
// get user token
|
||||||
std::vector<unsigned char> buffer(static_cast<size_t>(tusize));
|
std::vector<unsigned char> buffer(static_cast<size_t>(tusize));
|
||||||
if (!::GetTokenInformation(current_process_token.token_handle_, TokenUser, (LPVOID)buffer.data(), tusize,
|
if (!::GetTokenInformation(current_process_token.token_handle_, TokenUser,
|
||||||
&tusize)) {
|
(LPVOID)buffer.data(), tusize, &tusize)) {
|
||||||
SPDLOG_THROW(win32_error("GetTokenInformation"));
|
SPDLOG_THROW(win32_error("GetTokenInformation"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,14 +216,14 @@ protected:
|
|||||||
details::os::utf8_to_wstrbuf(string_view_t(formatted.data(), formatted.size()), buf);
|
details::os::utf8_to_wstrbuf(string_view_t(formatted.data(), formatted.size()), buf);
|
||||||
|
|
||||||
LPCWSTR lp_wstr = buf.data();
|
LPCWSTR lp_wstr = buf.data();
|
||||||
succeeded = static_cast<bool>(::ReportEventW(event_log_handle(), eventlog::get_event_type(msg),
|
succeeded = static_cast<bool>(::ReportEventW(
|
||||||
eventlog::get_event_category(msg), event_id_,
|
event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg),
|
||||||
current_user_sid_.as_sid(), 1, 0, &lp_wstr, nullptr));
|
event_id_, current_user_sid_.as_sid(), 1, 0, &lp_wstr, nullptr));
|
||||||
#else
|
#else
|
||||||
LPCSTR lp_str = formatted.data();
|
LPCSTR lp_str = formatted.data();
|
||||||
succeeded = static_cast<bool>(::ReportEventA(event_log_handle(), eventlog::get_event_type(msg),
|
succeeded = static_cast<bool>(::ReportEventA(
|
||||||
eventlog::get_event_category(msg), event_id_,
|
event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg),
|
||||||
current_user_sid_.as_sid(), 1, 0, &lp_str, nullptr));
|
event_id_, current_user_sid_.as_sid(), 1, 0, &lp_str, nullptr));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!succeeded) {
|
if (!succeeded) {
|
||||||
@ -226,14 +234,15 @@ protected:
|
|||||||
void flush_() override {}
|
void flush_() override {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
win_eventlog_sink(std::string const &source, DWORD event_id = 1000 /* according to mscoree.dll */)
|
win_eventlog_sink(std::string const &source,
|
||||||
: source_(source),
|
DWORD event_id = 1000 /* according to mscoree.dll */)
|
||||||
event_id_(event_id) {
|
: source_(source)
|
||||||
|
, event_id_(event_id) {
|
||||||
try {
|
try {
|
||||||
current_user_sid_ = internal::sid_t::get_current_user_sid();
|
current_user_sid_ = internal::sid_t::get_current_user_sid();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
// get_current_user_sid() is unlikely to fail and if it does, we can still proceed without
|
// get_current_user_sid() is unlikely to fail and if it does, we can still proceed
|
||||||
// current_user_sid but in the event log the record will have no user name
|
// without current_user_sid but in the event log the record will have no user name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,18 +17,20 @@ namespace spdlog {
|
|||||||
namespace sinks {
|
namespace sinks {
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
SPDLOG_INLINE wincolor_sink<ConsoleMutex>::wincolor_sink(void *out_handle, color_mode mode)
|
SPDLOG_INLINE wincolor_sink<ConsoleMutex>::wincolor_sink(void *out_handle, color_mode mode)
|
||||||
: out_handle_(out_handle),
|
: out_handle_(out_handle)
|
||||||
mutex_(ConsoleMutex::mutex()),
|
, mutex_(ConsoleMutex::mutex())
|
||||||
formatter_(details::make_unique<spdlog::pattern_formatter>()) {
|
, formatter_(details::make_unique<spdlog::pattern_formatter>()) {
|
||||||
|
|
||||||
set_color_mode_impl(mode);
|
set_color_mode_impl(mode);
|
||||||
// set level colors
|
// set level colors
|
||||||
colors_[level::trace] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; // white
|
colors_[level::trace] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; // white
|
||||||
colors_[level::debug] = FOREGROUND_GREEN | FOREGROUND_BLUE; // cyan
|
colors_[level::debug] = FOREGROUND_GREEN | FOREGROUND_BLUE; // cyan
|
||||||
colors_[level::info] = FOREGROUND_GREEN; // green
|
colors_[level::info] = FOREGROUND_GREEN; // green
|
||||||
colors_[level::warn] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; // intense yellow
|
colors_[level::warn] =
|
||||||
colors_[level::err] = FOREGROUND_RED | FOREGROUND_INTENSITY; // intense red
|
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; // intense yellow
|
||||||
colors_[level::critical] = BACKGROUND_RED | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
|
colors_[level::err] = FOREGROUND_RED | FOREGROUND_INTENSITY; // intense red
|
||||||
|
colors_[level::critical] = BACKGROUND_RED | FOREGROUND_RED | FOREGROUND_GREEN |
|
||||||
|
FOREGROUND_BLUE |
|
||||||
FOREGROUND_INTENSITY; // intense white on red background
|
FOREGROUND_INTENSITY; // intense white on red background
|
||||||
colors_[level::off] = 0;
|
colors_[level::off] = 0;
|
||||||
}
|
}
|
||||||
@ -40,7 +42,8 @@ SPDLOG_INLINE wincolor_sink<ConsoleMutex>::~wincolor_sink() {
|
|||||||
|
|
||||||
// change the color for the given level
|
// change the color for the given level
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::set_color(level::level_enum level, std::uint16_t color) {
|
void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::set_color(level::level_enum level,
|
||||||
|
std::uint16_t color) {
|
||||||
std::lock_guard<mutex_t> lock(mutex_);
|
std::lock_guard<mutex_t> lock(mutex_);
|
||||||
colors_[static_cast<size_t>(level)] = color;
|
colors_[static_cast<size_t>(level)] = color;
|
||||||
}
|
}
|
||||||
@ -60,7 +63,8 @@ void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::log(const details::log_msg &msg)
|
|||||||
// before color range
|
// before color range
|
||||||
print_range_(formatted, 0, msg.color_range_start);
|
print_range_(formatted, 0, msg.color_range_start);
|
||||||
// in color range
|
// in color range
|
||||||
auto orig_attribs = static_cast<WORD>(set_foreground_color_(colors_[static_cast<size_t>(msg.level)]));
|
auto orig_attribs =
|
||||||
|
static_cast<WORD>(set_foreground_color_(colors_[static_cast<size_t>(msg.level)]));
|
||||||
print_range_(formatted, msg.color_range_start, msg.color_range_end);
|
print_range_(formatted, msg.color_range_start, msg.color_range_end);
|
||||||
// reset to orig colors
|
// reset to orig colors
|
||||||
::SetConsoleTextAttribute(static_cast<HANDLE>(out_handle_), orig_attribs);
|
::SetConsoleTextAttribute(static_cast<HANDLE>(out_handle_), orig_attribs);
|
||||||
@ -83,7 +87,8 @@ void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::set_pattern(const std::string &p
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
void SPDLOG_INLINE
|
||||||
|
wincolor_sink<ConsoleMutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
||||||
std::lock_guard<mutex_t> lock(mutex_);
|
std::lock_guard<mutex_t> lock(mutex_);
|
||||||
formatter_ = std::move(sink_formatter);
|
formatter_ = std::move(sink_formatter);
|
||||||
}
|
}
|
||||||
@ -108,7 +113,8 @@ void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::set_color_mode_impl(color_mode m
|
|||||||
|
|
||||||
// set foreground color and return the orig console attributes (for resetting later)
|
// set foreground color and return the orig console attributes (for resetting later)
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
std::uint16_t SPDLOG_INLINE wincolor_sink<ConsoleMutex>::set_foreground_color_(std::uint16_t attribs) {
|
std::uint16_t SPDLOG_INLINE
|
||||||
|
wincolor_sink<ConsoleMutex>::set_foreground_color_(std::uint16_t attribs) {
|
||||||
CONSOLE_SCREEN_BUFFER_INFO orig_buffer_info;
|
CONSOLE_SCREEN_BUFFER_INFO orig_buffer_info;
|
||||||
if (!::GetConsoleScreenBufferInfo(static_cast<HANDLE>(out_handle_), &orig_buffer_info)) {
|
if (!::GetConsoleScreenBufferInfo(static_cast<HANDLE>(out_handle_), &orig_buffer_info)) {
|
||||||
// just return white if failed getting console info
|
// just return white if failed getting console info
|
||||||
@ -117,18 +123,21 @@ std::uint16_t SPDLOG_INLINE wincolor_sink<ConsoleMutex>::set_foreground_color_(s
|
|||||||
|
|
||||||
// change only the foreground bits (lowest 4 bits)
|
// change only the foreground bits (lowest 4 bits)
|
||||||
auto new_attribs = static_cast<WORD>(attribs) | (orig_buffer_info.wAttributes & 0xfff0);
|
auto new_attribs = static_cast<WORD>(attribs) | (orig_buffer_info.wAttributes & 0xfff0);
|
||||||
auto ignored = ::SetConsoleTextAttribute(static_cast<HANDLE>(out_handle_), static_cast<WORD>(new_attribs));
|
auto ignored =
|
||||||
|
::SetConsoleTextAttribute(static_cast<HANDLE>(out_handle_), static_cast<WORD>(new_attribs));
|
||||||
(void)(ignored);
|
(void)(ignored);
|
||||||
return static_cast<std::uint16_t>(orig_buffer_info.wAttributes); // return orig attribs
|
return static_cast<std::uint16_t>(orig_buffer_info.wAttributes); // return orig attribs
|
||||||
}
|
}
|
||||||
|
|
||||||
// print a range of formatted message to console
|
// print a range of formatted message to console
|
||||||
template <typename ConsoleMutex>
|
template <typename ConsoleMutex>
|
||||||
void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::print_range_(const memory_buf_t &formatted, size_t start, size_t end) {
|
void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::print_range_(const memory_buf_t &formatted,
|
||||||
|
size_t start,
|
||||||
|
size_t end) {
|
||||||
if (end > start) {
|
if (end > start) {
|
||||||
auto size = static_cast<DWORD>(end - start);
|
auto size = static_cast<DWORD>(end - start);
|
||||||
auto ignored =
|
auto ignored = ::WriteConsoleA(static_cast<HANDLE>(out_handle_), formatted.data() + start,
|
||||||
::WriteConsoleA(static_cast<HANDLE>(out_handle_), formatted.data() + start, size, nullptr, nullptr);
|
size, nullptr, nullptr);
|
||||||
(void)(ignored);
|
(void)(ignored);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +146,8 @@ template <typename ConsoleMutex>
|
|||||||
void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::write_to_file_(const memory_buf_t &formatted) {
|
void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::write_to_file_(const memory_buf_t &formatted) {
|
||||||
auto size = static_cast<DWORD>(formatted.size());
|
auto size = static_cast<DWORD>(formatted.size());
|
||||||
DWORD bytes_written = 0;
|
DWORD bytes_written = 0;
|
||||||
auto ignored = ::WriteFile(static_cast<HANDLE>(out_handle_), formatted.data(), size, &bytes_written, nullptr);
|
auto ignored = ::WriteFile(static_cast<HANDLE>(out_handle_), formatted.data(), size,
|
||||||
|
&bytes_written, nullptr);
|
||||||
(void)(ignored);
|
(void)(ignored);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,17 +16,22 @@ SPDLOG_INLINE void initialize_logger(std::shared_ptr<logger> logger) {
|
|||||||
details::registry::instance().initialize_logger(std::move(logger));
|
details::registry::instance().initialize_logger(std::move(logger));
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE std::shared_ptr<logger> get(const std::string &name) { return details::registry::instance().get(name); }
|
SPDLOG_INLINE std::shared_ptr<logger> get(const std::string &name) {
|
||||||
|
return details::registry::instance().get(name);
|
||||||
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void set_formatter(std::unique_ptr<spdlog::formatter> formatter) {
|
SPDLOG_INLINE void set_formatter(std::unique_ptr<spdlog::formatter> formatter) {
|
||||||
details::registry::instance().set_formatter(std::move(formatter));
|
details::registry::instance().set_formatter(std::move(formatter));
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void set_pattern(std::string pattern, pattern_time_type time_type) {
|
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 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 disable_backtrace() { details::registry::instance().disable_backtrace(); }
|
||||||
|
|
||||||
@ -34,11 +39,17 @@ SPDLOG_INLINE void dump_backtrace() { default_logger_raw()->dump_backtrace(); }
|
|||||||
|
|
||||||
SPDLOG_INLINE level::level_enum get_level() { return default_logger_raw()->level(); }
|
SPDLOG_INLINE level::level_enum get_level() { return default_logger_raw()->level(); }
|
||||||
|
|
||||||
SPDLOG_INLINE bool should_log(level::level_enum log_level) { return default_logger_raw()->should_log(log_level); }
|
SPDLOG_INLINE bool should_log(level::level_enum log_level) {
|
||||||
|
return default_logger_raw()->should_log(log_level);
|
||||||
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void set_level(level::level_enum log_level) { details::registry::instance().set_level(log_level); }
|
SPDLOG_INLINE void set_level(level::level_enum log_level) {
|
||||||
|
details::registry::instance().set_level(log_level);
|
||||||
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void flush_on(level::level_enum log_level) { details::registry::instance().flush_on(log_level); }
|
SPDLOG_INLINE void flush_on(level::level_enum log_level) {
|
||||||
|
details::registry::instance().flush_on(log_level);
|
||||||
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void set_error_handler(void (*handler)(const std::string &msg)) {
|
SPDLOG_INLINE void set_error_handler(void (*handler)(const std::string &msg)) {
|
||||||
details::registry::instance().set_error_handler(handler);
|
details::registry::instance().set_error_handler(handler);
|
||||||
@ -66,7 +77,9 @@ SPDLOG_INLINE std::shared_ptr<spdlog::logger> default_logger() {
|
|||||||
return details::registry::instance().default_logger();
|
return details::registry::instance().default_logger();
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE spdlog::logger *default_logger_raw() { return details::registry::instance().get_default_raw(); }
|
SPDLOG_INLINE spdlog::logger *default_logger_raw() {
|
||||||
|
return details::registry::instance().get_default_raw();
|
||||||
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void set_default_logger(std::shared_ptr<spdlog::logger> default_logger) {
|
SPDLOG_INLINE void set_default_logger(std::shared_ptr<spdlog::logger> default_logger) {
|
||||||
details::registry::instance().set_default_logger(std::move(default_logger));
|
details::registry::instance().set_default_logger(std::move(default_logger));
|
||||||
|
@ -32,7 +32,8 @@ using default_factory = synchronous_factory;
|
|||||||
// spdlog::create<daily_file_sink_st>("logger_name", "dailylog_filename", 11, 59);
|
// spdlog::create<daily_file_sink_st>("logger_name", "dailylog_filename", 11, 59);
|
||||||
template <typename Sink, typename... SinkArgs>
|
template <typename Sink, typename... SinkArgs>
|
||||||
inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&...sink_args) {
|
inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&...sink_args) {
|
||||||
return default_factory::create<Sink>(std::move(logger_name), std::forward<SinkArgs>(sink_args)...);
|
return default_factory::create<Sink>(std::move(logger_name),
|
||||||
|
std::forward<SinkArgs>(sink_args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize and register a logger,
|
// Initialize and register a logger,
|
||||||
@ -55,7 +56,8 @@ SPDLOG_API void set_formatter(std::unique_ptr<spdlog::formatter> formatter);
|
|||||||
|
|
||||||
// Set global format string.
|
// Set global format string.
|
||||||
// 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
|
// enable global backtrace support
|
||||||
SPDLOG_API void enable_backtrace(size_t n_messages);
|
SPDLOG_API void enable_backtrace(size_t n_messages);
|
||||||
@ -139,7 +141,8 @@ SPDLOG_API void set_default_logger(std::shared_ptr<spdlog::logger> default_logge
|
|||||||
SPDLOG_API void apply_logger_env_levels(std::shared_ptr<logger> logger);
|
SPDLOG_API void apply_logger_env_levels(std::shared_ptr<logger> logger);
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
inline void log(source_loc source, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) {
|
inline void
|
||||||
|
log(source_loc source, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) {
|
||||||
default_logger_raw()->log(source, lvl, fmt, std::forward<Args>(args)...);
|
default_logger_raw()->log(source, lvl, fmt, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +193,8 @@ inline void log(level::level_enum lvl, const T &msg) {
|
|||||||
|
|
||||||
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
inline void log(source_loc source, level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) {
|
inline void
|
||||||
|
log(source_loc source, level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) {
|
||||||
default_logger_raw()->log(source, lvl, fmt, std::forward<Args>(args)...);
|
default_logger_raw()->log(source, lvl, fmt, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,11 +283,13 @@ inline void critical(const T &msg) {
|
|||||||
#define SPDLOG_LOGGER_CALL(logger, level, ...) \
|
#define SPDLOG_LOGGER_CALL(logger, level, ...) \
|
||||||
(logger)->log(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__)
|
(logger)->log(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define SPDLOG_LOGGER_CALL(logger, level, ...) (logger)->log(spdlog::source_loc{}, level, __VA_ARGS__)
|
#define SPDLOG_LOGGER_CALL(logger, level, ...) \
|
||||||
|
(logger)->log(spdlog::source_loc{}, level, __VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
|
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
|
||||||
#define SPDLOG_LOGGER_TRACE(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::trace, __VA_ARGS__)
|
#define SPDLOG_LOGGER_TRACE(logger, ...) \
|
||||||
|
SPDLOG_LOGGER_CALL(logger, spdlog::level::trace, __VA_ARGS__)
|
||||||
#define SPDLOG_TRACE(...) SPDLOG_LOGGER_TRACE(spdlog::default_logger_raw(), __VA_ARGS__)
|
#define SPDLOG_TRACE(...) SPDLOG_LOGGER_TRACE(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define SPDLOG_LOGGER_TRACE(logger, ...) (void)0
|
#define SPDLOG_LOGGER_TRACE(logger, ...) (void)0
|
||||||
@ -291,7 +297,8 @@ inline void critical(const T &msg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
|
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
|
||||||
#define SPDLOG_LOGGER_DEBUG(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::debug, __VA_ARGS__)
|
#define SPDLOG_LOGGER_DEBUG(logger, ...) \
|
||||||
|
SPDLOG_LOGGER_CALL(logger, spdlog::level::debug, __VA_ARGS__)
|
||||||
#define SPDLOG_DEBUG(...) SPDLOG_LOGGER_DEBUG(spdlog::default_logger_raw(), __VA_ARGS__)
|
#define SPDLOG_DEBUG(...) SPDLOG_LOGGER_DEBUG(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define SPDLOG_LOGGER_DEBUG(logger, ...) (void)0
|
#define SPDLOG_LOGGER_DEBUG(logger, ...) (void)0
|
||||||
@ -299,7 +306,8 @@ inline void critical(const T &msg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_INFO
|
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_INFO
|
||||||
#define SPDLOG_LOGGER_INFO(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::info, __VA_ARGS__)
|
#define SPDLOG_LOGGER_INFO(logger, ...) \
|
||||||
|
SPDLOG_LOGGER_CALL(logger, spdlog::level::info, __VA_ARGS__)
|
||||||
#define SPDLOG_INFO(...) SPDLOG_LOGGER_INFO(spdlog::default_logger_raw(), __VA_ARGS__)
|
#define SPDLOG_INFO(...) SPDLOG_LOGGER_INFO(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define SPDLOG_LOGGER_INFO(logger, ...) (void)0
|
#define SPDLOG_LOGGER_INFO(logger, ...) (void)0
|
||||||
@ -307,7 +315,8 @@ inline void critical(const T &msg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_WARN
|
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_WARN
|
||||||
#define SPDLOG_LOGGER_WARN(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::warn, __VA_ARGS__)
|
#define SPDLOG_LOGGER_WARN(logger, ...) \
|
||||||
|
SPDLOG_LOGGER_CALL(logger, spdlog::level::warn, __VA_ARGS__)
|
||||||
#define SPDLOG_WARN(...) SPDLOG_LOGGER_WARN(spdlog::default_logger_raw(), __VA_ARGS__)
|
#define SPDLOG_WARN(...) SPDLOG_LOGGER_WARN(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define SPDLOG_LOGGER_WARN(logger, ...) (void)0
|
#define SPDLOG_LOGGER_WARN(logger, ...) (void)0
|
||||||
@ -315,7 +324,8 @@ inline void critical(const T &msg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_ERROR
|
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_ERROR
|
||||||
#define SPDLOG_LOGGER_ERROR(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::err, __VA_ARGS__)
|
#define SPDLOG_LOGGER_ERROR(logger, ...) \
|
||||||
|
SPDLOG_LOGGER_CALL(logger, spdlog::level::err, __VA_ARGS__)
|
||||||
#define SPDLOG_ERROR(...) SPDLOG_LOGGER_ERROR(spdlog::default_logger_raw(), __VA_ARGS__)
|
#define SPDLOG_ERROR(...) SPDLOG_LOGGER_ERROR(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define SPDLOG_LOGGER_ERROR(logger, ...) (void)0
|
#define SPDLOG_LOGGER_ERROR(logger, ...) (void)0
|
||||||
@ -323,7 +333,8 @@ inline void critical(const T &msg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_CRITICAL
|
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_CRITICAL
|
||||||
#define SPDLOG_LOGGER_CRITICAL(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::critical, __VA_ARGS__)
|
#define SPDLOG_LOGGER_CRITICAL(logger, ...) \
|
||||||
|
SPDLOG_LOGGER_CALL(logger, spdlog::level::critical, __VA_ARGS__)
|
||||||
#define SPDLOG_CRITICAL(...) SPDLOG_LOGGER_CRITICAL(spdlog::default_logger_raw(), __VA_ARGS__)
|
#define SPDLOG_CRITICAL(...) SPDLOG_LOGGER_CRITICAL(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define SPDLOG_LOGGER_CRITICAL(logger, ...) (void)0
|
#define SPDLOG_LOGGER_CRITICAL(logger, ...) (void)0
|
||||||
|
@ -35,7 +35,9 @@ public:
|
|||||||
stopwatch()
|
stopwatch()
|
||||||
: start_tp_{clock::now()} {}
|
: start_tp_{clock::now()} {}
|
||||||
|
|
||||||
std::chrono::duration<double> elapsed() const { return std::chrono::duration<double>(clock::now() - start_tp_); }
|
std::chrono::duration<double> elapsed() const {
|
||||||
|
return std::chrono::duration<double>(clock::now() - start_tp_);
|
||||||
|
}
|
||||||
|
|
||||||
void reset() { start_tp_ = clock::now(); }
|
void reset() { start_tp_ = clock::now(); }
|
||||||
};
|
};
|
||||||
|
@ -102,7 +102,8 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Uncomment to customize level names (e.g. "MY TRACE")
|
// Uncomment to customize level names (e.g. "MY TRACE")
|
||||||
//
|
//
|
||||||
// #define SPDLOG_LEVEL_NAMES { "MY TRACE", "MY DEBUG", "MY INFO", "MY WARNING", "MY ERROR", "MY CRITICAL", "OFF" }
|
// #define SPDLOG_LEVEL_NAMES { "MY TRACE", "MY DEBUG", "MY INFO", "MY WARNING", "MY ERROR", "MY
|
||||||
|
// CRITICAL", "OFF" }
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -31,7 +31,8 @@ template FMT_API void buffer<char>::append(const char *, const char *);
|
|||||||
// DEPRECATED!
|
// DEPRECATED!
|
||||||
// There is no correspondent extern template in format.h because of
|
// There is no correspondent extern template in format.h because of
|
||||||
// incompatibility between clang and gcc (#2377).
|
// incompatibility between clang and gcc (#2377).
|
||||||
template FMT_API void vformat_to(buffer<char> &, string_view, basic_format_args<FMT_BUFFER_CONTEXT(char)>, locale_ref);
|
template FMT_API void
|
||||||
|
vformat_to(buffer<char> &, string_view, basic_format_args<FMT_BUFFER_CONTEXT(char)>, locale_ref);
|
||||||
|
|
||||||
// Explicit instantiations for wchar_t.
|
// Explicit instantiations for wchar_t.
|
||||||
|
|
||||||
|
@ -33,13 +33,17 @@ template class SPDLOG_API spdlog::sinks::ansicolor_stderr_sink<spdlog::details::
|
|||||||
// factory methods for color loggers
|
// factory methods for color loggers
|
||||||
#include "spdlog/sinks/stdout_color_sinks-inl.h"
|
#include "spdlog/sinks/stdout_color_sinks-inl.h"
|
||||||
template SPDLOG_API std::shared_ptr<spdlog::logger>
|
template SPDLOG_API std::shared_ptr<spdlog::logger>
|
||||||
spdlog::stdout_color_mt<spdlog::synchronous_factory>(const std::string &logger_name, color_mode mode);
|
spdlog::stdout_color_mt<spdlog::synchronous_factory>(const std::string &logger_name,
|
||||||
|
color_mode mode);
|
||||||
template SPDLOG_API std::shared_ptr<spdlog::logger>
|
template SPDLOG_API std::shared_ptr<spdlog::logger>
|
||||||
spdlog::stdout_color_st<spdlog::synchronous_factory>(const std::string &logger_name, color_mode mode);
|
spdlog::stdout_color_st<spdlog::synchronous_factory>(const std::string &logger_name,
|
||||||
|
color_mode mode);
|
||||||
template SPDLOG_API std::shared_ptr<spdlog::logger>
|
template SPDLOG_API std::shared_ptr<spdlog::logger>
|
||||||
spdlog::stderr_color_mt<spdlog::synchronous_factory>(const std::string &logger_name, color_mode mode);
|
spdlog::stderr_color_mt<spdlog::synchronous_factory>(const std::string &logger_name,
|
||||||
|
color_mode mode);
|
||||||
template SPDLOG_API std::shared_ptr<spdlog::logger>
|
template SPDLOG_API std::shared_ptr<spdlog::logger>
|
||||||
spdlog::stderr_color_st<spdlog::synchronous_factory>(const std::string &logger_name, color_mode mode);
|
spdlog::stderr_color_st<spdlog::synchronous_factory>(const std::string &logger_name,
|
||||||
|
color_mode mode);
|
||||||
|
|
||||||
template SPDLOG_API std::shared_ptr<spdlog::logger>
|
template SPDLOG_API std::shared_ptr<spdlog::logger>
|
||||||
spdlog::stdout_color_mt<spdlog::async_factory>(const std::string &logger_name, color_mode mode);
|
spdlog::stdout_color_mt<spdlog::async_factory>(const std::string &logger_name, color_mode mode);
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
// template instantiate logger constructor with sinks init list
|
// template instantiate logger constructor with sinks init list
|
||||||
template SPDLOG_API
|
template SPDLOG_API spdlog::logger::logger(std::string name,
|
||||||
spdlog::logger::logger(std::string name, sinks_init_list::iterator begin, sinks_init_list::iterator end);
|
sinks_init_list::iterator begin,
|
||||||
|
sinks_init_list::iterator end);
|
||||||
template class SPDLOG_API spdlog::sinks::base_sink<std::mutex>;
|
template class SPDLOG_API spdlog::sinks::base_sink<std::mutex>;
|
||||||
template class SPDLOG_API spdlog::sinks::base_sink<spdlog::details::null_mutex>;
|
template class SPDLOG_API spdlog::sinks::base_sink<spdlog::details::null_mutex>;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ == 12
|
#if defined(__GNUC__) && __GNUC__ == 12
|
||||||
# pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // Workaround for GCC 12
|
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // Workaround for GCC 12
|
||||||
#endif
|
#endif
|
||||||
#include <catch2/catch_all.hpp>
|
#include <catch2/catch_all.hpp>
|
||||||
#if defined(__GNUC__) && __GNUC__ == 12
|
#if defined(__GNUC__) && __GNUC__ == 12
|
||||||
# pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#if defined(__GNUC__) && __GNUC__ == 12
|
#if defined(__GNUC__) && __GNUC__ == 12
|
||||||
# pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // Workaround for GCC 12
|
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // Workaround for GCC 12
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <catch2/catch_all.hpp>
|
#include <catch2/catch_all.hpp>
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ == 12
|
#if defined(__GNUC__) && __GNUC__ == 12
|
||||||
# pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,17 +5,16 @@
|
|||||||
|
|
||||||
#define TEST_FILENAME "test_logs/async_test.log"
|
#define TEST_FILENAME "test_logs/async_test.log"
|
||||||
|
|
||||||
TEST_CASE("basic async test ", "[async]")
|
TEST_CASE("basic async test ", "[async]") {
|
||||||
{
|
|
||||||
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
size_t overrun_counter = 0;
|
size_t overrun_counter = 0;
|
||||||
size_t queue_size = 128;
|
size_t queue_size = 128;
|
||||||
size_t messages = 256;
|
size_t messages = 256;
|
||||||
{
|
{
|
||||||
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
||||||
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::block);
|
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp,
|
||||||
for (size_t i = 0; i < messages; i++)
|
spdlog::async_overflow_policy::block);
|
||||||
{
|
for (size_t i = 0; i < messages; i++) {
|
||||||
logger->info("Hello message #{}", i);
|
logger->info("Hello message #{}", i);
|
||||||
}
|
}
|
||||||
logger->flush();
|
logger->flush();
|
||||||
@ -26,42 +25,39 @@ TEST_CASE("basic async test ", "[async]")
|
|||||||
REQUIRE(overrun_counter == 0);
|
REQUIRE(overrun_counter == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("discard policy ", "[async]")
|
TEST_CASE("discard policy ", "[async]") {
|
||||||
{
|
|
||||||
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
test_sink->set_delay(std::chrono::milliseconds(1));
|
test_sink->set_delay(std::chrono::milliseconds(1));
|
||||||
size_t queue_size = 4;
|
size_t queue_size = 4;
|
||||||
size_t messages = 1024;
|
size_t messages = 1024;
|
||||||
|
|
||||||
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
||||||
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::overrun_oldest);
|
auto logger = std::make_shared<spdlog::async_logger>(
|
||||||
for (size_t i = 0; i < messages; i++)
|
"as", test_sink, tp, spdlog::async_overflow_policy::overrun_oldest);
|
||||||
{
|
for (size_t i = 0; i < messages; i++) {
|
||||||
logger->info("Hello message");
|
logger->info("Hello message");
|
||||||
}
|
}
|
||||||
REQUIRE(test_sink->msg_counter() < messages);
|
REQUIRE(test_sink->msg_counter() < messages);
|
||||||
REQUIRE(tp->overrun_counter() > 0);
|
REQUIRE(tp->overrun_counter() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("discard policy discard_new ", "[async]")
|
TEST_CASE("discard policy discard_new ", "[async]") {
|
||||||
{
|
|
||||||
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
test_sink->set_delay(std::chrono::milliseconds(1));
|
test_sink->set_delay(std::chrono::milliseconds(1));
|
||||||
size_t queue_size = 4;
|
size_t queue_size = 4;
|
||||||
size_t messages = 1024;
|
size_t messages = 1024;
|
||||||
|
|
||||||
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
||||||
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::discard_new);
|
auto logger = std::make_shared<spdlog::async_logger>(
|
||||||
for (size_t i = 0; i < messages; i++)
|
"as", test_sink, tp, spdlog::async_overflow_policy::discard_new);
|
||||||
{
|
for (size_t i = 0; i < messages; i++) {
|
||||||
logger->info("Hello message");
|
logger->info("Hello message");
|
||||||
}
|
}
|
||||||
REQUIRE(test_sink->msg_counter() < messages);
|
REQUIRE(test_sink->msg_counter() < messages);
|
||||||
REQUIRE(tp->discard_counter() > 0);
|
REQUIRE(tp->discard_counter() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("discard policy using factory ", "[async]")
|
TEST_CASE("discard policy using factory ", "[async]") {
|
||||||
{
|
|
||||||
size_t queue_size = 4;
|
size_t queue_size = 4;
|
||||||
size_t messages = 1024;
|
size_t messages = 1024;
|
||||||
spdlog::init_thread_pool(queue_size, 1);
|
spdlog::init_thread_pool(queue_size, 1);
|
||||||
@ -70,8 +66,7 @@ TEST_CASE("discard policy using factory ", "[async]")
|
|||||||
auto test_sink = std::static_pointer_cast<spdlog::sinks::test_sink_mt>(logger->sinks()[0]);
|
auto test_sink = std::static_pointer_cast<spdlog::sinks::test_sink_mt>(logger->sinks()[0]);
|
||||||
test_sink->set_delay(std::chrono::milliseconds(3));
|
test_sink->set_delay(std::chrono::milliseconds(3));
|
||||||
|
|
||||||
for (size_t i = 0; i < messages; i++)
|
for (size_t i = 0; i < messages; i++) {
|
||||||
{
|
|
||||||
logger->info("Hello message");
|
logger->info("Hello message");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,16 +74,15 @@ TEST_CASE("discard policy using factory ", "[async]")
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("flush", "[async]")
|
TEST_CASE("flush", "[async]") {
|
||||||
{
|
|
||||||
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
size_t queue_size = 256;
|
size_t queue_size = 256;
|
||||||
size_t messages = 256;
|
size_t messages = 256;
|
||||||
{
|
{
|
||||||
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
||||||
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::block);
|
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp,
|
||||||
for (size_t i = 0; i < messages; i++)
|
spdlog::async_overflow_policy::block);
|
||||||
{
|
for (size_t i = 0; i < messages; i++) {
|
||||||
logger->info("Hello message #{}", i);
|
logger->info("Hello message #{}", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +93,7 @@ TEST_CASE("flush", "[async]")
|
|||||||
REQUIRE(test_sink->flush_counter() == 1);
|
REQUIRE(test_sink->flush_counter() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("async periodic flush", "[async]")
|
TEST_CASE("async periodic flush", "[async]") {
|
||||||
{
|
|
||||||
|
|
||||||
auto logger = spdlog::create_async<spdlog::sinks::test_sink_mt>("as");
|
auto logger = spdlog::create_async<spdlog::sinks::test_sink_mt>("as");
|
||||||
auto test_sink = std::static_pointer_cast<spdlog::sinks::test_sink_mt>(logger->sinks()[0]);
|
auto test_sink = std::static_pointer_cast<spdlog::sinks::test_sink_mt>(logger->sinks()[0]);
|
||||||
@ -112,16 +105,15 @@ TEST_CASE("async periodic flush", "[async]")
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("tp->wait_empty() ", "[async]")
|
TEST_CASE("tp->wait_empty() ", "[async]") {
|
||||||
{
|
|
||||||
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
test_sink->set_delay(std::chrono::milliseconds(5));
|
test_sink->set_delay(std::chrono::milliseconds(5));
|
||||||
size_t messages = 100;
|
size_t messages = 100;
|
||||||
|
|
||||||
auto tp = std::make_shared<spdlog::details::thread_pool>(messages, 2);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(messages, 2);
|
||||||
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::block);
|
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp,
|
||||||
for (size_t i = 0; i < messages; i++)
|
spdlog::async_overflow_policy::block);
|
||||||
{
|
for (size_t i = 0; i < messages; i++) {
|
||||||
logger->info("Hello message #{}", i);
|
logger->info("Hello message #{}", i);
|
||||||
}
|
}
|
||||||
logger->flush();
|
logger->flush();
|
||||||
@ -131,30 +123,27 @@ TEST_CASE("tp->wait_empty() ", "[async]")
|
|||||||
REQUIRE(test_sink->flush_counter() == 1);
|
REQUIRE(test_sink->flush_counter() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("multi threads", "[async]")
|
TEST_CASE("multi threads", "[async]") {
|
||||||
{
|
|
||||||
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
size_t queue_size = 128;
|
size_t queue_size = 128;
|
||||||
size_t messages = 256;
|
size_t messages = 256;
|
||||||
size_t n_threads = 10;
|
size_t n_threads = 10;
|
||||||
{
|
{
|
||||||
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
||||||
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::block);
|
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp,
|
||||||
|
spdlog::async_overflow_policy::block);
|
||||||
|
|
||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> threads;
|
||||||
for (size_t i = 0; i < n_threads; i++)
|
for (size_t i = 0; i < n_threads; i++) {
|
||||||
{
|
|
||||||
threads.emplace_back([logger, messages] {
|
threads.emplace_back([logger, messages] {
|
||||||
for (size_t j = 0; j < messages; j++)
|
for (size_t j = 0; j < messages; j++) {
|
||||||
{
|
|
||||||
logger->info("Hello message #{}", j);
|
logger->info("Hello message #{}", j);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
logger->flush();
|
logger->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &t : threads)
|
for (auto &t : threads) {
|
||||||
{
|
|
||||||
t.join();
|
t.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,8 +152,7 @@ TEST_CASE("multi threads", "[async]")
|
|||||||
REQUIRE(test_sink->flush_counter() == n_threads);
|
REQUIRE(test_sink->flush_counter() == n_threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("to_file", "[async]")
|
TEST_CASE("to_file", "[async]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
size_t messages = 1024;
|
size_t messages = 1024;
|
||||||
size_t tp_threads = 1;
|
size_t tp_threads = 1;
|
||||||
@ -172,10 +160,10 @@ TEST_CASE("to_file", "[async]")
|
|||||||
{
|
{
|
||||||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
|
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
|
||||||
auto tp = std::make_shared<spdlog::details::thread_pool>(messages, tp_threads);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(messages, tp_threads);
|
||||||
auto logger = std::make_shared<spdlog::async_logger>("as", std::move(file_sink), std::move(tp));
|
auto logger =
|
||||||
|
std::make_shared<spdlog::async_logger>("as", std::move(file_sink), std::move(tp));
|
||||||
|
|
||||||
for (size_t j = 0; j < messages; j++)
|
for (size_t j = 0; j < messages; j++) {
|
||||||
{
|
|
||||||
logger->info("Hello message #{}", j);
|
logger->info("Hello message #{}", j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,8 +174,7 @@ TEST_CASE("to_file", "[async]")
|
|||||||
REQUIRE(ends_with(contents, spdlog::fmt_lib::format("Hello message #1023{}", default_eol)));
|
REQUIRE(ends_with(contents, spdlog::fmt_lib::format("Hello message #1023{}", default_eol)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("to_file multi-workers", "[async]")
|
TEST_CASE("to_file multi-workers", "[async]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
size_t messages = 1024 * 10;
|
size_t messages = 1024 * 10;
|
||||||
size_t tp_threads = 10;
|
size_t tp_threads = 10;
|
||||||
@ -195,18 +182,17 @@ TEST_CASE("to_file multi-workers", "[async]")
|
|||||||
{
|
{
|
||||||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
|
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
|
||||||
auto tp = std::make_shared<spdlog::details::thread_pool>(messages, tp_threads);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(messages, tp_threads);
|
||||||
auto logger = std::make_shared<spdlog::async_logger>("as", std::move(file_sink), std::move(tp));
|
auto logger =
|
||||||
|
std::make_shared<spdlog::async_logger>("as", std::move(file_sink), std::move(tp));
|
||||||
|
|
||||||
for (size_t j = 0; j < messages; j++)
|
for (size_t j = 0; j < messages; j++) {
|
||||||
{
|
|
||||||
logger->info("Hello message #{}", j);
|
logger->info("Hello message #{}", j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
require_message_count(TEST_FILENAME, messages);
|
require_message_count(TEST_FILENAME, messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("bad_tp", "[async]")
|
TEST_CASE("bad_tp", "[async]") {
|
||||||
{
|
|
||||||
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
std::shared_ptr<spdlog::details::thread_pool> const empty_tp;
|
std::shared_ptr<spdlog::details::thread_pool> const empty_tp;
|
||||||
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, empty_tp);
|
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, empty_tp);
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
#include "test_sink.h"
|
#include "test_sink.h"
|
||||||
#include "spdlog/async.h"
|
#include "spdlog/async.h"
|
||||||
|
|
||||||
TEST_CASE("bactrace1", "[bactrace]")
|
TEST_CASE("bactrace1", "[bactrace]") {
|
||||||
{
|
|
||||||
|
|
||||||
using spdlog::sinks::test_sink_st;
|
using spdlog::sinks::test_sink_st;
|
||||||
auto test_sink = std::make_shared<test_sink_st>();
|
auto test_sink = std::make_shared<test_sink_st>();
|
||||||
@ -31,8 +30,7 @@ TEST_CASE("bactrace1", "[bactrace]")
|
|||||||
REQUIRE(test_sink->lines()[7] == "****************** Backtrace End ********************");
|
REQUIRE(test_sink->lines()[7] == "****************** Backtrace End ********************");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("bactrace-empty", "[bactrace]")
|
TEST_CASE("bactrace-empty", "[bactrace]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::test_sink_st;
|
using spdlog::sinks::test_sink_st;
|
||||||
auto test_sink = std::make_shared<test_sink_st>();
|
auto test_sink = std::make_shared<test_sink_st>();
|
||||||
size_t backtrace_size = 5;
|
size_t backtrace_size = 5;
|
||||||
@ -44,8 +42,7 @@ TEST_CASE("bactrace-empty", "[bactrace]")
|
|||||||
REQUIRE(test_sink->lines().size() == 0);
|
REQUIRE(test_sink->lines().size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("bactrace-async", "[bactrace]")
|
TEST_CASE("bactrace-async", "[bactrace]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::test_sink_mt;
|
using spdlog::sinks::test_sink_mt;
|
||||||
auto test_sink = std::make_shared<test_sink_mt>();
|
auto test_sink = std::make_shared<test_sink_mt>();
|
||||||
using spdlog::details::os::sleep_for_millis;
|
using spdlog::details::os::sleep_for_millis;
|
||||||
@ -53,7 +50,8 @@ TEST_CASE("bactrace-async", "[bactrace]")
|
|||||||
size_t backtrace_size = 5;
|
size_t backtrace_size = 5;
|
||||||
|
|
||||||
spdlog::init_thread_pool(120, 1);
|
spdlog::init_thread_pool(120, 1);
|
||||||
auto logger = std::make_shared<spdlog::async_logger>("test-bactrace-async", test_sink, spdlog::thread_pool());
|
auto logger = std::make_shared<spdlog::async_logger>("test-bactrace-async", test_sink,
|
||||||
|
spdlog::thread_pool());
|
||||||
logger->set_pattern("%v");
|
logger->set_pattern("%v");
|
||||||
logger->enable_backtrace(backtrace_size);
|
logger->enable_backtrace(backtrace_size);
|
||||||
|
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
#include "test_sink.h"
|
#include "test_sink.h"
|
||||||
#include "spdlog/fmt/bin_to_hex.h"
|
#include "spdlog/fmt/bin_to_hex.h"
|
||||||
|
|
||||||
TEST_CASE("to_hex", "[to_hex]")
|
TEST_CASE("to_hex", "[to_hex]") {
|
||||||
{
|
|
||||||
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("oss", oss_sink);
|
spdlog::logger oss_logger("oss", oss_sink);
|
||||||
@ -12,11 +11,11 @@ TEST_CASE("to_hex", "[to_hex]")
|
|||||||
oss_logger.info("{}", spdlog::to_hex(v));
|
oss_logger.info("{}", spdlog::to_hex(v));
|
||||||
|
|
||||||
auto output = oss.str();
|
auto output = oss.str();
|
||||||
REQUIRE(ends_with(output, "0000: 09 0a 0b 0c ff ff" + std::string(spdlog::details::os::default_eol)));
|
REQUIRE(ends_with(output,
|
||||||
|
"0000: 09 0a 0b 0c ff ff" + std::string(spdlog::details::os::default_eol)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("to_hex_upper", "[to_hex]")
|
TEST_CASE("to_hex_upper", "[to_hex]") {
|
||||||
{
|
|
||||||
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("oss", oss_sink);
|
spdlog::logger oss_logger("oss", oss_sink);
|
||||||
@ -25,11 +24,11 @@ TEST_CASE("to_hex_upper", "[to_hex]")
|
|||||||
oss_logger.info("{:X}", spdlog::to_hex(v));
|
oss_logger.info("{:X}", spdlog::to_hex(v));
|
||||||
|
|
||||||
auto output = oss.str();
|
auto output = oss.str();
|
||||||
REQUIRE(ends_with(output, "0000: 09 0A 0B 0C FF FF" + std::string(spdlog::details::os::default_eol)));
|
REQUIRE(ends_with(output,
|
||||||
|
"0000: 09 0A 0B 0C FF FF" + std::string(spdlog::details::os::default_eol)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("to_hex_no_delimiter", "[to_hex]")
|
TEST_CASE("to_hex_no_delimiter", "[to_hex]") {
|
||||||
{
|
|
||||||
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("oss", oss_sink);
|
spdlog::logger oss_logger("oss", oss_sink);
|
||||||
@ -38,11 +37,11 @@ TEST_CASE("to_hex_no_delimiter", "[to_hex]")
|
|||||||
oss_logger.info("{:sX}", spdlog::to_hex(v));
|
oss_logger.info("{:sX}", spdlog::to_hex(v));
|
||||||
|
|
||||||
auto output = oss.str();
|
auto output = oss.str();
|
||||||
REQUIRE(ends_with(output, "0000: 090A0B0CFFFF" + std::string(spdlog::details::os::default_eol)));
|
REQUIRE(
|
||||||
|
ends_with(output, "0000: 090A0B0CFFFF" + std::string(spdlog::details::os::default_eol)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("to_hex_show_ascii", "[to_hex]")
|
TEST_CASE("to_hex_show_ascii", "[to_hex]") {
|
||||||
{
|
|
||||||
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("oss", oss_sink);
|
spdlog::logger oss_logger("oss", oss_sink);
|
||||||
@ -50,11 +49,11 @@ TEST_CASE("to_hex_show_ascii", "[to_hex]")
|
|||||||
std::vector<unsigned char> v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff};
|
std::vector<unsigned char> v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff};
|
||||||
oss_logger.info("{:Xsa}", spdlog::to_hex(v, 8));
|
oss_logger.info("{:Xsa}", spdlog::to_hex(v, 8));
|
||||||
|
|
||||||
REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF ...A.K.." + std::string(spdlog::details::os::default_eol)));
|
REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF ...A.K.." +
|
||||||
|
std::string(spdlog::details::os::default_eol)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("to_hex_different_size_per_line", "[to_hex]")
|
TEST_CASE("to_hex_different_size_per_line", "[to_hex]") {
|
||||||
{
|
|
||||||
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("oss", oss_sink);
|
spdlog::logger oss_logger("oss", oss_sink);
|
||||||
@ -62,22 +61,25 @@ TEST_CASE("to_hex_different_size_per_line", "[to_hex]")
|
|||||||
std::vector<unsigned char> v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff};
|
std::vector<unsigned char> v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff};
|
||||||
|
|
||||||
oss_logger.info("{:Xsa}", spdlog::to_hex(v, 10));
|
oss_logger.info("{:Xsa}", spdlog::to_hex(v, 10));
|
||||||
REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF ...A.K.." + std::string(spdlog::details::os::default_eol)));
|
REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF ...A.K.." +
|
||||||
|
|
||||||
oss_logger.info("{:Xs}", spdlog::to_hex(v, 10));
|
|
||||||
REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol)));
|
|
||||||
|
|
||||||
oss_logger.info("{:Xsa}", spdlog::to_hex(v, 6));
|
|
||||||
REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4B ...A.K" + std::string(spdlog::details::os::default_eol) + "0006: FFFF .." +
|
|
||||||
std::string(spdlog::details::os::default_eol)));
|
std::string(spdlog::details::os::default_eol)));
|
||||||
|
|
||||||
|
oss_logger.info("{:Xs}", spdlog::to_hex(v, 10));
|
||||||
|
REQUIRE(ends_with(oss.str(),
|
||||||
|
"0000: 090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol)));
|
||||||
|
|
||||||
|
oss_logger.info("{:Xsa}", spdlog::to_hex(v, 6));
|
||||||
|
REQUIRE(ends_with(
|
||||||
|
oss.str(), "0000: 090A0B410C4B ...A.K" + std::string(spdlog::details::os::default_eol) +
|
||||||
|
"0006: FFFF .." + std::string(spdlog::details::os::default_eol)));
|
||||||
|
|
||||||
oss_logger.info("{:Xs}", spdlog::to_hex(v, 6));
|
oss_logger.info("{:Xs}", spdlog::to_hex(v, 6));
|
||||||
REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4B" + std::string(spdlog::details::os::default_eol) + "0006: FFFF" +
|
REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4B" +
|
||||||
|
std::string(spdlog::details::os::default_eol) + "0006: FFFF" +
|
||||||
std::string(spdlog::details::os::default_eol)));
|
std::string(spdlog::details::os::default_eol)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("to_hex_no_ascii", "[to_hex]")
|
TEST_CASE("to_hex_no_ascii", "[to_hex]") {
|
||||||
{
|
|
||||||
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("oss", oss_sink);
|
spdlog::logger oss_logger("oss", oss_sink);
|
||||||
@ -85,9 +87,11 @@ TEST_CASE("to_hex_no_ascii", "[to_hex]")
|
|||||||
std::vector<unsigned char> v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff};
|
std::vector<unsigned char> v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff};
|
||||||
oss_logger.info("{:Xs}", spdlog::to_hex(v, 8));
|
oss_logger.info("{:Xs}", spdlog::to_hex(v, 8));
|
||||||
|
|
||||||
REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol)));
|
REQUIRE(ends_with(oss.str(),
|
||||||
|
"0000: 090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol)));
|
||||||
|
|
||||||
oss_logger.info("{:Xsna}", spdlog::to_hex(v, 8));
|
oss_logger.info("{:Xsna}", spdlog::to_hex(v, 8));
|
||||||
|
|
||||||
REQUIRE(ends_with(oss.str(), "090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol)));
|
REQUIRE(
|
||||||
|
ends_with(oss.str(), "090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol)));
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,7 @@ using spdlog::cfg::load_argv_levels;
|
|||||||
using spdlog::cfg::load_env_levels;
|
using spdlog::cfg::load_env_levels;
|
||||||
using spdlog::sinks::test_sink_st;
|
using spdlog::sinks::test_sink_st;
|
||||||
|
|
||||||
TEST_CASE("env", "[cfg]")
|
TEST_CASE("env", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
auto l1 = spdlog::create<test_sink_st>("l1");
|
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||||
#ifdef CATCH_PLATFORM_WINDOWS
|
#ifdef CATCH_PLATFORM_WINDOWS
|
||||||
@ -24,8 +23,7 @@ TEST_CASE("env", "[cfg]")
|
|||||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("argv1", "[cfg]")
|
TEST_CASE("argv1", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn"};
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn"};
|
||||||
load_argv_levels(2, argv);
|
load_argv_levels(2, argv);
|
||||||
@ -34,8 +32,7 @@ TEST_CASE("argv1", "[cfg]")
|
|||||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("argv2", "[cfg]")
|
TEST_CASE("argv2", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn,trace"};
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn,trace"};
|
||||||
load_argv_levels(2, argv);
|
load_argv_levels(2, argv);
|
||||||
@ -44,8 +41,7 @@ TEST_CASE("argv2", "[cfg]")
|
|||||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("argv3", "[cfg]")
|
TEST_CASE("argv3", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::set_level(spdlog::level::trace);
|
spdlog::set_level(spdlog::level::trace);
|
||||||
|
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
@ -56,8 +52,7 @@ TEST_CASE("argv3", "[cfg]")
|
|||||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("argv4", "[cfg]")
|
TEST_CASE("argv4", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::set_level(spdlog::level::info);
|
spdlog::set_level(spdlog::level::info);
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk"};
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk"};
|
||||||
@ -66,8 +61,7 @@ TEST_CASE("argv4", "[cfg]")
|
|||||||
REQUIRE(l1->level() == spdlog::level::info);
|
REQUIRE(l1->level() == spdlog::level::info);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("argv5", "[cfg]")
|
TEST_CASE("argv5", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::set_level(spdlog::level::info);
|
spdlog::set_level(spdlog::level::info);
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
const char *argv[] = {"ignore", "ignore", "SPDLOG_LEVEL=l1=warn,trace"};
|
const char *argv[] = {"ignore", "ignore", "SPDLOG_LEVEL=l1=warn,trace"};
|
||||||
@ -78,8 +72,7 @@ TEST_CASE("argv5", "[cfg]")
|
|||||||
spdlog::set_level(spdlog::level::info);
|
spdlog::set_level(spdlog::level::info);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("argv6", "[cfg]")
|
TEST_CASE("argv6", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::set_level(spdlog::level::err);
|
spdlog::set_level(spdlog::level::err);
|
||||||
const char *argv[] = {""};
|
const char *argv[] = {""};
|
||||||
load_argv_levels(1, argv);
|
load_argv_levels(1, argv);
|
||||||
@ -87,8 +80,7 @@ TEST_CASE("argv6", "[cfg]")
|
|||||||
spdlog::set_level(spdlog::level::info);
|
spdlog::set_level(spdlog::level::info);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("argv7", "[cfg]")
|
TEST_CASE("argv7", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::set_level(spdlog::level::err);
|
spdlog::set_level(spdlog::level::err);
|
||||||
const char *argv[] = {""};
|
const char *argv[] = {""};
|
||||||
load_argv_levels(0, argv);
|
load_argv_levels(0, argv);
|
||||||
@ -96,8 +88,7 @@ TEST_CASE("argv7", "[cfg]")
|
|||||||
spdlog::set_level(spdlog::level::info);
|
spdlog::set_level(spdlog::level::info);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("level-not-set-test1", "[cfg]")
|
TEST_CASE("level-not-set-test1", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
const char *argv[] = {"ignore", ""};
|
const char *argv[] = {"ignore", ""};
|
||||||
load_argv_levels(2, argv);
|
load_argv_levels(2, argv);
|
||||||
@ -107,8 +98,7 @@ TEST_CASE("level-not-set-test1", "[cfg]")
|
|||||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("level-not-set-test2", "[cfg]")
|
TEST_CASE("level-not-set-test2", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
spdlog::drop("l2");
|
spdlog::drop("l2");
|
||||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace"};
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace"};
|
||||||
@ -125,8 +115,7 @@ TEST_CASE("level-not-set-test2", "[cfg]")
|
|||||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("level-not-set-test3", "[cfg]")
|
TEST_CASE("level-not-set-test3", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
spdlog::drop("l2");
|
spdlog::drop("l2");
|
||||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace"};
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace"};
|
||||||
@ -141,8 +130,7 @@ TEST_CASE("level-not-set-test3", "[cfg]")
|
|||||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("level-not-set-test4", "[cfg]")
|
TEST_CASE("level-not-set-test4", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
spdlog::drop("l2");
|
spdlog::drop("l2");
|
||||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace,warn"};
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace,warn"};
|
||||||
@ -157,8 +145,7 @@ TEST_CASE("level-not-set-test4", "[cfg]")
|
|||||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::warn);
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::warn);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("level-not-set-test5", "[cfg]")
|
TEST_CASE("level-not-set-test5", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
spdlog::drop("l2");
|
spdlog::drop("l2");
|
||||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=junk,warn"};
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=junk,warn"};
|
||||||
@ -173,8 +160,7 @@ TEST_CASE("level-not-set-test5", "[cfg]")
|
|||||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::warn);
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::warn);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("restore-to-default", "[cfg]")
|
TEST_CASE("restore-to-default", "[cfg]") {
|
||||||
{
|
|
||||||
spdlog::drop("l1");
|
spdlog::drop("l1");
|
||||||
spdlog::drop("l2");
|
spdlog::drop("l2");
|
||||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=info"};
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=info"};
|
||||||
|
@ -2,14 +2,12 @@
|
|||||||
#include "spdlog/details/circular_q.h"
|
#include "spdlog/details/circular_q.h"
|
||||||
|
|
||||||
using q_type = spdlog::details::circular_q<size_t>;
|
using q_type = spdlog::details::circular_q<size_t>;
|
||||||
TEST_CASE("test_size", "[circular_q]")
|
TEST_CASE("test_size", "[circular_q]") {
|
||||||
{
|
|
||||||
const size_t q_size = 4;
|
const size_t q_size = 4;
|
||||||
q_type q(q_size);
|
q_type q(q_size);
|
||||||
REQUIRE(q.size() == 0);
|
REQUIRE(q.size() == 0);
|
||||||
REQUIRE(q.empty() == true);
|
REQUIRE(q.empty() == true);
|
||||||
for (size_t i = 0; i < q_size; i++)
|
for (size_t i = 0; i < q_size; i++) {
|
||||||
{
|
|
||||||
q.push_back(std::move(i));
|
q.push_back(std::move(i));
|
||||||
}
|
}
|
||||||
REQUIRE(q.size() == q_size);
|
REQUIRE(q.size() == q_size);
|
||||||
@ -17,13 +15,11 @@ TEST_CASE("test_size", "[circular_q]")
|
|||||||
REQUIRE(q.size() == q_size);
|
REQUIRE(q.size() == q_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("test_rolling", "[circular_q]")
|
TEST_CASE("test_rolling", "[circular_q]") {
|
||||||
{
|
|
||||||
const size_t q_size = 4;
|
const size_t q_size = 4;
|
||||||
q_type q(q_size);
|
q_type q(q_size);
|
||||||
|
|
||||||
for (size_t i = 0; i < q_size + 2; i++)
|
for (size_t i = 0; i < q_size + 2; i++) {
|
||||||
{
|
|
||||||
q.push_back(std::move(i));
|
q.push_back(std::move(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,8 +43,7 @@ TEST_CASE("test_rolling", "[circular_q]")
|
|||||||
REQUIRE(q.front() == 6);
|
REQUIRE(q.front() == 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("test_empty", "[circular_q]")
|
TEST_CASE("test_empty", "[circular_q]") {
|
||||||
{
|
|
||||||
q_type q(0);
|
q_type q(0);
|
||||||
q.push_back(1);
|
q.push_back(1);
|
||||||
REQUIRE(q.empty());
|
REQUIRE(q.empty());
|
||||||
|
@ -1,40 +1,46 @@
|
|||||||
/*
|
/*
|
||||||
* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
* This content is released under the MIT License as specified in
|
||||||
|
* https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
using spdlog::details::os::create_dir;
|
using spdlog::details::os::create_dir;
|
||||||
using spdlog::details::os::path_exists;
|
using spdlog::details::os::path_exists;
|
||||||
|
|
||||||
bool try_create_dir(const spdlog::filename_t &path, const spdlog::filename_t &normalized_path)
|
bool try_create_dir(const spdlog::filename_t &path, const spdlog::filename_t &normalized_path) {
|
||||||
{
|
|
||||||
auto rv = create_dir(path);
|
auto rv = create_dir(path);
|
||||||
REQUIRE(rv == true);
|
REQUIRE(rv == true);
|
||||||
return path_exists(normalized_path);
|
return path_exists(normalized_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("create_dir", "[create_dir]")
|
TEST_CASE("create_dir", "[create_dir]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
|
|
||||||
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1/dir1"), SPDLOG_FILENAME_T("test_logs/dir1/dir1")));
|
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1/dir1"),
|
||||||
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1/dir1"), SPDLOG_FILENAME_T("test_logs/dir1/dir1"))); // test existing
|
SPDLOG_FILENAME_T("test_logs/dir1/dir1")));
|
||||||
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1///dir2//"), SPDLOG_FILENAME_T("test_logs/dir1/dir2")));
|
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1/dir1"),
|
||||||
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("./test_logs/dir1/dir3"), SPDLOG_FILENAME_T("test_logs/dir1/dir3")));
|
SPDLOG_FILENAME_T("test_logs/dir1/dir1"))); // test existing
|
||||||
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/../test_logs/dir1/dir4"), SPDLOG_FILENAME_T("test_logs/dir1/dir4")));
|
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1///dir2//"),
|
||||||
|
SPDLOG_FILENAME_T("test_logs/dir1/dir2")));
|
||||||
|
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("./test_logs/dir1/dir3"),
|
||||||
|
SPDLOG_FILENAME_T("test_logs/dir1/dir3")));
|
||||||
|
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/../test_logs/dir1/dir4"),
|
||||||
|
SPDLOG_FILENAME_T("test_logs/dir1/dir4")));
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// test backslash folder separator
|
// test backslash folder separator
|
||||||
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\dir1\\dir222"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir222")));
|
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\dir1\\dir222"),
|
||||||
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\dir1\\dir223\\"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir223\\")));
|
SPDLOG_FILENAME_T("test_logs\\dir1\\dir222")));
|
||||||
REQUIRE(
|
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\dir1\\dir223\\"),
|
||||||
try_create_dir(SPDLOG_FILENAME_T(".\\test_logs\\dir1\\dir2\\dir99\\..\\dir23"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir2\\dir23")));
|
SPDLOG_FILENAME_T("test_logs\\dir1\\dir223\\")));
|
||||||
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\..\\test_logs\\dir1\\dir5"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir5")));
|
REQUIRE(try_create_dir(SPDLOG_FILENAME_T(".\\test_logs\\dir1\\dir2\\dir99\\..\\dir23"),
|
||||||
|
SPDLOG_FILENAME_T("test_logs\\dir1\\dir2\\dir23")));
|
||||||
|
REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\..\\test_logs\\dir1\\dir5"),
|
||||||
|
SPDLOG_FILENAME_T("test_logs\\dir1\\dir5")));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("create_invalid_dir", "[create_dir]")
|
TEST_CASE("create_invalid_dir", "[create_dir]") {
|
||||||
{
|
|
||||||
REQUIRE(create_dir(SPDLOG_FILENAME_T("")) == false);
|
REQUIRE(create_dir(SPDLOG_FILENAME_T("")) == false);
|
||||||
REQUIRE(create_dir(spdlog::filename_t{}) == false);
|
REQUIRE(create_dir(spdlog::filename_t{}) == false);
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -42,8 +48,7 @@ TEST_CASE("create_invalid_dir", "[create_dir]")
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("dir_name", "[create_dir]")
|
TEST_CASE("dir_name", "[create_dir]") {
|
||||||
{
|
|
||||||
using spdlog::details::os::dir_name;
|
using spdlog::details::os::dir_name;
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T("")).empty());
|
REQUIRE(dir_name(SPDLOG_FILENAME_T("")).empty());
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T("dir")).empty());
|
REQUIRE(dir_name(SPDLOG_FILENAME_T("dir")).empty());
|
||||||
@ -55,13 +60,16 @@ TEST_CASE("dir_name", "[create_dir]")
|
|||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file)")) == SPDLOG_FILENAME_T("dir"));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file)")) == SPDLOG_FILENAME_T("dir"));
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file.txt)")) == SPDLOG_FILENAME_T("dir"));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file.txt)")) == SPDLOG_FILENAME_T("dir"));
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file)")) == SPDLOG_FILENAME_T("dir"));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file)")) == SPDLOG_FILENAME_T("dir"));
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file.txt\)")) == SPDLOG_FILENAME_T(R"(dir\file.txt)"));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file.txt\)")) ==
|
||||||
|
SPDLOG_FILENAME_T(R"(dir\file.txt)"));
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(\dir\file.txt)")) == SPDLOG_FILENAME_T(R"(\dir)"));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(\dir\file.txt)")) == SPDLOG_FILENAME_T(R"(\dir)"));
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(\\dir\file.txt)")) == SPDLOG_FILENAME_T(R"(\\dir)"));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(\\dir\file.txt)")) == SPDLOG_FILENAME_T(R"(\\dir)"));
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(..\file.txt)")) == SPDLOG_FILENAME_T(".."));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(..\file.txt)")) == SPDLOG_FILENAME_T(".."));
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(.\file.txt)")) == SPDLOG_FILENAME_T("."));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(.\file.txt)")) == SPDLOG_FILENAME_T("."));
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c:\\a\b\c\d\file.txt)")) == SPDLOG_FILENAME_T(R"(c:\\a\b\c\d)"));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c:\\a\b\c\d\file.txt)")) ==
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c://a/b/c/d/file.txt)")) == SPDLOG_FILENAME_T(R"(c://a/b/c/d)"));
|
SPDLOG_FILENAME_T(R"(c:\\a\b\c\d)"));
|
||||||
|
REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c://a/b/c/d/file.txt)")) ==
|
||||||
|
SPDLOG_FILENAME_T(R"(c://a/b/c/d)"));
|
||||||
#endif
|
#endif
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T("dir/")) == SPDLOG_FILENAME_T("dir"));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T("dir/")) == SPDLOG_FILENAME_T("dir"));
|
||||||
REQUIRE(dir_name(SPDLOG_FILENAME_T("dir///")) == SPDLOG_FILENAME_T("dir//"));
|
REQUIRE(dir_name(SPDLOG_FILENAME_T("dir///")) == SPDLOG_FILENAME_T("dir//"));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
* This content is released under the MIT License as specified in
|
||||||
|
* https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "test_sink.h"
|
#include "test_sink.h"
|
||||||
@ -7,16 +8,16 @@
|
|||||||
#include "spdlog/async.h"
|
#include "spdlog/async.h"
|
||||||
#include "spdlog/common.h"
|
#include "spdlog/common.h"
|
||||||
|
|
||||||
TEST_CASE("custom_callback_logger", "[custom_callback_logger]")
|
TEST_CASE("custom_callback_logger", "[custom_callback_logger]") {
|
||||||
{
|
|
||||||
std::vector<std::string> lines;
|
std::vector<std::string> lines;
|
||||||
spdlog::pattern_formatter formatter;
|
spdlog::pattern_formatter formatter;
|
||||||
auto callback_logger = std::make_shared<spdlog::sinks::callback_sink_st>([&](const spdlog::details::log_msg &msg) {
|
auto callback_logger =
|
||||||
spdlog::memory_buf_t formatted;
|
std::make_shared<spdlog::sinks::callback_sink_st>([&](const spdlog::details::log_msg &msg) {
|
||||||
formatter.format(msg, formatted);
|
spdlog::memory_buf_t formatted;
|
||||||
auto eol_len = strlen(spdlog::details::os::default_eol);
|
formatter.format(msg, formatted);
|
||||||
lines.emplace_back(formatted.begin(), formatted.end() - eol_len);
|
auto eol_len = strlen(spdlog::details::os::default_eol);
|
||||||
});
|
lines.emplace_back(formatted.begin(), formatted.end() - eol_len);
|
||||||
|
});
|
||||||
std::shared_ptr<spdlog::sinks::test_sink_st> test_sink(new spdlog::sinks::test_sink_st);
|
std::shared_ptr<spdlog::sinks::test_sink_st> test_sink(new spdlog::sinks::test_sink_st);
|
||||||
|
|
||||||
spdlog::logger logger("test-callback", {callback_logger, test_sink});
|
spdlog::logger logger("test-callback", {callback_logger, test_sink});
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
* This content is released under the MIT License as specified in
|
||||||
|
* https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
@ -10,22 +11,20 @@ using filename_memory_buf_t = fmt::basic_memory_buffer<spdlog::filename_t::value
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SPDLOG_WCHAR_FILENAMES
|
#ifdef SPDLOG_WCHAR_FILENAMES
|
||||||
std::string filename_buf_to_utf8string(const filename_memory_buf_t &w)
|
std::string filename_buf_to_utf8string(const filename_memory_buf_t &w) {
|
||||||
{
|
|
||||||
spdlog::memory_buf_t buf;
|
spdlog::memory_buf_t buf;
|
||||||
spdlog::details::os::wstr_to_utf8buf(spdlog::wstring_view_t(w.data(), w.size()), buf);
|
spdlog::details::os::wstr_to_utf8buf(spdlog::wstring_view_t(w.data(), w.size()), buf);
|
||||||
return SPDLOG_BUF_TO_STRING(buf);
|
return SPDLOG_BUF_TO_STRING(buf);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
std::string filename_buf_to_utf8string(const filename_memory_buf_t &w)
|
std::string filename_buf_to_utf8string(const filename_memory_buf_t &w) {
|
||||||
{
|
|
||||||
return SPDLOG_BUF_TO_STRING(w);
|
return SPDLOG_BUF_TO_STRING(w);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]")
|
TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]") {
|
||||||
{
|
using sink_type =
|
||||||
using sink_type = spdlog::sinks::daily_file_sink<std::mutex, spdlog::sinks::daily_filename_calculator>;
|
spdlog::sinks::daily_file_sink<std::mutex, spdlog::sinks::daily_filename_calculator>;
|
||||||
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
|
|
||||||
@ -33,12 +32,11 @@ TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]")
|
|||||||
spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly");
|
spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly");
|
||||||
std::tm tm = spdlog::details::os::localtime();
|
std::tm tm = spdlog::details::os::localtime();
|
||||||
filename_memory_buf_t w;
|
filename_memory_buf_t w;
|
||||||
spdlog::fmt_lib::format_to(
|
spdlog::fmt_lib::format_to(std::back_inserter(w), SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}"),
|
||||||
std::back_inserter(w), SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
|
basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
|
||||||
|
|
||||||
auto logger = spdlog::create<sink_type>("logger", basename, 0, 0);
|
auto logger = spdlog::create<sink_type>("logger", basename, 0, 0);
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i) {
|
||||||
{
|
|
||||||
|
|
||||||
logger->info("Test message {}", i);
|
logger->info("Test message {}", i);
|
||||||
}
|
}
|
||||||
@ -47,20 +45,18 @@ TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]")
|
|||||||
require_message_count(filename_buf_to_utf8string(w), 10);
|
require_message_count(filename_buf_to_utf8string(w), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct custom_daily_file_name_calculator
|
struct custom_daily_file_name_calculator {
|
||||||
{
|
static spdlog::filename_t calc_filename(const spdlog::filename_t &basename, const tm &now_tm) {
|
||||||
static spdlog::filename_t calc_filename(const spdlog::filename_t &basename, const tm &now_tm)
|
|
||||||
{
|
|
||||||
filename_memory_buf_t w;
|
filename_memory_buf_t w;
|
||||||
spdlog::fmt_lib::format_to(std::back_inserter(w), SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename, now_tm.tm_year + 1900,
|
spdlog::fmt_lib::format_to(std::back_inserter(w), SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"),
|
||||||
now_tm.tm_mon + 1, now_tm.tm_mday);
|
basename, now_tm.tm_year + 1900, now_tm.tm_mon + 1,
|
||||||
|
now_tm.tm_mday);
|
||||||
|
|
||||||
return SPDLOG_BUF_TO_STRING(w);
|
return SPDLOG_BUF_TO_STRING(w);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE("daily_logger with custom calculator", "[daily_logger]")
|
TEST_CASE("daily_logger with custom calculator", "[daily_logger]") {
|
||||||
{
|
|
||||||
using sink_type = spdlog::sinks::daily_file_sink<std::mutex, custom_daily_file_name_calculator>;
|
using sink_type = spdlog::sinks::daily_file_sink<std::mutex, custom_daily_file_name_calculator>;
|
||||||
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
@ -69,12 +65,11 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]")
|
|||||||
spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly");
|
spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly");
|
||||||
std::tm tm = spdlog::details::os::localtime();
|
std::tm tm = spdlog::details::os::localtime();
|
||||||
filename_memory_buf_t w;
|
filename_memory_buf_t w;
|
||||||
spdlog::fmt_lib::format_to(
|
spdlog::fmt_lib::format_to(std::back_inserter(w), SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"),
|
||||||
std::back_inserter(w), SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
|
basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
|
||||||
|
|
||||||
auto logger = spdlog::create<sink_type>("logger", basename, 0, 0);
|
auto logger = spdlog::create<sink_type>("logger", basename, 0, 0);
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i) {
|
||||||
{
|
|
||||||
logger->info("Test message {}", i);
|
logger->info("Test message {}", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,34 +82,33 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]")
|
|||||||
* File name calculations
|
* File name calculations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TEST_CASE("rotating_file_sink::calc_filename1", "[rotating_file_sink]")
|
TEST_CASE("rotating_file_sink::calc_filename1", "[rotating_file_sink]") {
|
||||||
{
|
auto filename =
|
||||||
auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated.txt"), 3);
|
spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated.txt"), 3);
|
||||||
REQUIRE(filename == SPDLOG_FILENAME_T("rotated.3.txt"));
|
REQUIRE(filename == SPDLOG_FILENAME_T("rotated.3.txt"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("rotating_file_sink::calc_filename2", "[rotating_file_sink]")
|
TEST_CASE("rotating_file_sink::calc_filename2", "[rotating_file_sink]") {
|
||||||
{
|
auto filename =
|
||||||
auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated"), 3);
|
spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated"), 3);
|
||||||
REQUIRE(filename == SPDLOG_FILENAME_T("rotated.3"));
|
REQUIRE(filename == SPDLOG_FILENAME_T("rotated.3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("rotating_file_sink::calc_filename3", "[rotating_file_sink]")
|
TEST_CASE("rotating_file_sink::calc_filename3", "[rotating_file_sink]") {
|
||||||
{
|
auto filename =
|
||||||
auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated.txt"), 0);
|
spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated.txt"), 0);
|
||||||
REQUIRE(filename == SPDLOG_FILENAME_T("rotated.txt"));
|
REQUIRE(filename == SPDLOG_FILENAME_T("rotated.txt"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// regex supported only from gcc 4.9 and above
|
// regex supported only from gcc 4.9 and above
|
||||||
#if defined(_MSC_VER) || !(__GNUC__ <= 4 && __GNUC_MINOR__ < 9)
|
#if defined(_MSC_VER) || !(__GNUC__ <= 4 && __GNUC_MINOR__ < 9)
|
||||||
|
|
||||||
# include <regex>
|
#include <regex>
|
||||||
|
|
||||||
TEST_CASE("daily_file_sink::daily_filename_calculator", "[daily_file_sink]")
|
TEST_CASE("daily_file_sink::daily_filename_calculator", "[daily_file_sink]") {
|
||||||
{
|
|
||||||
// daily_YYYY-MM-DD_hh-mm.txt
|
// daily_YYYY-MM-DD_hh-mm.txt
|
||||||
auto filename =
|
auto filename = spdlog::sinks::daily_filename_calculator::calc_filename(
|
||||||
spdlog::sinks::daily_filename_calculator::calc_filename(SPDLOG_FILENAME_T("daily.txt"), spdlog::details::os::localtime());
|
SPDLOG_FILENAME_T("daily.txt"), spdlog::details::os::localtime());
|
||||||
// date regex based on https://www.regular-expressions.info/dates.html
|
// date regex based on https://www.regular-expressions.info/dates.html
|
||||||
std::basic_regex<spdlog::filename_t::value_type> re(
|
std::basic_regex<spdlog::filename_t::value_type> re(
|
||||||
SPDLOG_FILENAME_T(R"(^daily_(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])\.txt$)"));
|
SPDLOG_FILENAME_T(R"(^daily_(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])\.txt$)"));
|
||||||
@ -123,27 +117,26 @@ TEST_CASE("daily_file_sink::daily_filename_calculator", "[daily_file_sink]")
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_CASE("daily_file_sink::daily_filename_format_calculator", "[daily_file_sink]")
|
TEST_CASE("daily_file_sink::daily_filename_format_calculator", "[daily_file_sink]") {
|
||||||
{
|
|
||||||
std::tm tm = spdlog::details::os::localtime();
|
std::tm tm = spdlog::details::os::localtime();
|
||||||
// example-YYYY-MM-DD.log
|
// example-YYYY-MM-DD.log
|
||||||
auto filename = spdlog::sinks::daily_filename_format_calculator::calc_filename(SPDLOG_FILENAME_T("example-%Y-%m-%d.log"), tm);
|
auto filename = spdlog::sinks::daily_filename_format_calculator::calc_filename(
|
||||||
|
SPDLOG_FILENAME_T("example-%Y-%m-%d.log"), tm);
|
||||||
|
|
||||||
REQUIRE(filename ==
|
REQUIRE(filename ==
|
||||||
spdlog::fmt_lib::format(SPDLOG_FILENAME_T("example-{:04d}-{:02d}-{:02d}.log"), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday));
|
spdlog::fmt_lib::format(SPDLOG_FILENAME_T("example-{:04d}-{:02d}-{:02d}.log"),
|
||||||
|
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test removal of old files */
|
/* Test removal of old files */
|
||||||
static spdlog::details::log_msg create_msg(std::chrono::seconds offset)
|
static spdlog::details::log_msg create_msg(std::chrono::seconds offset) {
|
||||||
{
|
|
||||||
using spdlog::log_clock;
|
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;
|
msg.time = log_clock::now() + offset;
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_rotate(int days_to_run, uint16_t max_days, uint16_t expected_n_files)
|
static void test_rotate(int days_to_run, uint16_t max_days, uint16_t expected_n_files) {
|
||||||
{
|
|
||||||
using spdlog::log_clock;
|
using spdlog::log_clock;
|
||||||
using spdlog::details::log_msg;
|
using spdlog::details::log_msg;
|
||||||
using spdlog::sinks::daily_file_sink_st;
|
using spdlog::sinks::daily_file_sink_st;
|
||||||
@ -155,8 +148,7 @@ static void test_rotate(int days_to_run, uint16_t max_days, uint16_t expected_n_
|
|||||||
|
|
||||||
// simulate messages with 24 intervals
|
// simulate messages with 24 intervals
|
||||||
|
|
||||||
for (int i = 0; i < days_to_run; i++)
|
for (int i = 0; i < days_to_run; i++) {
|
||||||
{
|
|
||||||
auto offset = std::chrono::seconds{24 * 3600 * i};
|
auto offset = std::chrono::seconds{24 * 3600 * i};
|
||||||
sink.log(create_msg(offset));
|
sink.log(create_msg(offset));
|
||||||
}
|
}
|
||||||
@ -164,8 +156,7 @@ static void test_rotate(int days_to_run, uint16_t max_days, uint16_t expected_n_
|
|||||||
REQUIRE(count_files("test_logs") == static_cast<size_t>(expected_n_files));
|
REQUIRE(count_files("test_logs") == static_cast<size_t>(expected_n_files));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("daily_logger rotate", "[daily_file_sink]")
|
TEST_CASE("daily_logger rotate", "[daily_file_sink]") {
|
||||||
{
|
|
||||||
int days_to_run = 1;
|
int days_to_run = 1;
|
||||||
test_rotate(days_to_run, 0, 1);
|
test_rotate(days_to_run, 0, 1);
|
||||||
test_rotate(days_to_run, 1, 1);
|
test_rotate(days_to_run, 1, 1);
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
#include "spdlog/sinks/dup_filter_sink.h"
|
#include "spdlog/sinks/dup_filter_sink.h"
|
||||||
#include "test_sink.h"
|
#include "test_sink.h"
|
||||||
|
|
||||||
TEST_CASE("dup_filter_test1", "[dup_filter_sink]")
|
TEST_CASE("dup_filter_test1", "[dup_filter_sink]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::dup_filter_sink_st;
|
using spdlog::sinks::dup_filter_sink_st;
|
||||||
using spdlog::sinks::test_sink_mt;
|
using spdlog::sinks::test_sink_mt;
|
||||||
|
|
||||||
@ -11,16 +10,14 @@ TEST_CASE("dup_filter_test1", "[dup_filter_sink]")
|
|||||||
auto test_sink = std::make_shared<test_sink_mt>();
|
auto test_sink = std::make_shared<test_sink_mt>();
|
||||||
dup_sink.add_sink(test_sink);
|
dup_sink.add_sink(test_sink);
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
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);
|
REQUIRE(test_sink->msg_counter() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("dup_filter_test2", "[dup_filter_sink]")
|
TEST_CASE("dup_filter_test2", "[dup_filter_sink]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::dup_filter_sink_st;
|
using spdlog::sinks::dup_filter_sink_st;
|
||||||
using spdlog::sinks::test_sink_mt;
|
using spdlog::sinks::test_sink_mt;
|
||||||
|
|
||||||
@ -28,8 +25,7 @@ TEST_CASE("dup_filter_test2", "[dup_filter_sink]")
|
|||||||
auto test_sink = std::make_shared<test_sink_mt>();
|
auto test_sink = std::make_shared<test_sink_mt>();
|
||||||
dup_sink.add_sink(test_sink);
|
dup_sink.add_sink(test_sink);
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
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));
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
}
|
}
|
||||||
@ -37,8 +33,7 @@ TEST_CASE("dup_filter_test2", "[dup_filter_sink]")
|
|||||||
REQUIRE(test_sink->msg_counter() == 10);
|
REQUIRE(test_sink->msg_counter() == 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("dup_filter_test3", "[dup_filter_sink]")
|
TEST_CASE("dup_filter_test3", "[dup_filter_sink]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::dup_filter_sink_st;
|
using spdlog::sinks::dup_filter_sink_st;
|
||||||
using spdlog::sinks::test_sink_mt;
|
using spdlog::sinks::test_sink_mt;
|
||||||
|
|
||||||
@ -46,8 +41,7 @@ TEST_CASE("dup_filter_test3", "[dup_filter_sink]")
|
|||||||
auto test_sink = std::make_shared<test_sink_mt>();
|
auto test_sink = std::make_shared<test_sink_mt>();
|
||||||
dup_sink.add_sink(test_sink);
|
dup_sink.add_sink(test_sink);
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
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"});
|
||||||
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"});
|
dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"});
|
||||||
}
|
}
|
||||||
@ -55,8 +49,7 @@ TEST_CASE("dup_filter_test3", "[dup_filter_sink]")
|
|||||||
REQUIRE(test_sink->msg_counter() == 20);
|
REQUIRE(test_sink->msg_counter() == 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("dup_filter_test4", "[dup_filter_sink]")
|
TEST_CASE("dup_filter_test4", "[dup_filter_sink]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::dup_filter_sink_mt;
|
using spdlog::sinks::dup_filter_sink_mt;
|
||||||
using spdlog::sinks::test_sink_mt;
|
using spdlog::sinks::test_sink_mt;
|
||||||
|
|
||||||
@ -70,8 +63,7 @@ TEST_CASE("dup_filter_test4", "[dup_filter_sink]")
|
|||||||
REQUIRE(test_sink->msg_counter() == 2);
|
REQUIRE(test_sink->msg_counter() == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("dup_filter_test5", "[dup_filter_sink]")
|
TEST_CASE("dup_filter_test5", "[dup_filter_sink]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::dup_filter_sink_mt;
|
using spdlog::sinks::dup_filter_sink_mt;
|
||||||
using spdlog::sinks::test_sink_mt;
|
using spdlog::sinks::test_sink_mt;
|
||||||
|
|
||||||
@ -85,6 +77,7 @@ TEST_CASE("dup_filter_test5", "[dup_filter_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, "message2"});
|
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
|
REQUIRE(test_sink->msg_counter() ==
|
||||||
|
3); // skip 2 messages but log the "skipped.." message before message2
|
||||||
REQUIRE(test_sink->lines()[1] == "Skipped 2 duplicate messages..");
|
REQUIRE(test_sink->lines()[1] == "Skipped 2 duplicate messages..");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
* This content is released under the MIT License as specified in
|
||||||
|
* https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
@ -8,25 +9,18 @@
|
|||||||
#define SIMPLE_LOG "test_logs/simple_log.txt"
|
#define SIMPLE_LOG "test_logs/simple_log.txt"
|
||||||
#define SIMPLE_ASYNC_LOG "test_logs/simple_async_log.txt"
|
#define SIMPLE_ASYNC_LOG "test_logs/simple_async_log.txt"
|
||||||
|
|
||||||
class failing_sink : public spdlog::sinks::base_sink<std::mutex>
|
class failing_sink : public spdlog::sinks::base_sink<std::mutex> {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
void sink_it_(const spdlog::details::log_msg &) final
|
void sink_it_(const spdlog::details::log_msg &) final {
|
||||||
{
|
|
||||||
throw std::runtime_error("some error happened during log");
|
throw std::runtime_error("some error happened during log");
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_() final
|
void flush_() final { throw std::runtime_error("some error happened during flush"); }
|
||||||
{
|
|
||||||
throw std::runtime_error("some error happened during flush");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
struct custom_ex
|
struct custom_ex {};
|
||||||
{};
|
|
||||||
|
|
||||||
#if !defined(SPDLOG_USE_STD_FORMAT) // std formt doesn't fully support tuntime strings
|
#if !defined(SPDLOG_USE_STD_FORMAT) // std formt doesn't fully support tuntime strings
|
||||||
TEST_CASE("default_error_handler", "[errors]")
|
TEST_CASE("default_error_handler", "[errors]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
|
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
|
||||||
|
|
||||||
@ -40,8 +34,7 @@ TEST_CASE("default_error_handler", "[errors]")
|
|||||||
REQUIRE(count_lines(SIMPLE_LOG) == 1);
|
REQUIRE(count_lines(SIMPLE_LOG) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("custom_error_handler", "[errors]")
|
TEST_CASE("custom_error_handler", "[errors]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
|
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
|
||||||
auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
|
auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
|
||||||
@ -55,16 +48,14 @@ TEST_CASE("custom_error_handler", "[errors]")
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_CASE("default_error_handler2", "[errors]")
|
TEST_CASE("default_error_handler2", "[errors]") {
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
auto logger = spdlog::create<failing_sink>("failed_logger");
|
auto logger = spdlog::create<failing_sink>("failed_logger");
|
||||||
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
|
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
|
||||||
REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
|
REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("flush_error_handler", "[errors]")
|
TEST_CASE("flush_error_handler", "[errors]") {
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
auto logger = spdlog::create<failing_sink>("failed_logger");
|
auto logger = spdlog::create<failing_sink>("failed_logger");
|
||||||
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
|
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
|
||||||
@ -72,19 +63,18 @@ TEST_CASE("flush_error_handler", "[errors]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(SPDLOG_USE_STD_FORMAT)
|
#if !defined(SPDLOG_USE_STD_FORMAT)
|
||||||
TEST_CASE("async_error_handler", "[errors]")
|
TEST_CASE("async_error_handler", "[errors]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
std::string err_msg("log failed with some msg");
|
std::string err_msg("log failed with some msg");
|
||||||
|
|
||||||
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_ASYNC_LOG);
|
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_ASYNC_LOG);
|
||||||
{
|
{
|
||||||
spdlog::init_thread_pool(128, 1);
|
spdlog::init_thread_pool(128, 1);
|
||||||
auto logger = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
|
auto logger =
|
||||||
|
spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
|
||||||
logger->set_error_handler([=](const std::string &) {
|
logger->set_error_handler([=](const std::string &) {
|
||||||
std::ofstream ofs("test_logs/custom_err.txt");
|
std::ofstream ofs("test_logs/custom_err.txt");
|
||||||
if (!ofs)
|
if (!ofs) {
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed open test_logs/custom_err.txt");
|
throw std::runtime_error("Failed open test_logs/custom_err.txt");
|
||||||
}
|
}
|
||||||
ofs << err_msg;
|
ofs << err_msg;
|
||||||
@ -101,8 +91,7 @@ TEST_CASE("async_error_handler", "[errors]")
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Make sure async error handler is executed
|
// Make sure async error handler is executed
|
||||||
TEST_CASE("async_error_handler2", "[errors]")
|
TEST_CASE("async_error_handler2", "[errors]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
std::string err_msg("This is async handler error message");
|
std::string err_msg("This is async handler error message");
|
||||||
{
|
{
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
|
||||||
# include "includes.h"
|
#include "includes.h"
|
||||||
# include "test_sink.h"
|
#include "test_sink.h"
|
||||||
|
|
||||||
# include "spdlog/sinks/win_eventlog_sink.h"
|
#include "spdlog/sinks/win_eventlog_sink.h"
|
||||||
|
|
||||||
static const LPCSTR TEST_SOURCE = "spdlog_test";
|
static const LPCSTR TEST_SOURCE = "spdlog_test";
|
||||||
|
|
||||||
static void test_single_print(std::function<void(std::string const &)> do_log, std::string const &expected_contents, WORD expected_ev_type)
|
static void test_single_print(std::function<void(std::string const &)> do_log,
|
||||||
{
|
std::string const &expected_contents,
|
||||||
|
WORD expected_ev_type) {
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
do_log(expected_contents);
|
do_log(expected_contents);
|
||||||
const auto expected_time_generated = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
|
const auto expected_time_generated =
|
||||||
|
duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
|
||||||
|
|
||||||
struct handle_t
|
struct handle_t {
|
||||||
{
|
|
||||||
HANDLE handle_;
|
HANDLE handle_;
|
||||||
|
|
||||||
~handle_t()
|
~handle_t() {
|
||||||
{
|
if (handle_) {
|
||||||
if (handle_)
|
|
||||||
{
|
|
||||||
REQUIRE(CloseEventLog(handle_));
|
REQUIRE(CloseEventLog(handle_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,16 +28,16 @@ static void test_single_print(std::function<void(std::string const &)> do_log, s
|
|||||||
REQUIRE(event_log.handle_);
|
REQUIRE(event_log.handle_);
|
||||||
|
|
||||||
DWORD read_bytes{}, size_needed{};
|
DWORD read_bytes{}, size_needed{};
|
||||||
auto ok = ::ReadEventLogA(
|
auto ok = ::ReadEventLogA(event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ,
|
||||||
event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, &read_bytes, 0, &read_bytes, &size_needed);
|
0, &read_bytes, 0, &read_bytes, &size_needed);
|
||||||
REQUIRE(!ok);
|
REQUIRE(!ok);
|
||||||
REQUIRE(::GetLastError() == ERROR_INSUFFICIENT_BUFFER);
|
REQUIRE(::GetLastError() == ERROR_INSUFFICIENT_BUFFER);
|
||||||
|
|
||||||
std::vector<char> record_buffer(size_needed);
|
std::vector<char> record_buffer(size_needed);
|
||||||
PEVENTLOGRECORD record = (PEVENTLOGRECORD)record_buffer.data();
|
PEVENTLOGRECORD record = (PEVENTLOGRECORD)record_buffer.data();
|
||||||
|
|
||||||
ok = ::ReadEventLogA(
|
ok = ::ReadEventLogA(event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0,
|
||||||
event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, record, size_needed, &read_bytes, &size_needed);
|
record, size_needed, &read_bytes, &size_needed);
|
||||||
REQUIRE(ok);
|
REQUIRE(ok);
|
||||||
|
|
||||||
REQUIRE(record->NumStrings == 1);
|
REQUIRE(record->NumStrings == 1);
|
||||||
@ -49,8 +48,7 @@ static void test_single_print(std::function<void(std::string const &)> do_log, s
|
|||||||
REQUIRE(message_in_log == expected_contents + spdlog::details::os::default_eol);
|
REQUIRE(message_in_log == expected_contents + spdlog::details::os::default_eol);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("eventlog", "[eventlog]")
|
TEST_CASE("eventlog", "[eventlog]") {
|
||||||
{
|
|
||||||
using namespace spdlog;
|
using namespace spdlog;
|
||||||
|
|
||||||
auto test_sink = std::make_shared<sinks::win_eventlog_sink_mt>(TEST_SOURCE);
|
auto test_sink = std::make_shared<sinks::win_eventlog_sink_mt>(TEST_SOURCE);
|
||||||
@ -60,12 +58,18 @@ TEST_CASE("eventlog", "[eventlog]")
|
|||||||
|
|
||||||
test_sink->set_pattern("%v");
|
test_sink->set_pattern("%v");
|
||||||
|
|
||||||
test_single_print([&test_logger](std::string const &msg) { test_logger.trace(msg); }, "my trace message", EVENTLOG_SUCCESS);
|
test_single_print([&test_logger](std::string const &msg) { test_logger.trace(msg); },
|
||||||
test_single_print([&test_logger](std::string const &msg) { test_logger.debug(msg); }, "my debug message", EVENTLOG_SUCCESS);
|
"my trace message", EVENTLOG_SUCCESS);
|
||||||
test_single_print([&test_logger](std::string const &msg) { test_logger.info(msg); }, "my info message", EVENTLOG_INFORMATION_TYPE);
|
test_single_print([&test_logger](std::string const &msg) { test_logger.debug(msg); },
|
||||||
test_single_print([&test_logger](std::string const &msg) { test_logger.warn(msg); }, "my warn message", EVENTLOG_WARNING_TYPE);
|
"my debug message", EVENTLOG_SUCCESS);
|
||||||
test_single_print([&test_logger](std::string const &msg) { test_logger.error(msg); }, "my error message", EVENTLOG_ERROR_TYPE);
|
test_single_print([&test_logger](std::string const &msg) { test_logger.info(msg); },
|
||||||
test_single_print([&test_logger](std::string const &msg) { test_logger.critical(msg); }, "my critical message", EVENTLOG_ERROR_TYPE);
|
"my info message", EVENTLOG_INFORMATION_TYPE);
|
||||||
|
test_single_print([&test_logger](std::string const &msg) { test_logger.warn(msg); },
|
||||||
|
"my warn message", EVENTLOG_WARNING_TYPE);
|
||||||
|
test_single_print([&test_logger](std::string const &msg) { test_logger.error(msg); },
|
||||||
|
"my error message", EVENTLOG_ERROR_TYPE);
|
||||||
|
test_single_print([&test_logger](std::string const &msg) { test_logger.critical(msg); },
|
||||||
|
"my critical message", EVENTLOG_ERROR_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //_WIN32
|
#endif //_WIN32
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
* This content is released under the MIT License as specified in
|
||||||
|
* https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
@ -7,16 +8,14 @@
|
|||||||
|
|
||||||
using spdlog::details::file_helper;
|
using spdlog::details::file_helper;
|
||||||
|
|
||||||
static void write_with_helper(file_helper &helper, size_t howmany)
|
static void write_with_helper(file_helper &helper, size_t howmany) {
|
||||||
{
|
|
||||||
spdlog::memory_buf_t formatted;
|
spdlog::memory_buf_t formatted;
|
||||||
spdlog::fmt_lib::format_to(std::back_inserter(formatted), "{}", std::string(howmany, '1'));
|
spdlog::fmt_lib::format_to(std::back_inserter(formatted), "{}", std::string(howmany, '1'));
|
||||||
helper.write(formatted);
|
helper.write(formatted);
|
||||||
helper.flush();
|
helper.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("file_helper_filename", "[file_helper::filename()]")
|
TEST_CASE("file_helper_filename", "[file_helper::filename()]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
|
|
||||||
file_helper helper;
|
file_helper helper;
|
||||||
@ -25,8 +24,7 @@ TEST_CASE("file_helper_filename", "[file_helper::filename()]")
|
|||||||
REQUIRE(helper.filename() == target_filename);
|
REQUIRE(helper.filename() == target_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("file_helper_size", "[file_helper::size()]")
|
TEST_CASE("file_helper_size", "[file_helper::size()]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
||||||
size_t expected_size = 123;
|
size_t expected_size = 123;
|
||||||
@ -39,8 +37,7 @@ TEST_CASE("file_helper_size", "[file_helper::size()]")
|
|||||||
REQUIRE(get_filesize(TEST_FILENAME) == expected_size);
|
REQUIRE(get_filesize(TEST_FILENAME) == expected_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("file_helper_reopen", "[file_helper::reopen()]")
|
TEST_CASE("file_helper_reopen", "[file_helper::reopen()]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
||||||
file_helper helper;
|
file_helper helper;
|
||||||
@ -51,8 +48,7 @@ TEST_CASE("file_helper_reopen", "[file_helper::reopen()]")
|
|||||||
REQUIRE(helper.size() == 0);
|
REQUIRE(helper.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]")
|
TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
||||||
size_t expected_size = 14;
|
size_t expected_size = 14;
|
||||||
@ -64,9 +60,9 @@ TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]")
|
|||||||
REQUIRE(helper.size() == expected_size);
|
REQUIRE(helper.size() == expected_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_split_ext(const spdlog::filename_t::value_type *fname, const spdlog::filename_t::value_type *expect_base,
|
static void test_split_ext(const spdlog::filename_t::value_type *fname,
|
||||||
const spdlog::filename_t::value_type *expect_ext)
|
const spdlog::filename_t::value_type *expect_base,
|
||||||
{
|
const spdlog::filename_t::value_type *expect_ext) {
|
||||||
spdlog::filename_t filename(fname);
|
spdlog::filename_t filename(fname);
|
||||||
spdlog::filename_t expected_base(expect_base);
|
spdlog::filename_t expected_base(expect_base);
|
||||||
spdlog::filename_t expected_ext(expect_ext);
|
spdlog::filename_t expected_ext(expect_ext);
|
||||||
@ -78,37 +74,43 @@ static void test_split_ext(const spdlog::filename_t::value_type *fname, const sp
|
|||||||
REQUIRE(ext == expected_ext);
|
REQUIRE(ext == expected_ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("file_helper_split_by_extension", "[file_helper::split_by_extension()]")
|
TEST_CASE("file_helper_split_by_extension", "[file_helper::split_by_extension()]") {
|
||||||
{
|
test_split_ext(SPDLOG_FILENAME_T("mylog.txt"), SPDLOG_FILENAME_T("mylog"),
|
||||||
test_split_ext(SPDLOG_FILENAME_T("mylog.txt"), SPDLOG_FILENAME_T("mylog"), SPDLOG_FILENAME_T(".txt"));
|
SPDLOG_FILENAME_T(".txt"));
|
||||||
test_split_ext(SPDLOG_FILENAME_T(".mylog.txt"), SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T(".txt"));
|
test_split_ext(SPDLOG_FILENAME_T(".mylog.txt"), SPDLOG_FILENAME_T(".mylog"),
|
||||||
|
SPDLOG_FILENAME_T(".txt"));
|
||||||
test_split_ext(SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T(""));
|
test_split_ext(SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T(""));
|
||||||
test_split_ext(SPDLOG_FILENAME_T("/aaa/bb.d/mylog"), SPDLOG_FILENAME_T("/aaa/bb.d/mylog"), SPDLOG_FILENAME_T(""));
|
test_split_ext(SPDLOG_FILENAME_T("/aaa/bb.d/mylog"), SPDLOG_FILENAME_T("/aaa/bb.d/mylog"),
|
||||||
test_split_ext(SPDLOG_FILENAME_T("/aaa/bb.d/mylog.txt"), SPDLOG_FILENAME_T("/aaa/bb.d/mylog"), SPDLOG_FILENAME_T(".txt"));
|
SPDLOG_FILENAME_T(""));
|
||||||
test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog.txt"), SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog"), SPDLOG_FILENAME_T(".txt"));
|
test_split_ext(SPDLOG_FILENAME_T("/aaa/bb.d/mylog.txt"), SPDLOG_FILENAME_T("/aaa/bb.d/mylog"),
|
||||||
test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog."), SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog."), SPDLOG_FILENAME_T(""));
|
SPDLOG_FILENAME_T(".txt"));
|
||||||
test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/.mylog.txt"), SPDLOG_FILENAME_T("aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T(".txt"));
|
test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog.txt"),
|
||||||
test_split_ext(SPDLOG_FILENAME_T("/aaa/bbb/ccc/mylog.txt"), SPDLOG_FILENAME_T("/aaa/bbb/ccc/mylog"), SPDLOG_FILENAME_T(".txt"));
|
SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog"), SPDLOG_FILENAME_T(".txt"));
|
||||||
test_split_ext(SPDLOG_FILENAME_T("/aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T("/aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T(""));
|
test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog."), SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog."),
|
||||||
test_split_ext(SPDLOG_FILENAME_T("../mylog.txt"), SPDLOG_FILENAME_T("../mylog"), SPDLOG_FILENAME_T(".txt"));
|
SPDLOG_FILENAME_T(""));
|
||||||
test_split_ext(SPDLOG_FILENAME_T(".././mylog.txt"), SPDLOG_FILENAME_T(".././mylog"), SPDLOG_FILENAME_T(".txt"));
|
test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/.mylog.txt"),
|
||||||
test_split_ext(SPDLOG_FILENAME_T(".././mylog.txt/xxx"), SPDLOG_FILENAME_T(".././mylog.txt/xxx"), SPDLOG_FILENAME_T(""));
|
SPDLOG_FILENAME_T("aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T(".txt"));
|
||||||
test_split_ext(SPDLOG_FILENAME_T("/mylog.txt"), SPDLOG_FILENAME_T("/mylog"), SPDLOG_FILENAME_T(".txt"));
|
test_split_ext(SPDLOG_FILENAME_T("/aaa/bbb/ccc/mylog.txt"),
|
||||||
test_split_ext(SPDLOG_FILENAME_T("//mylog.txt"), SPDLOG_FILENAME_T("//mylog"), SPDLOG_FILENAME_T(".txt"));
|
SPDLOG_FILENAME_T("/aaa/bbb/ccc/mylog"), SPDLOG_FILENAME_T(".txt"));
|
||||||
|
test_split_ext(SPDLOG_FILENAME_T("/aaa/bbb/ccc/.mylog"),
|
||||||
|
SPDLOG_FILENAME_T("/aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T(""));
|
||||||
|
test_split_ext(SPDLOG_FILENAME_T("../mylog.txt"), SPDLOG_FILENAME_T("../mylog"),
|
||||||
|
SPDLOG_FILENAME_T(".txt"));
|
||||||
|
test_split_ext(SPDLOG_FILENAME_T(".././mylog.txt"), SPDLOG_FILENAME_T(".././mylog"),
|
||||||
|
SPDLOG_FILENAME_T(".txt"));
|
||||||
|
test_split_ext(SPDLOG_FILENAME_T(".././mylog.txt/xxx"), SPDLOG_FILENAME_T(".././mylog.txt/xxx"),
|
||||||
|
SPDLOG_FILENAME_T(""));
|
||||||
|
test_split_ext(SPDLOG_FILENAME_T("/mylog.txt"), SPDLOG_FILENAME_T("/mylog"),
|
||||||
|
SPDLOG_FILENAME_T(".txt"));
|
||||||
|
test_split_ext(SPDLOG_FILENAME_T("//mylog.txt"), SPDLOG_FILENAME_T("//mylog"),
|
||||||
|
SPDLOG_FILENAME_T(".txt"));
|
||||||
test_split_ext(SPDLOG_FILENAME_T(""), SPDLOG_FILENAME_T(""), SPDLOG_FILENAME_T(""));
|
test_split_ext(SPDLOG_FILENAME_T(""), SPDLOG_FILENAME_T(""), SPDLOG_FILENAME_T(""));
|
||||||
test_split_ext(SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T(""));
|
test_split_ext(SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T(""));
|
||||||
test_split_ext(SPDLOG_FILENAME_T("..txt"), SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T(".txt"));
|
test_split_ext(SPDLOG_FILENAME_T("..txt"), SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T(".txt"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("file_event_handlers", "[file_helper]")
|
TEST_CASE("file_event_handlers", "[file_helper]") {
|
||||||
{
|
enum class flags { before_open, after_open, before_close, after_close };
|
||||||
enum class flags
|
|
||||||
{
|
|
||||||
before_open,
|
|
||||||
after_open,
|
|
||||||
before_close,
|
|
||||||
after_close
|
|
||||||
};
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
|
|
||||||
spdlog::filename_t test_filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
spdlog::filename_t test_filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
||||||
@ -155,8 +157,7 @@ TEST_CASE("file_event_handlers", "[file_helper]")
|
|||||||
REQUIRE(file_contents(TEST_FILENAME) == "after_open\nbefore_close\n");
|
REQUIRE(file_contents(TEST_FILENAME) == "after_open\nbefore_close\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("file_helper_open", "[file_helper]")
|
TEST_CASE("file_helper_open", "[file_helper]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
||||||
file_helper helper;
|
file_helper helper;
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
* This content is released under the MIT License as specified in
|
||||||
|
* https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
#define SIMPLE_LOG "test_logs/simple_log"
|
#define SIMPLE_LOG "test_logs/simple_log"
|
||||||
#define ROTATING_LOG "test_logs/rotating_log"
|
#define ROTATING_LOG "test_logs/rotating_log"
|
||||||
|
|
||||||
TEST_CASE("simple_file_logger", "[simple_logger]")
|
TEST_CASE("simple_file_logger", "[simple_logger]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
|
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
|
||||||
|
|
||||||
@ -20,11 +20,11 @@ TEST_CASE("simple_file_logger", "[simple_logger]")
|
|||||||
logger->flush();
|
logger->flush();
|
||||||
require_message_count(SIMPLE_LOG, 2);
|
require_message_count(SIMPLE_LOG, 2);
|
||||||
using spdlog::details::os::default_eol;
|
using spdlog::details::os::default_eol;
|
||||||
REQUIRE(file_contents(SIMPLE_LOG) == spdlog::fmt_lib::format("Test message 1{}Test message 2{}", default_eol, default_eol));
|
REQUIRE(file_contents(SIMPLE_LOG) ==
|
||||||
|
spdlog::fmt_lib::format("Test message 1{}Test message 2{}", default_eol, default_eol));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("flush_on", "[flush_on]")
|
TEST_CASE("flush_on", "[flush_on]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
|
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
|
||||||
|
|
||||||
@ -41,18 +41,17 @@ TEST_CASE("flush_on", "[flush_on]")
|
|||||||
require_message_count(SIMPLE_LOG, 3);
|
require_message_count(SIMPLE_LOG, 3);
|
||||||
using spdlog::details::os::default_eol;
|
using spdlog::details::os::default_eol;
|
||||||
REQUIRE(file_contents(SIMPLE_LOG) ==
|
REQUIRE(file_contents(SIMPLE_LOG) ==
|
||||||
spdlog::fmt_lib::format("Should not be flushed{}Test message 1{}Test message 2{}", default_eol, default_eol, default_eol));
|
spdlog::fmt_lib::format("Should not be flushed{}Test message 1{}Test message 2{}",
|
||||||
|
default_eol, default_eol, default_eol));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("rotating_file_logger1", "[rotating_logger]")
|
TEST_CASE("rotating_file_logger1", "[rotating_logger]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
size_t max_size = 1024 * 10;
|
size_t max_size = 1024 * 10;
|
||||||
spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG);
|
spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG);
|
||||||
auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 0);
|
auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 0);
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i) {
|
||||||
{
|
|
||||||
logger->info("Test message {}", i);
|
logger->info("Test message {}", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,8 +59,7 @@ TEST_CASE("rotating_file_logger1", "[rotating_logger]")
|
|||||||
require_message_count(ROTATING_LOG, 10);
|
require_message_count(ROTATING_LOG, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("rotating_file_logger2", "[rotating_logger]")
|
TEST_CASE("rotating_file_logger2", "[rotating_logger]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
size_t max_size = 1024 * 10;
|
size_t max_size = 1024 * 10;
|
||||||
spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG);
|
spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG);
|
||||||
@ -69,8 +67,7 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]")
|
|||||||
{
|
{
|
||||||
// make an initial logger to create the first output file
|
// make an initial logger to create the first output file
|
||||||
auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 2, true);
|
auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 2, true);
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i) {
|
||||||
{
|
|
||||||
logger->info("Test message {}", i);
|
logger->info("Test message {}", i);
|
||||||
}
|
}
|
||||||
// drop causes the logger destructor to be called, which is required so the
|
// drop causes the logger destructor to be called, which is required so the
|
||||||
@ -79,8 +76,7 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 2, true);
|
auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 2, true);
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i) {
|
||||||
{
|
|
||||||
logger->info("Test message {}", i);
|
logger->info("Test message {}", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,8 +84,7 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]")
|
|||||||
|
|
||||||
require_message_count(ROTATING_LOG, 10);
|
require_message_count(ROTATING_LOG, 10);
|
||||||
|
|
||||||
for (int i = 0; i < 1000; i++)
|
for (int i = 0; i < 1000; i++) {
|
||||||
{
|
|
||||||
|
|
||||||
logger->info("Test message {}", i);
|
logger->info("Test message {}", i);
|
||||||
}
|
}
|
||||||
@ -100,10 +95,10 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
// test that passing max_size=0 throws
|
// test that passing max_size=0 throws
|
||||||
TEST_CASE("rotating_file_logger3", "[rotating_logger]")
|
TEST_CASE("rotating_file_logger3", "[rotating_logger]") {
|
||||||
{
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
size_t max_size = 0;
|
size_t max_size = 0;
|
||||||
spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG);
|
spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG);
|
||||||
REQUIRE_THROWS_AS(spdlog::rotating_logger_mt("logger", basename, max_size, 0), spdlog::spdlog_ex);
|
REQUIRE_THROWS_AS(spdlog::rotating_logger_mt("logger", basename, max_size, 0),
|
||||||
|
spdlog::spdlog_ex);
|
||||||
}
|
}
|
||||||
|
@ -4,40 +4,35 @@
|
|||||||
using spdlog::memory_buf_t;
|
using spdlog::memory_buf_t;
|
||||||
using spdlog::details::to_string_view;
|
using spdlog::details::to_string_view;
|
||||||
|
|
||||||
void test_pad2(int n, const char *expected)
|
void test_pad2(int n, const char *expected) {
|
||||||
{
|
|
||||||
memory_buf_t buf;
|
memory_buf_t buf;
|
||||||
spdlog::details::fmt_helper::pad2(n, buf);
|
spdlog::details::fmt_helper::pad2(n, buf);
|
||||||
|
|
||||||
REQUIRE(to_string_view(buf) == expected);
|
REQUIRE(to_string_view(buf) == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_pad3(uint32_t n, const char *expected)
|
void test_pad3(uint32_t n, const char *expected) {
|
||||||
{
|
|
||||||
memory_buf_t buf;
|
memory_buf_t buf;
|
||||||
spdlog::details::fmt_helper::pad3(n, buf);
|
spdlog::details::fmt_helper::pad3(n, buf);
|
||||||
|
|
||||||
REQUIRE(to_string_view(buf) == expected);
|
REQUIRE(to_string_view(buf) == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_pad6(std::size_t n, const char *expected)
|
void test_pad6(std::size_t n, const char *expected) {
|
||||||
{
|
|
||||||
memory_buf_t buf;
|
memory_buf_t buf;
|
||||||
spdlog::details::fmt_helper::pad6(n, buf);
|
spdlog::details::fmt_helper::pad6(n, buf);
|
||||||
|
|
||||||
REQUIRE(to_string_view(buf) == expected);
|
REQUIRE(to_string_view(buf) == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_pad9(std::size_t n, const char *expected)
|
void test_pad9(std::size_t n, const char *expected) {
|
||||||
{
|
|
||||||
memory_buf_t buf;
|
memory_buf_t buf;
|
||||||
spdlog::details::fmt_helper::pad9(n, buf);
|
spdlog::details::fmt_helper::pad9(n, buf);
|
||||||
|
|
||||||
REQUIRE(to_string_view(buf) == expected);
|
REQUIRE(to_string_view(buf) == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("pad2", "[fmt_helper]")
|
TEST_CASE("pad2", "[fmt_helper]") {
|
||||||
{
|
|
||||||
test_pad2(0, "00");
|
test_pad2(0, "00");
|
||||||
test_pad2(3, "03");
|
test_pad2(3, "03");
|
||||||
test_pad2(10, "10");
|
test_pad2(10, "10");
|
||||||
@ -49,8 +44,7 @@ TEST_CASE("pad2", "[fmt_helper]")
|
|||||||
test_pad2(-5, "-5");
|
test_pad2(-5, "-5");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("pad3", "[fmt_helper]")
|
TEST_CASE("pad3", "[fmt_helper]") {
|
||||||
{
|
|
||||||
test_pad3(0, "000");
|
test_pad3(0, "000");
|
||||||
test_pad3(3, "003");
|
test_pad3(3, "003");
|
||||||
test_pad3(10, "010");
|
test_pad3(10, "010");
|
||||||
@ -63,8 +57,7 @@ TEST_CASE("pad3", "[fmt_helper]")
|
|||||||
test_pad3(1234, "1234");
|
test_pad3(1234, "1234");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("pad6", "[fmt_helper]")
|
TEST_CASE("pad6", "[fmt_helper]") {
|
||||||
{
|
|
||||||
test_pad6(0, "000000");
|
test_pad6(0, "000000");
|
||||||
test_pad6(3, "000003");
|
test_pad6(3, "000003");
|
||||||
test_pad6(23, "000023");
|
test_pad6(23, "000023");
|
||||||
@ -74,8 +67,7 @@ TEST_CASE("pad6", "[fmt_helper]")
|
|||||||
test_pad6(123456, "123456");
|
test_pad6(123456, "123456");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("pad9", "[fmt_helper]")
|
TEST_CASE("pad9", "[fmt_helper]") {
|
||||||
{
|
|
||||||
test_pad9(0, "000000000");
|
test_pad9(0, "000000000");
|
||||||
test_pad9(3, "000000003");
|
test_pad9(3, "000000003");
|
||||||
test_pad9(23, "000000023");
|
test_pad9(23, "000000023");
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
* This content is released under the MIT License as specified in
|
||||||
|
* https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
#if SPDLOG_ACTIVE_LEVEL != SPDLOG_LEVEL_DEBUG
|
#if SPDLOG_ACTIVE_LEVEL != SPDLOG_LEVEL_DEBUG
|
||||||
# error "Invalid SPDLOG_ACTIVE_LEVEL in test. Should be SPDLOG_LEVEL_DEBUG"
|
#error "Invalid SPDLOG_ACTIVE_LEVEL in test. Should be SPDLOG_LEVEL_DEBUG"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TEST_FILENAME "test_logs/simple_log"
|
#define TEST_FILENAME "test_logs/simple_log"
|
||||||
|
|
||||||
TEST_CASE("debug and trace w/o format string", "[macros]")
|
TEST_CASE("debug and trace w/o format string", "[macros]") {
|
||||||
{
|
|
||||||
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
spdlog::filename_t filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
spdlog::filename_t filename = SPDLOG_FILENAME_T(TEST_FILENAME);
|
||||||
@ -25,7 +25,8 @@ TEST_CASE("debug and trace w/o format string", "[macros]")
|
|||||||
logger->flush();
|
logger->flush();
|
||||||
|
|
||||||
using spdlog::details::os::default_eol;
|
using spdlog::details::os::default_eol;
|
||||||
REQUIRE(ends_with(file_contents(TEST_FILENAME), spdlog::fmt_lib::format("Test message 2{}", default_eol)));
|
REQUIRE(ends_with(file_contents(TEST_FILENAME),
|
||||||
|
spdlog::fmt_lib::format("Test message 2{}", default_eol)));
|
||||||
REQUIRE(count_lines(TEST_FILENAME) == 1);
|
REQUIRE(count_lines(TEST_FILENAME) == 1);
|
||||||
|
|
||||||
auto orig_default_logger = spdlog::default_logger();
|
auto orig_default_logger = spdlog::default_logger();
|
||||||
@ -36,17 +37,16 @@ TEST_CASE("debug and trace w/o format string", "[macros]")
|
|||||||
logger->flush();
|
logger->flush();
|
||||||
|
|
||||||
require_message_count(TEST_FILENAME, 2);
|
require_message_count(TEST_FILENAME, 2);
|
||||||
REQUIRE(ends_with(file_contents(TEST_FILENAME), spdlog::fmt_lib::format("Test message 4{}", default_eol)));
|
REQUIRE(ends_with(file_contents(TEST_FILENAME),
|
||||||
|
spdlog::fmt_lib::format("Test message 4{}", default_eol)));
|
||||||
spdlog::set_default_logger(std::move(orig_default_logger));
|
spdlog::set_default_logger(std::move(orig_default_logger));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("disable param evaluation", "[macros]")
|
TEST_CASE("disable param evaluation", "[macros]") {
|
||||||
{
|
|
||||||
SPDLOG_TRACE("Test message {}", throw std::runtime_error("Should not be evaluated"));
|
SPDLOG_TRACE("Test message {}", throw std::runtime_error("Should not be evaluated"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("pass logger pointer", "[macros]")
|
TEST_CASE("pass logger pointer", "[macros]") {
|
||||||
{
|
|
||||||
auto logger = spdlog::create<spdlog::sinks::null_sink_mt>("refmacro");
|
auto logger = spdlog::create<spdlog::sinks::null_sink_mt>("refmacro");
|
||||||
auto &ref = *logger;
|
auto &ref = *logger;
|
||||||
SPDLOG_LOGGER_TRACE(&ref, "Test message 1");
|
SPDLOG_LOGGER_TRACE(&ref, "Test message 1");
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "test_sink.h"
|
#include "test_sink.h"
|
||||||
|
|
||||||
template<class T>
|
template <class T>
|
||||||
std::string log_info(const T &what, spdlog::level::level_enum logger_level = spdlog::level::info)
|
std::string log_info(const T &what, spdlog::level::level_enum logger_level = spdlog::level::info) {
|
||||||
{
|
|
||||||
|
|
||||||
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);
|
||||||
@ -16,8 +15,7 @@ std::string log_info(const T &what, spdlog::level::level_enum logger_level = spd
|
|||||||
return oss.str().substr(0, oss.str().length() - strlen(spdlog::details::os::default_eol));
|
return oss.str().substr(0, oss.str().length() - strlen(spdlog::details::os::default_eol));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("basic_logging ", "[basic_logging]")
|
TEST_CASE("basic_logging ", "[basic_logging]") {
|
||||||
{
|
|
||||||
// const char
|
// const char
|
||||||
REQUIRE(log_info("Hello") == "Hello");
|
REQUIRE(log_info("Hello") == "Hello");
|
||||||
REQUIRE(log_info("").empty());
|
REQUIRE(log_info("").empty());
|
||||||
@ -34,8 +32,7 @@ TEST_CASE("basic_logging ", "[basic_logging]")
|
|||||||
// REQUIRE(log_info(some_logged_class("some_val")) == "some_val");
|
// REQUIRE(log_info(some_logged_class("some_val")) == "some_val");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("log_levels", "[log_levels]")
|
TEST_CASE("log_levels", "[log_levels]") {
|
||||||
{
|
|
||||||
REQUIRE(log_info("Hello", spdlog::level::err).empty());
|
REQUIRE(log_info("Hello", spdlog::level::err).empty());
|
||||||
REQUIRE(log_info("Hello", spdlog::level::critical).empty());
|
REQUIRE(log_info("Hello", spdlog::level::critical).empty());
|
||||||
REQUIRE(log_info("Hello", spdlog::level::info) == "Hello");
|
REQUIRE(log_info("Hello", spdlog::level::info) == "Hello");
|
||||||
@ -43,8 +40,7 @@ TEST_CASE("log_levels", "[log_levels]")
|
|||||||
REQUIRE(log_info("Hello", spdlog::level::trace) == "Hello");
|
REQUIRE(log_info("Hello", spdlog::level::trace) == "Hello");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("level_to_string_view", "[convert_to_string_view]")
|
TEST_CASE("level_to_string_view", "[convert_to_string_view]") {
|
||||||
{
|
|
||||||
REQUIRE(spdlog::level::to_string_view(spdlog::level::trace) == "trace");
|
REQUIRE(spdlog::level::to_string_view(spdlog::level::trace) == "trace");
|
||||||
REQUIRE(spdlog::level::to_string_view(spdlog::level::debug) == "debug");
|
REQUIRE(spdlog::level::to_string_view(spdlog::level::debug) == "debug");
|
||||||
REQUIRE(spdlog::level::to_string_view(spdlog::level::info) == "info");
|
REQUIRE(spdlog::level::to_string_view(spdlog::level::info) == "info");
|
||||||
@ -54,8 +50,7 @@ TEST_CASE("level_to_string_view", "[convert_to_string_view]")
|
|||||||
REQUIRE(spdlog::level::to_string_view(spdlog::level::off) == "off");
|
REQUIRE(spdlog::level::to_string_view(spdlog::level::off) == "off");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("to_short_c_str", "[convert_to_short_c_str]")
|
TEST_CASE("to_short_c_str", "[convert_to_short_c_str]") {
|
||||||
{
|
|
||||||
REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::trace)) == "T");
|
REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::trace)) == "T");
|
||||||
REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::debug)) == "D");
|
REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::debug)) == "D");
|
||||||
REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::info)) == "I");
|
REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::info)) == "I");
|
||||||
@ -65,8 +60,7 @@ TEST_CASE("to_short_c_str", "[convert_to_short_c_str]")
|
|||||||
REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::off)) == "O");
|
REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::off)) == "O");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("to_level_enum", "[convert_to_level_enum]")
|
TEST_CASE("to_level_enum", "[convert_to_level_enum]") {
|
||||||
{
|
|
||||||
REQUIRE(spdlog::level::from_str("trace") == spdlog::level::trace);
|
REQUIRE(spdlog::level::from_str("trace") == spdlog::level::trace);
|
||||||
REQUIRE(spdlog::level::from_str("debug") == spdlog::level::debug);
|
REQUIRE(spdlog::level::from_str("debug") == spdlog::level::debug);
|
||||||
REQUIRE(spdlog::level::from_str("info") == spdlog::level::info);
|
REQUIRE(spdlog::level::from_str("info") == spdlog::level::info);
|
||||||
@ -78,8 +72,7 @@ TEST_CASE("to_level_enum", "[convert_to_level_enum]")
|
|||||||
REQUIRE(spdlog::level::from_str("null") == spdlog::level::off);
|
REQUIRE(spdlog::level::from_str("null") == spdlog::level::off);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("periodic flush", "[periodic_flush]")
|
TEST_CASE("periodic flush", "[periodic_flush]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::test_sink_mt;
|
using spdlog::sinks::test_sink_mt;
|
||||||
auto logger = spdlog::create<test_sink_mt>("periodic_flush");
|
auto logger = spdlog::create<test_sink_mt>("periodic_flush");
|
||||||
auto test_sink = std::static_pointer_cast<test_sink_mt>(logger->sinks()[0]);
|
auto test_sink = std::static_pointer_cast<test_sink_mt>(logger->sinks()[0]);
|
||||||
@ -91,8 +84,7 @@ TEST_CASE("periodic flush", "[periodic_flush]")
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("clone-logger", "[clone]")
|
TEST_CASE("clone-logger", "[clone]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::test_sink_mt;
|
using spdlog::sinks::test_sink_mt;
|
||||||
auto test_sink = std::make_shared<test_sink_mt>();
|
auto test_sink = std::make_shared<test_sink_mt>();
|
||||||
auto logger = std::make_shared<spdlog::logger>("orig", test_sink);
|
auto logger = std::make_shared<spdlog::logger>("orig", test_sink);
|
||||||
@ -113,8 +105,7 @@ TEST_CASE("clone-logger", "[clone]")
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("clone async", "[clone]")
|
TEST_CASE("clone async", "[clone]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::test_sink_st;
|
using spdlog::sinks::test_sink_st;
|
||||||
spdlog::init_thread_pool(4, 1);
|
spdlog::init_thread_pool(4, 1);
|
||||||
auto test_sink = std::make_shared<test_sink_st>();
|
auto test_sink = std::make_shared<test_sink_st>();
|
||||||
@ -139,8 +130,7 @@ TEST_CASE("clone async", "[clone]")
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("default logger API", "[default logger]")
|
TEST_CASE("default logger API", "[default logger]") {
|
||||||
{
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -3,12 +3,10 @@
|
|||||||
using std::chrono::milliseconds;
|
using std::chrono::milliseconds;
|
||||||
using test_clock = std::chrono::high_resolution_clock;
|
using test_clock = std::chrono::high_resolution_clock;
|
||||||
|
|
||||||
static milliseconds millis_from(const test_clock::time_point &tp0)
|
static milliseconds millis_from(const test_clock::time_point &tp0) {
|
||||||
{
|
|
||||||
return std::chrono::duration_cast<milliseconds>(test_clock::now() - tp0);
|
return std::chrono::duration_cast<milliseconds>(test_clock::now() - tp0);
|
||||||
}
|
}
|
||||||
TEST_CASE("dequeue-empty-nowait", "[mpmc_blocking_q]")
|
TEST_CASE("dequeue-empty-nowait", "[mpmc_blocking_q]") {
|
||||||
{
|
|
||||||
size_t q_size = 100;
|
size_t q_size = 100;
|
||||||
milliseconds tolerance_wait(20);
|
milliseconds tolerance_wait(20);
|
||||||
spdlog::details::mpmc_blocking_queue<int> q(q_size);
|
spdlog::details::mpmc_blocking_queue<int> q(q_size);
|
||||||
@ -23,8 +21,7 @@ TEST_CASE("dequeue-empty-nowait", "[mpmc_blocking_q]")
|
|||||||
REQUIRE(delta_ms <= tolerance_wait);
|
REQUIRE(delta_ms <= tolerance_wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("dequeue-empty-wait", "[mpmc_blocking_q]")
|
TEST_CASE("dequeue-empty-wait", "[mpmc_blocking_q]") {
|
||||||
{
|
|
||||||
|
|
||||||
size_t q_size = 100;
|
size_t q_size = 100;
|
||||||
milliseconds wait_ms(250);
|
milliseconds wait_ms(250);
|
||||||
@ -43,8 +40,7 @@ TEST_CASE("dequeue-empty-wait", "[mpmc_blocking_q]")
|
|||||||
REQUIRE(delta_ms <= wait_ms + tolerance_wait);
|
REQUIRE(delta_ms <= wait_ms + tolerance_wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("dequeue-full-nowait", "[mpmc_blocking_q]")
|
TEST_CASE("dequeue-full-nowait", "[mpmc_blocking_q]") {
|
||||||
{
|
|
||||||
spdlog::details::mpmc_blocking_queue<int> q(1);
|
spdlog::details::mpmc_blocking_queue<int> q(1);
|
||||||
q.enqueue(42);
|
q.enqueue(42);
|
||||||
|
|
||||||
@ -53,8 +49,7 @@ TEST_CASE("dequeue-full-nowait", "[mpmc_blocking_q]")
|
|||||||
REQUIRE(item == 42);
|
REQUIRE(item == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("dequeue-full-wait", "[mpmc_blocking_q]")
|
TEST_CASE("dequeue-full-wait", "[mpmc_blocking_q]") {
|
||||||
{
|
|
||||||
spdlog::details::mpmc_blocking_queue<int> q(1);
|
spdlog::details::mpmc_blocking_queue<int> q(1);
|
||||||
q.enqueue(42);
|
q.enqueue(42);
|
||||||
|
|
||||||
@ -63,8 +58,7 @@ TEST_CASE("dequeue-full-wait", "[mpmc_blocking_q]")
|
|||||||
REQUIRE(item == 42);
|
REQUIRE(item == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("enqueue_nowait", "[mpmc_blocking_q]")
|
TEST_CASE("enqueue_nowait", "[mpmc_blocking_q]") {
|
||||||
{
|
|
||||||
|
|
||||||
size_t q_size = 1;
|
size_t q_size = 1;
|
||||||
spdlog::details::mpmc_blocking_queue<int> q(q_size);
|
spdlog::details::mpmc_blocking_queue<int> q(q_size);
|
||||||
@ -82,8 +76,7 @@ TEST_CASE("enqueue_nowait", "[mpmc_blocking_q]")
|
|||||||
REQUIRE(q.overrun_counter() == 1);
|
REQUIRE(q.overrun_counter() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("bad_queue", "[mpmc_blocking_q]")
|
TEST_CASE("bad_queue", "[mpmc_blocking_q]") {
|
||||||
{
|
|
||||||
size_t q_size = 0;
|
size_t q_size = 0;
|
||||||
spdlog::details::mpmc_blocking_queue<int> q(q_size);
|
spdlog::details::mpmc_blocking_queue<int> q(q_size);
|
||||||
q.enqueue_nowait(1);
|
q.enqueue_nowait(1);
|
||||||
@ -92,28 +85,25 @@ TEST_CASE("bad_queue", "[mpmc_blocking_q]")
|
|||||||
REQUIRE(q.dequeue_for(i, milliseconds(0)) == false);
|
REQUIRE(q.dequeue_for(i, milliseconds(0)) == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("empty_queue", "[mpmc_blocking_q]")
|
TEST_CASE("empty_queue", "[mpmc_blocking_q]") {
|
||||||
{
|
|
||||||
size_t q_size = 10;
|
size_t q_size = 10;
|
||||||
spdlog::details::mpmc_blocking_queue<int> q(q_size);
|
spdlog::details::mpmc_blocking_queue<int> q(q_size);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
REQUIRE(q.dequeue_for(i, milliseconds(10)) == false);
|
REQUIRE(q.dequeue_for(i, milliseconds(10)) == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("full_queue", "[mpmc_blocking_q]")
|
TEST_CASE("full_queue", "[mpmc_blocking_q]") {
|
||||||
{
|
|
||||||
size_t q_size = 100;
|
size_t q_size = 100;
|
||||||
spdlog::details::mpmc_blocking_queue<int> q(q_size);
|
spdlog::details::mpmc_blocking_queue<int> q(q_size);
|
||||||
for (int i = 0; i < static_cast<int>(q_size); i++)
|
for (int i = 0; i < static_cast<int>(q_size); i++) {
|
||||||
{
|
q.enqueue(i + 0); // i+0 to force rvalue and avoid tidy warnings on the same time if we
|
||||||
q.enqueue(i + 0); // i+0 to force rvalue and avoid tidy warnings on the same time if we std::move(i) instead
|
// std::move(i) instead
|
||||||
}
|
}
|
||||||
|
|
||||||
q.enqueue_nowait(123456);
|
q.enqueue_nowait(123456);
|
||||||
REQUIRE(q.overrun_counter() == 1);
|
REQUIRE(q.overrun_counter() == 1);
|
||||||
|
|
||||||
for (int i = 1; i < static_cast<int>(q_size); i++)
|
for (int i = 1; i < static_cast<int>(q_size); i++) {
|
||||||
{
|
|
||||||
int item = -1;
|
int item = -1;
|
||||||
q.dequeue(item);
|
q.dequeue(item);
|
||||||
REQUIRE(item == i);
|
REQUIRE(item == i);
|
||||||
|
@ -5,79 +5,78 @@ using spdlog::memory_buf_t;
|
|||||||
using spdlog::details::to_string_view;
|
using spdlog::details::to_string_view;
|
||||||
|
|
||||||
// log to str and return it
|
// log to str and return it
|
||||||
template<typename... Args>
|
template <typename... Args>
|
||||||
static std::string log_to_str(const std::string &msg, const Args &...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);
|
||||||
|
|
||||||
oss_logger.set_formatter(std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(args...)));
|
oss_logger.set_formatter(
|
||||||
|
std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(args...)));
|
||||||
|
|
||||||
oss_logger.info(msg);
|
oss_logger.info(msg);
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("custom eol", "[pattern_formatter]")
|
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 = ";)";
|
||||||
REQUIRE(log_to_str(msg, "%v", spdlog::pattern_time_type::local, ";)") == 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]") {
|
||||||
{
|
|
||||||
REQUIRE(log_to_str("Some message", "", spdlog::pattern_time_type::local, "").empty());
|
REQUIRE(log_to_str("Some message", "", spdlog::pattern_time_type::local, "").empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("empty format2", "[pattern_formatter]")
|
TEST_CASE("empty format2", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
REQUIRE(log_to_str("Some message", "", spdlog::pattern_time_type::local, "\n") == "\n");
|
REQUIRE(log_to_str("Some message", "", spdlog::pattern_time_type::local, "\n") == "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("level", "[pattern_formatter]")
|
TEST_CASE("level", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%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");
|
"[info] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("short level", "[pattern_formatter]")
|
TEST_CASE("short level", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%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");
|
"[I] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("name", "[pattern_formatter]")
|
TEST_CASE("name", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%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");
|
"[pattern_tester] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("date MM/DD/YY ", "[pattern_formatter]")
|
TEST_CASE("date MM/DD/YY ", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
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_year + 1900) % 1000 << " Some message\n";
|
<< now_tm.tm_mday << "/" << std::setw(2) << (now_tm.tm_year + 1900) % 1000
|
||||||
REQUIRE(log_to_str("Some message", "%D %v", spdlog::pattern_time_type::local, "\n") == oss.str());
|
<< " Some message\n";
|
||||||
|
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]") {
|
||||||
{
|
auto formatter = std::make_shared<spdlog::pattern_formatter>(
|
||||||
auto formatter = std::make_shared<spdlog::pattern_formatter>("%^%v%$", spdlog::pattern_time_type::local, "\n");
|
"%^%v%$", spdlog::pattern_time_type::local, "\n");
|
||||||
|
|
||||||
memory_buf_t buf;
|
memory_buf_t buf;
|
||||||
spdlog::fmt_lib::format_to(std::back_inserter(buf), "Hello");
|
spdlog::fmt_lib::format_to(std::back_inserter(buf), "Hello");
|
||||||
memory_buf_t formatted;
|
memory_buf_t formatted;
|
||||||
std::string logger_name = "test";
|
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);
|
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", "%^%v%$", spdlog::pattern_time_type::local, "\n") == "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 =
|
||||||
auto formatter = std::make_shared<spdlog::pattern_formatter>("%^%$", spdlog::pattern_time_type::local, "\n");
|
std::make_shared<spdlog::pattern_formatter>("%^%$", spdlog::pattern_time_type::local, "\n");
|
||||||
std::string logger_name = "test";
|
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;
|
memory_buf_t formatted;
|
||||||
@ -87,8 +86,7 @@ TEST_CASE("color range test2", "[pattern_formatter]")
|
|||||||
REQUIRE(log_to_str("", "%^%$", spdlog::pattern_time_type::local, "\n") == "\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>("%^***%$");
|
||||||
std::string logger_name = "test";
|
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");
|
||||||
@ -98,9 +96,9 @@ TEST_CASE("color range test3", "[pattern_formatter]")
|
|||||||
REQUIRE(msg.color_range_end == 3);
|
REQUIRE(msg.color_range_end == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("color range test4", "[pattern_formatter]")
|
TEST_CASE("color range test4", "[pattern_formatter]") {
|
||||||
{
|
auto formatter = std::make_shared<spdlog::pattern_formatter>(
|
||||||
auto formatter = std::make_shared<spdlog::pattern_formatter>("XX%^YYY%$", spdlog::pattern_time_type::local, "\n");
|
"XX%^YYY%$", spdlog::pattern_time_type::local, "\n");
|
||||||
std::string logger_name = "test";
|
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");
|
||||||
|
|
||||||
@ -108,11 +106,11 @@ TEST_CASE("color range test4", "[pattern_formatter]")
|
|||||||
formatter->format(msg, 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", "XX%^YYY%$", spdlog::pattern_time_type::local, "\n") == "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>("**%^");
|
||||||
std::string logger_name = "test";
|
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");
|
||||||
@ -122,8 +120,7 @@ TEST_CASE("color range test5", "[pattern_formatter]")
|
|||||||
REQUIRE(msg.color_range_end == 0);
|
REQUIRE(msg.color_range_end == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("color range test6", "[pattern_formatter]")
|
TEST_CASE("color range test6", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
auto formatter = std::make_shared<spdlog::pattern_formatter>("**%$");
|
auto formatter = std::make_shared<spdlog::pattern_formatter>("**%$");
|
||||||
std::string logger_name = "test";
|
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");
|
||||||
@ -137,62 +134,70 @@ TEST_CASE("color range test6", "[pattern_formatter]")
|
|||||||
// Test padding
|
// Test padding
|
||||||
//
|
//
|
||||||
|
|
||||||
TEST_CASE("level_left_padded", "[pattern_formatter]")
|
TEST_CASE("level_left_padded", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%8l] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
REQUIRE(log_to_str("Some message", "[%8l] %v", spdlog::pattern_time_type::local, "\n") == "[ info] Some message\n");
|
"[ info] Some message\n");
|
||||||
REQUIRE(log_to_str("Some message", "[%8!l] %v", spdlog::pattern_time_type::local, "\n") == "[ info] Some message\n");
|
REQUIRE(log_to_str("Some message", "[%8!l] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
|
"[ info] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("level_right_padded", "[pattern_formatter]")
|
TEST_CASE("level_right_padded", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%-8l] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
REQUIRE(log_to_str("Some message", "[%-8l] %v", spdlog::pattern_time_type::local, "\n") == "[info ] Some message\n");
|
"[info ] Some message\n");
|
||||||
REQUIRE(log_to_str("Some message", "[%-8!l] %v", spdlog::pattern_time_type::local, "\n") == "[info ] Some message\n");
|
REQUIRE(log_to_str("Some message", "[%-8!l] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
|
"[info ] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("level_center_padded", "[pattern_formatter]")
|
TEST_CASE("level_center_padded", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%=8l] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
REQUIRE(log_to_str("Some message", "[%=8l] %v", spdlog::pattern_time_type::local, "\n") == "[ info ] Some message\n");
|
"[ info ] Some message\n");
|
||||||
REQUIRE(log_to_str("Some message", "[%=8!l] %v", spdlog::pattern_time_type::local, "\n") == "[ info ] Some message\n");
|
REQUIRE(log_to_str("Some message", "[%=8!l] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
|
"[ info ] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("short level_left_padded", "[pattern_formatter]")
|
TEST_CASE("short level_left_padded", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%3L] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
REQUIRE(log_to_str("Some message", "[%3L] %v", spdlog::pattern_time_type::local, "\n") == "[ I] Some message\n");
|
"[ I] Some message\n");
|
||||||
REQUIRE(log_to_str("Some message", "[%3!L] %v", spdlog::pattern_time_type::local, "\n") == "[ I] Some message\n");
|
REQUIRE(log_to_str("Some message", "[%3!L] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
|
"[ I] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("short level_right_padded", "[pattern_formatter]")
|
TEST_CASE("short level_right_padded", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%-3L] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
REQUIRE(log_to_str("Some message", "[%-3L] %v", spdlog::pattern_time_type::local, "\n") == "[I ] Some message\n");
|
"[I ] Some message\n");
|
||||||
REQUIRE(log_to_str("Some message", "[%-3!L] %v", spdlog::pattern_time_type::local, "\n") == "[I ] Some message\n");
|
REQUIRE(log_to_str("Some message", "[%-3!L] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
|
"[I ] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("short level_center_padded", "[pattern_formatter]")
|
TEST_CASE("short level_center_padded", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%=3L] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
REQUIRE(log_to_str("Some message", "[%=3L] %v", spdlog::pattern_time_type::local, "\n") == "[ I ] Some message\n");
|
"[ I ] Some message\n");
|
||||||
REQUIRE(log_to_str("Some message", "[%=3!L] %v", spdlog::pattern_time_type::local, "\n") == "[ I ] Some message\n");
|
REQUIRE(log_to_str("Some message", "[%=3!L] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
|
"[ I ] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("left_padded_short", "[pattern_formatter]")
|
TEST_CASE("left_padded_short", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%3n] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
REQUIRE(log_to_str("Some message", "[%3n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n");
|
"[pattern_tester] Some message\n");
|
||||||
REQUIRE(log_to_str("Some message", "[%3!n] %v", spdlog::pattern_time_type::local, "\n") == "[pat] Some message\n");
|
REQUIRE(log_to_str("Some message", "[%3!n] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
|
"[pat] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("right_padded_short", "[pattern_formatter]")
|
TEST_CASE("right_padded_short", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%-3n] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
REQUIRE(log_to_str("Some message", "[%-3n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n");
|
"[pattern_tester] Some message\n");
|
||||||
REQUIRE(log_to_str("Some message", "[%-3!n] %v", spdlog::pattern_time_type::local, "\n") == "[pat] Some message\n");
|
REQUIRE(log_to_str("Some message", "[%-3!n] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
|
"[pat] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("center_padded_short", "[pattern_formatter]")
|
TEST_CASE("center_padded_short", "[pattern_formatter]") {
|
||||||
{
|
REQUIRE(log_to_str("Some message", "[%=3n] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
REQUIRE(log_to_str("Some message", "[%=3n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n");
|
"[pattern_tester] Some message\n");
|
||||||
REQUIRE(log_to_str("Some message", "[%=3!n] %v", spdlog::pattern_time_type::local, "\n") == "[pat] Some message\n");
|
REQUIRE(log_to_str("Some message", "[%=3!n] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
|
"[pat] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("left_padded_huge", "[pattern_formatter]")
|
TEST_CASE("left_padded_huge", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
REQUIRE(log_to_str("Some message", "[%-300n] %v", spdlog::pattern_time_type::local, "\n") ==
|
REQUIRE(log_to_str("Some message", "[%-300n] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
"[pattern_tester ] Some message\n");
|
"[pattern_tester ] Some message\n");
|
||||||
|
|
||||||
@ -200,8 +205,7 @@ TEST_CASE("left_padded_huge", "[pattern_formatter]")
|
|||||||
"[pattern_tester ] Some message\n");
|
"[pattern_tester ] Some message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("left_padded_max", "[pattern_formatter]")
|
TEST_CASE("left_padded_max", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
REQUIRE(log_to_str("Some message", "[%-64n] %v", spdlog::pattern_time_type::local, "\n") ==
|
REQUIRE(log_to_str("Some message", "[%-64n] %v", spdlog::pattern_time_type::local, "\n") ==
|
||||||
"[pattern_tester ] Some message\n");
|
"[pattern_tester ] Some message\n");
|
||||||
|
|
||||||
@ -211,8 +215,7 @@ TEST_CASE("left_padded_max", "[pattern_formatter]")
|
|||||||
|
|
||||||
// Test padding + truncate flag
|
// Test padding + truncate flag
|
||||||
|
|
||||||
TEST_CASE("paddinng_truncate", "[pattern_formatter]")
|
TEST_CASE("paddinng_truncate", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
REQUIRE(log_to_str("123456", "%6!v", spdlog::pattern_time_type::local, "\n") == "123456\n");
|
REQUIRE(log_to_str("123456", "%6!v", spdlog::pattern_time_type::local, "\n") == "123456\n");
|
||||||
REQUIRE(log_to_str("123456", "%5!v", spdlog::pattern_time_type::local, "\n") == "12345\n");
|
REQUIRE(log_to_str("123456", "%5!v", spdlog::pattern_time_type::local, "\n") == "12345\n");
|
||||||
REQUIRE(log_to_str("123456", "%7!v", spdlog::pattern_time_type::local, "\n") == " 123456\n");
|
REQUIRE(log_to_str("123456", "%7!v", spdlog::pattern_time_type::local, "\n") == " 123456\n");
|
||||||
@ -228,42 +231,43 @@ TEST_CASE("paddinng_truncate", "[pattern_formatter]")
|
|||||||
REQUIRE(log_to_str("123456", "%0!v", spdlog::pattern_time_type::local, "\n") == "\n");
|
REQUIRE(log_to_str("123456", "%0!v", spdlog::pattern_time_type::local, "\n") == "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("padding_truncate_funcname", "[pattern_formatter]")
|
TEST_CASE("padding_truncate_funcname", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
spdlog::sinks::test_sink_st test_sink;
|
spdlog::sinks::test_sink_st test_sink;
|
||||||
|
|
||||||
const char *pattern = "%v [%5!!]";
|
const char *pattern = "%v [%5!!]";
|
||||||
auto formatter = std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(pattern));
|
auto formatter = std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(pattern));
|
||||||
test_sink.set_formatter(std::move(formatter));
|
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);
|
test_sink.log(msg1);
|
||||||
REQUIRE(test_sink.lines()[0] == "message [ func]");
|
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);
|
test_sink.log(msg2);
|
||||||
REQUIRE(test_sink.lines()[1] == "message [funct]");
|
REQUIRE(test_sink.lines()[1] == "message [funct]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("padding_funcname", "[pattern_formatter]")
|
TEST_CASE("padding_funcname", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
spdlog::sinks::test_sink_st test_sink;
|
spdlog::sinks::test_sink_st test_sink;
|
||||||
|
|
||||||
const char *pattern = "%v [%10!]";
|
const char *pattern = "%v [%10!]";
|
||||||
auto formatter = std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(pattern));
|
auto formatter = std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(pattern));
|
||||||
test_sink.set_formatter(std::move(formatter));
|
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);
|
test_sink.log(msg1);
|
||||||
REQUIRE(test_sink.lines()[0] == "message [ func]");
|
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);
|
test_sink.log(msg2);
|
||||||
REQUIRE(test_sink.lines()[1] == "message [func567890123]");
|
REQUIRE(test_sink.lines()[1] == "message [func567890123]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("clone-default-formatter", "[pattern_formatter]")
|
TEST_CASE("clone-default-formatter", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>();
|
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>();
|
||||||
auto formatter_2 = formatter_1->clone();
|
auto formatter_2 = formatter_1->clone();
|
||||||
std::string logger_name = "test";
|
std::string logger_name = "test";
|
||||||
@ -277,8 +281,7 @@ TEST_CASE("clone-default-formatter", "[pattern_formatter]")
|
|||||||
REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2));
|
REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("clone-default-formatter2", "[pattern_formatter]")
|
TEST_CASE("clone-default-formatter2", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%+");
|
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%+");
|
||||||
auto formatter_2 = formatter_1->clone();
|
auto formatter_2 = formatter_1->clone();
|
||||||
std::string logger_name = "test";
|
std::string logger_name = "test";
|
||||||
@ -292,8 +295,7 @@ TEST_CASE("clone-default-formatter2", "[pattern_formatter]")
|
|||||||
REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2));
|
REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("clone-formatter", "[pattern_formatter]")
|
TEST_CASE("clone-formatter", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%D %X [%] [%n] %v");
|
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%D %X [%] [%n] %v");
|
||||||
auto formatter_2 = formatter_1->clone();
|
auto formatter_2 = formatter_1->clone();
|
||||||
std::string logger_name = "test";
|
std::string logger_name = "test";
|
||||||
@ -307,10 +309,10 @@ TEST_CASE("clone-formatter", "[pattern_formatter]")
|
|||||||
REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2));
|
REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("clone-formatter-2", "[pattern_formatter]")
|
TEST_CASE("clone-formatter-2", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
using spdlog::pattern_time_type;
|
using spdlog::pattern_time_type;
|
||||||
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%D %X [%] [%n] %v", pattern_time_type::utc, "xxxxxx\n");
|
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();
|
auto formatter_2 = formatter_1->clone();
|
||||||
std::string logger_name = "test2";
|
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");
|
||||||
@ -323,43 +325,35 @@ TEST_CASE("clone-formatter-2", "[pattern_formatter]")
|
|||||||
REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2));
|
REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
class custom_test_flag : public spdlog::custom_flag_formatter
|
class custom_test_flag : public spdlog::custom_flag_formatter {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit custom_test_flag(std::string txt)
|
explicit custom_test_flag(std::string txt)
|
||||||
: some_txt{std::move(txt)}
|
: some_txt{std::move(txt)} {}
|
||||||
{}
|
|
||||||
|
|
||||||
void format(const spdlog::details::log_msg &, const std::tm &tm, spdlog::memory_buf_t &dest) override
|
void format(const spdlog::details::log_msg &,
|
||||||
{
|
const std::tm &tm,
|
||||||
if (some_txt == "throw_me")
|
spdlog::memory_buf_t &dest) override {
|
||||||
{
|
if (some_txt == "throw_me") {
|
||||||
throw spdlog::spdlog_ex("custom_flag_exception_test");
|
throw spdlog::spdlog_ex("custom_flag_exception_test");
|
||||||
}
|
} else if (some_txt == "time") {
|
||||||
else if (some_txt == "time")
|
auto formatted = spdlog::fmt_lib::format("{:d}:{:02d}{:s}", tm.tm_hour % 12, tm.tm_min,
|
||||||
{
|
tm.tm_hour / 12 ? "PM" : "AM");
|
||||||
auto formatted = spdlog::fmt_lib::format("{:d}:{:02d}{:s}", tm.tm_hour % 12, tm.tm_min, tm.tm_hour / 12 ? "PM" : "AM");
|
|
||||||
dest.append(formatted.data(), formatted.data() + formatted.size());
|
dest.append(formatted.data(), formatted.data() + formatted.size());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
some_txt = std::string(padinfo_.width_, ' ') + some_txt;
|
some_txt = std::string(padinfo_.width_, ' ') + some_txt;
|
||||||
dest.append(some_txt.data(), some_txt.data() + some_txt.size());
|
dest.append(some_txt.data(), some_txt.data() + some_txt.size());
|
||||||
}
|
}
|
||||||
spdlog::details::padding_info get_padding_info()
|
spdlog::details::padding_info get_padding_info() { return padinfo_; }
|
||||||
{
|
|
||||||
return padinfo_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string some_txt;
|
std::string some_txt;
|
||||||
|
|
||||||
std::unique_ptr<custom_flag_formatter> clone() const override
|
std::unique_ptr<custom_flag_formatter> clone() const override {
|
||||||
{
|
|
||||||
return spdlog::details::make_unique<custom_test_flag>(some_txt);
|
return spdlog::details::make_unique<custom_test_flag>(some_txt);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// test clone with custom flag formatters
|
// test clone with custom flag formatters
|
||||||
TEST_CASE("clone-custom_formatter", "[pattern_formatter]")
|
TEST_CASE("clone-custom_formatter", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>();
|
auto formatter_1 = std::make_shared<spdlog::pattern_formatter>();
|
||||||
formatter_1->add_flag<custom_test_flag>('t', "custom_output").set_pattern("[%n] [%t] %v");
|
formatter_1->add_flag<custom_test_flag>('t', "custom_output").set_pattern("[%n] [%t] %v");
|
||||||
auto formatter_2 = formatter_1->clone();
|
auto formatter_2 = formatter_1->clone();
|
||||||
@ -371,7 +365,8 @@ TEST_CASE("clone-custom_formatter", "[pattern_formatter]")
|
|||||||
formatter_1->format(msg, formatted_1);
|
formatter_1->format(msg, formatted_1);
|
||||||
formatter_2->format(msg, formatted_2);
|
formatter_2->format(msg, formatted_2);
|
||||||
|
|
||||||
auto expected = spdlog::fmt_lib::format("[logger-name] [custom_output] some message{}", spdlog::details::os::default_eol);
|
auto expected = spdlog::fmt_lib::format("[logger-name] [custom_output] some message{}",
|
||||||
|
spdlog::details::os::default_eol);
|
||||||
|
|
||||||
REQUIRE(to_string_view(formatted_1) == expected);
|
REQUIRE(to_string_view(formatted_1) == expected);
|
||||||
REQUIRE(to_string_view(formatted_2) == expected);
|
REQUIRE(to_string_view(formatted_2) == expected);
|
||||||
@ -387,8 +382,7 @@ static const char *const test_path = "\\a\\b\\c/myfile.cpp";
|
|||||||
static const char *const test_path = "/a/b//myfile.cpp";
|
static const char *const test_path = "/a/b//myfile.cpp";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_CASE("short filename formatter-1", "[pattern_formatter]")
|
TEST_CASE("short filename formatter-1", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
spdlog::pattern_formatter formatter("%s", spdlog::pattern_time_type::local, "");
|
spdlog::pattern_formatter formatter("%s", spdlog::pattern_time_type::local, "");
|
||||||
memory_buf_t formatted;
|
memory_buf_t formatted;
|
||||||
std::string logger_name = "logger-name";
|
std::string logger_name = "logger-name";
|
||||||
@ -399,8 +393,7 @@ TEST_CASE("short filename formatter-1", "[pattern_formatter]")
|
|||||||
REQUIRE(to_string_view(formatted) == "myfile.cpp");
|
REQUIRE(to_string_view(formatted) == "myfile.cpp");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("short filename formatter-2", "[pattern_formatter]")
|
TEST_CASE("short filename formatter-2", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
spdlog::pattern_formatter formatter("%s:%#", spdlog::pattern_time_type::local, "");
|
spdlog::pattern_formatter formatter("%s:%#", spdlog::pattern_time_type::local, "");
|
||||||
memory_buf_t formatted;
|
memory_buf_t formatted;
|
||||||
std::string logger_name = "logger-name";
|
std::string logger_name = "logger-name";
|
||||||
@ -411,8 +404,7 @@ TEST_CASE("short filename formatter-2", "[pattern_formatter]")
|
|||||||
REQUIRE(to_string_view(formatted) == "myfile.cpp:123");
|
REQUIRE(to_string_view(formatted) == "myfile.cpp:123");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("short filename formatter-3", "[pattern_formatter]")
|
TEST_CASE("short filename formatter-3", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
spdlog::pattern_formatter formatter("%s %v", spdlog::pattern_time_type::local, "");
|
spdlog::pattern_formatter formatter("%s %v", spdlog::pattern_time_type::local, "");
|
||||||
memory_buf_t formatted;
|
memory_buf_t formatted;
|
||||||
std::string logger_name = "logger-name";
|
std::string logger_name = "logger-name";
|
||||||
@ -423,8 +415,7 @@ TEST_CASE("short filename formatter-3", "[pattern_formatter]")
|
|||||||
REQUIRE(to_string_view(formatted) == " Hello");
|
REQUIRE(to_string_view(formatted) == " Hello");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("full filename formatter", "[pattern_formatter]")
|
TEST_CASE("full filename formatter", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
spdlog::pattern_formatter formatter("%g", spdlog::pattern_time_type::local, "");
|
spdlog::pattern_formatter formatter("%g", spdlog::pattern_time_type::local, "");
|
||||||
memory_buf_t formatted;
|
memory_buf_t formatted;
|
||||||
std::string logger_name = "logger-name";
|
std::string logger_name = "logger-name";
|
||||||
@ -435,52 +426,61 @@ TEST_CASE("full filename formatter", "[pattern_formatter]")
|
|||||||
REQUIRE(to_string_view(formatted) == test_path);
|
REQUIRE(to_string_view(formatted) == test_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("custom flags", "[pattern_formatter]")
|
TEST_CASE("custom flags", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
auto formatter = std::make_shared<spdlog::pattern_formatter>();
|
auto formatter = std::make_shared<spdlog::pattern_formatter>();
|
||||||
formatter->add_flag<custom_test_flag>('t', "custom1").add_flag<custom_test_flag>('u', "custom2").set_pattern("[%n] [%t] [%u] %v");
|
formatter->add_flag<custom_test_flag>('t', "custom1")
|
||||||
|
.add_flag<custom_test_flag>('u', "custom2")
|
||||||
|
.set_pattern("[%n] [%t] [%u] %v");
|
||||||
|
|
||||||
memory_buf_t formatted;
|
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);
|
formatter->format(msg, formatted);
|
||||||
auto expected = spdlog::fmt_lib::format("[logger-name] [custom1] [custom2] some message{}", spdlog::details::os::default_eol);
|
auto expected = spdlog::fmt_lib::format("[logger-name] [custom1] [custom2] some message{}",
|
||||||
|
spdlog::details::os::default_eol);
|
||||||
|
|
||||||
REQUIRE(to_string_view(formatted) == expected);
|
REQUIRE(to_string_view(formatted) == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("custom flags-padding", "[pattern_formatter]")
|
TEST_CASE("custom flags-padding", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
auto formatter = std::make_shared<spdlog::pattern_formatter>();
|
auto formatter = std::make_shared<spdlog::pattern_formatter>();
|
||||||
formatter->add_flag<custom_test_flag>('t', "custom1").add_flag<custom_test_flag>('u', "custom2").set_pattern("[%n] [%t] [%5u] %v");
|
formatter->add_flag<custom_test_flag>('t', "custom1")
|
||||||
|
.add_flag<custom_test_flag>('u', "custom2")
|
||||||
|
.set_pattern("[%n] [%t] [%5u] %v");
|
||||||
|
|
||||||
memory_buf_t formatted;
|
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);
|
formatter->format(msg, formatted);
|
||||||
auto expected = spdlog::fmt_lib::format("[logger-name] [custom1] [ custom2] some message{}", spdlog::details::os::default_eol);
|
auto expected = spdlog::fmt_lib::format("[logger-name] [custom1] [ custom2] some message{}",
|
||||||
|
spdlog::details::os::default_eol);
|
||||||
|
|
||||||
REQUIRE(to_string_view(formatted) == expected);
|
REQUIRE(to_string_view(formatted) == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("custom flags-exception", "[pattern_formatter]")
|
TEST_CASE("custom flags-exception", "[pattern_formatter]") {
|
||||||
{
|
|
||||||
auto formatter = std::make_shared<spdlog::pattern_formatter>();
|
auto formatter = std::make_shared<spdlog::pattern_formatter>();
|
||||||
formatter->add_flag<custom_test_flag>('t', "throw_me").add_flag<custom_test_flag>('u', "custom2").set_pattern("[%n] [%t] [%u] %v");
|
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;
|
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);
|
CHECK_THROWS_AS(formatter->format(msg, formatted), spdlog::spdlog_ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("override need_localtime", "[pattern_formatter]")
|
TEST_CASE("override need_localtime", "[pattern_formatter]") {
|
||||||
{
|
auto formatter =
|
||||||
auto formatter = std::make_shared<spdlog::pattern_formatter>(spdlog::pattern_time_type::local, "\n");
|
std::make_shared<spdlog::pattern_formatter>(spdlog::pattern_time_type::local, "\n");
|
||||||
formatter->add_flag<custom_test_flag>('t', "time").set_pattern("%t> %v");
|
formatter->add_flag<custom_test_flag>('t', "time").set_pattern("%t> %v");
|
||||||
|
|
||||||
{
|
{
|
||||||
memory_buf_t formatted;
|
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);
|
formatter->format(msg, formatted);
|
||||||
REQUIRE(to_string_view(formatted) == "0:00AM> some message\n");
|
REQUIRE(to_string_view(formatted) == "0:00AM> some message\n");
|
||||||
}
|
}
|
||||||
@ -490,11 +490,12 @@ TEST_CASE("override need_localtime", "[pattern_formatter]")
|
|||||||
|
|
||||||
auto now_tm = spdlog::details::os::localtime();
|
auto now_tm = spdlog::details::os::localtime();
|
||||||
std::stringstream oss;
|
std::stringstream oss;
|
||||||
oss << (now_tm.tm_hour % 12) << ":" << std::setfill('0') << std::setw(2) << now_tm.tm_min << (now_tm.tm_hour / 12 ? "PM" : "AM")
|
oss << (now_tm.tm_hour % 12) << ":" << std::setfill('0') << std::setw(2) << now_tm.tm_min
|
||||||
<< "> some message\n";
|
<< (now_tm.tm_hour / 12 ? "PM" : "AM") << "> some message\n";
|
||||||
|
|
||||||
memory_buf_t formatted;
|
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);
|
formatter->format(msg, formatted);
|
||||||
REQUIRE(to_string_view(formatted) == oss.str());
|
REQUIRE(to_string_view(formatted) == oss.str());
|
||||||
}
|
}
|
||||||
|
@ -4,32 +4,34 @@ static const char *const tested_logger_name = "null_logger";
|
|||||||
static const char *const tested_logger_name2 = "null_logger2";
|
static const char *const tested_logger_name2 = "null_logger2";
|
||||||
|
|
||||||
#ifndef SPDLOG_NO_EXCEPTIONS
|
#ifndef SPDLOG_NO_EXCEPTIONS
|
||||||
TEST_CASE("register_drop", "[registry]")
|
TEST_CASE("register_drop", "[registry]") {
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
||||||
REQUIRE(spdlog::get(tested_logger_name) != nullptr);
|
REQUIRE(spdlog::get(tested_logger_name) != nullptr);
|
||||||
// Throw if registering existing name
|
// Throw if registering existing name
|
||||||
REQUIRE_THROWS_AS(spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name), spdlog::spdlog_ex);
|
REQUIRE_THROWS_AS(spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name),
|
||||||
|
spdlog::spdlog_ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("explicit register", "[registry]")
|
TEST_CASE("explicit register", "[registry]") {
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
auto logger = std::make_shared<spdlog::logger>(tested_logger_name, std::make_shared<spdlog::sinks::null_sink_st>());
|
auto logger = std::make_shared<spdlog::logger>(tested_logger_name,
|
||||||
|
std::make_shared<spdlog::sinks::null_sink_st>());
|
||||||
spdlog::register_logger(logger);
|
spdlog::register_logger(logger);
|
||||||
REQUIRE(spdlog::get(tested_logger_name) != nullptr);
|
REQUIRE(spdlog::get(tested_logger_name) != nullptr);
|
||||||
// Throw if registering existing name
|
// Throw if registering existing name
|
||||||
REQUIRE_THROWS_AS(spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name), spdlog::spdlog_ex);
|
REQUIRE_THROWS_AS(spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name),
|
||||||
|
spdlog::spdlog_ex);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_CASE("apply_all", "[registry]")
|
TEST_CASE("apply_all", "[registry]") {
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
auto logger = std::make_shared<spdlog::logger>(tested_logger_name, std::make_shared<spdlog::sinks::null_sink_st>());
|
auto logger = std::make_shared<spdlog::logger>(tested_logger_name,
|
||||||
|
std::make_shared<spdlog::sinks::null_sink_st>());
|
||||||
spdlog::register_logger(logger);
|
spdlog::register_logger(logger);
|
||||||
auto logger2 = std::make_shared<spdlog::logger>(tested_logger_name2, std::make_shared<spdlog::sinks::null_sink_st>());
|
auto logger2 = std::make_shared<spdlog::logger>(
|
||||||
|
tested_logger_name2, std::make_shared<spdlog::sinks::null_sink_st>());
|
||||||
spdlog::register_logger(logger2);
|
spdlog::register_logger(logger2);
|
||||||
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
@ -45,24 +47,21 @@ TEST_CASE("apply_all", "[registry]")
|
|||||||
REQUIRE(counter == 1);
|
REQUIRE(counter == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("drop", "[registry]")
|
TEST_CASE("drop", "[registry]") {
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
||||||
spdlog::drop(tested_logger_name);
|
spdlog::drop(tested_logger_name);
|
||||||
REQUIRE_FALSE(spdlog::get(tested_logger_name));
|
REQUIRE_FALSE(spdlog::get(tested_logger_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("drop-default", "[registry]")
|
TEST_CASE("drop-default", "[registry]") {
|
||||||
{
|
|
||||||
spdlog::set_default_logger(spdlog::null_logger_st(tested_logger_name));
|
spdlog::set_default_logger(spdlog::null_logger_st(tested_logger_name));
|
||||||
spdlog::drop(tested_logger_name);
|
spdlog::drop(tested_logger_name);
|
||||||
REQUIRE_FALSE(spdlog::default_logger());
|
REQUIRE_FALSE(spdlog::default_logger());
|
||||||
REQUIRE_FALSE(spdlog::get(tested_logger_name));
|
REQUIRE_FALSE(spdlog::get(tested_logger_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("drop_all", "[registry]")
|
TEST_CASE("drop_all", "[registry]") {
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
||||||
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name2);
|
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name2);
|
||||||
@ -72,8 +71,7 @@ TEST_CASE("drop_all", "[registry]")
|
|||||||
REQUIRE_FALSE(spdlog::default_logger());
|
REQUIRE_FALSE(spdlog::default_logger());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("drop non existing", "[registry]")
|
TEST_CASE("drop non existing", "[registry]") {
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
||||||
spdlog::drop("some_name");
|
spdlog::drop("some_name");
|
||||||
@ -82,28 +80,26 @@ TEST_CASE("drop non existing", "[registry]")
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("default logger", "[registry]")
|
TEST_CASE("default logger", "[registry]") {
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
spdlog::set_default_logger(spdlog::null_logger_st(tested_logger_name));
|
spdlog::set_default_logger(spdlog::null_logger_st(tested_logger_name));
|
||||||
REQUIRE(spdlog::get(tested_logger_name) == spdlog::default_logger());
|
REQUIRE(spdlog::get(tested_logger_name) == spdlog::default_logger());
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("set_default_logger(nullptr)", "[registry]")
|
TEST_CASE("set_default_logger(nullptr)", "[registry]") {
|
||||||
{
|
|
||||||
spdlog::set_default_logger(nullptr);
|
spdlog::set_default_logger(nullptr);
|
||||||
REQUIRE_FALSE(spdlog::default_logger());
|
REQUIRE_FALSE(spdlog::default_logger());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("disable automatic registration", "[registry]")
|
TEST_CASE("disable automatic registration", "[registry]") {
|
||||||
{
|
|
||||||
// set some global parameters
|
// set some global parameters
|
||||||
spdlog::level::level_enum log_level = spdlog::level::level_enum::warn;
|
spdlog::level::level_enum log_level = spdlog::level::level_enum::warn;
|
||||||
spdlog::set_level(log_level);
|
spdlog::set_level(log_level);
|
||||||
// but disable automatic registration
|
// but disable automatic registration
|
||||||
spdlog::set_automatic_registration(false);
|
spdlog::set_automatic_registration(false);
|
||||||
auto logger1 = spdlog::create<spdlog::sinks::daily_file_sink_st>(tested_logger_name, SPDLOG_FILENAME_T("filename"), 11, 59);
|
auto logger1 = spdlog::create<spdlog::sinks::daily_file_sink_st>(
|
||||||
|
tested_logger_name, SPDLOG_FILENAME_T("filename"), 11, 59);
|
||||||
auto logger2 = spdlog::create_async<spdlog::sinks::stdout_color_sink_mt>(tested_logger_name2);
|
auto logger2 = spdlog::create_async<spdlog::sinks::stdout_color_sink_mt>(tested_logger_name2);
|
||||||
// loggers should not be part of the registry
|
// loggers should not be part of the registry
|
||||||
REQUIRE_FALSE(spdlog::get(tested_logger_name));
|
REQUIRE_FALSE(spdlog::get(tested_logger_name));
|
||||||
|
@ -15,56 +15,46 @@
|
|||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace sinks {
|
namespace sinks {
|
||||||
|
|
||||||
template<class Mutex>
|
template <class Mutex>
|
||||||
class test_sink : public base_sink<Mutex>
|
class test_sink : public base_sink<Mutex> {
|
||||||
{
|
|
||||||
const size_t lines_to_save = 100;
|
const size_t lines_to_save = 100;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
size_t msg_counter()
|
size_t msg_counter() {
|
||||||
{
|
|
||||||
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
||||||
return msg_counter_;
|
return msg_counter_;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t flush_counter()
|
size_t flush_counter() {
|
||||||
{
|
|
||||||
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
||||||
return flush_counter_;
|
return flush_counter_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_delay(std::chrono::milliseconds delay)
|
void set_delay(std::chrono::milliseconds delay) {
|
||||||
{
|
|
||||||
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
||||||
delay_ = delay;
|
delay_ = delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return last output without the eol
|
// return last output without the eol
|
||||||
std::vector<std::string> lines()
|
std::vector<std::string> lines() {
|
||||||
{
|
|
||||||
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
||||||
return lines_;
|
return lines_;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void sink_it_(const details::log_msg &msg) override
|
void sink_it_(const details::log_msg &msg) override {
|
||||||
{
|
|
||||||
memory_buf_t formatted;
|
memory_buf_t formatted;
|
||||||
base_sink<Mutex>::formatter_->format(msg, formatted);
|
base_sink<Mutex>::formatter_->format(msg, formatted);
|
||||||
// save the line without the eol
|
// save the line without the eol
|
||||||
auto eol_len = strlen(details::os::default_eol);
|
auto eol_len = strlen(details::os::default_eol);
|
||||||
if (lines_.size() < lines_to_save)
|
if (lines_.size() < lines_to_save) {
|
||||||
{
|
|
||||||
lines_.emplace_back(formatted.begin(), formatted.end() - eol_len);
|
lines_.emplace_back(formatted.begin(), formatted.end() - eol_len);
|
||||||
}
|
}
|
||||||
msg_counter_++;
|
msg_counter_++;
|
||||||
std::this_thread::sleep_for(delay_);
|
std::this_thread::sleep_for(delay_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_() override
|
void flush_() override { flush_counter_++; }
|
||||||
{
|
|
||||||
flush_counter_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t msg_counter_{0};
|
size_t msg_counter_{0};
|
||||||
size_t flush_counter_{0};
|
size_t flush_counter_{0};
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
* This content is released under the MIT License as specified in
|
||||||
|
* https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "spdlog/sinks/stdout_sinks.h"
|
#include "spdlog/sinks/stdout_sinks.h"
|
||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
TEST_CASE("stdout_st", "[stdout]")
|
TEST_CASE("stdout_st", "[stdout]") {
|
||||||
{
|
|
||||||
auto l = spdlog::stdout_logger_st("test");
|
auto l = spdlog::stdout_logger_st("test");
|
||||||
l->set_pattern("%+");
|
l->set_pattern("%+");
|
||||||
l->set_level(spdlog::level::trace);
|
l->set_level(spdlog::level::trace);
|
||||||
@ -13,8 +13,7 @@ TEST_CASE("stdout_st", "[stdout]")
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("stdout_mt", "[stdout]")
|
TEST_CASE("stdout_mt", "[stdout]") {
|
||||||
{
|
|
||||||
auto l = spdlog::stdout_logger_mt("test");
|
auto l = spdlog::stdout_logger_mt("test");
|
||||||
l->set_pattern("%+");
|
l->set_pattern("%+");
|
||||||
l->set_level(spdlog::level::debug);
|
l->set_level(spdlog::level::debug);
|
||||||
@ -22,16 +21,14 @@ TEST_CASE("stdout_mt", "[stdout]")
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("stderr_st", "[stderr]")
|
TEST_CASE("stderr_st", "[stderr]") {
|
||||||
{
|
|
||||||
auto l = spdlog::stderr_logger_st("test");
|
auto l = spdlog::stderr_logger_st("test");
|
||||||
l->set_pattern("%+");
|
l->set_pattern("%+");
|
||||||
l->info("Test stderr_st");
|
l->info("Test stderr_st");
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("stderr_mt", "[stderr]")
|
TEST_CASE("stderr_mt", "[stderr]") {
|
||||||
{
|
|
||||||
auto l = spdlog::stderr_logger_mt("test");
|
auto l = spdlog::stderr_logger_mt("test");
|
||||||
l->set_pattern("%+");
|
l->set_pattern("%+");
|
||||||
l->info("Test stderr_mt");
|
l->info("Test stderr_mt");
|
||||||
@ -42,16 +39,14 @@ TEST_CASE("stderr_mt", "[stderr]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
// color loggers
|
// color loggers
|
||||||
TEST_CASE("stdout_color_st", "[stdout]")
|
TEST_CASE("stdout_color_st", "[stdout]") {
|
||||||
{
|
|
||||||
auto l = spdlog::stdout_color_st("test");
|
auto l = spdlog::stdout_color_st("test");
|
||||||
l->set_pattern("%+");
|
l->set_pattern("%+");
|
||||||
l->info("Test stdout_color_st");
|
l->info("Test stdout_color_st");
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("stdout_color_mt", "[stdout]")
|
TEST_CASE("stdout_color_mt", "[stdout]") {
|
||||||
{
|
|
||||||
auto l = spdlog::stdout_color_mt("test");
|
auto l = spdlog::stdout_color_mt("test");
|
||||||
l->set_pattern("%+");
|
l->set_pattern("%+");
|
||||||
l->set_level(spdlog::level::trace);
|
l->set_level(spdlog::level::trace);
|
||||||
@ -59,8 +54,7 @@ TEST_CASE("stdout_color_mt", "[stdout]")
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("stderr_color_st", "[stderr]")
|
TEST_CASE("stderr_color_st", "[stderr]") {
|
||||||
{
|
|
||||||
auto l = spdlog::stderr_color_st("test");
|
auto l = spdlog::stderr_color_st("test");
|
||||||
l->set_pattern("%+");
|
l->set_pattern("%+");
|
||||||
l->set_level(spdlog::level::debug);
|
l->set_level(spdlog::level::debug);
|
||||||
@ -68,8 +62,7 @@ TEST_CASE("stderr_color_st", "[stderr]")
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("stderr_color_mt", "[stderr]")
|
TEST_CASE("stderr_color_mt", "[stderr]") {
|
||||||
{
|
|
||||||
auto l = spdlog::stderr_color_mt("test");
|
auto l = spdlog::stderr_color_mt("test");
|
||||||
l->set_pattern("%+");
|
l->set_pattern("%+");
|
||||||
l->info("Test stderr_color_mt");
|
l->info("Test stderr_color_mt");
|
||||||
@ -81,8 +74,7 @@ TEST_CASE("stderr_color_mt", "[stderr]")
|
|||||||
|
|
||||||
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||||
|
|
||||||
TEST_CASE("wchar_api", "[stdout]")
|
TEST_CASE("wchar_api", "[stdout]") {
|
||||||
{
|
|
||||||
auto l = spdlog::stdout_logger_st("wchar_logger");
|
auto l = spdlog::stdout_logger_st("wchar_logger");
|
||||||
l->set_pattern("%+");
|
l->set_pattern("%+");
|
||||||
l->set_level(spdlog::level::trace);
|
l->set_level(spdlog::level::trace);
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
#include "test_sink.h"
|
#include "test_sink.h"
|
||||||
#include "spdlog/stopwatch.h"
|
#include "spdlog/stopwatch.h"
|
||||||
|
|
||||||
TEST_CASE("stopwatch1", "[stopwatch]")
|
TEST_CASE("stopwatch1", "[stopwatch]") {
|
||||||
{
|
|
||||||
using std::chrono::milliseconds;
|
using std::chrono::milliseconds;
|
||||||
using clock = std::chrono::steady_clock;
|
using clock = std::chrono::steady_clock;
|
||||||
milliseconds wait_ms(200);
|
milliseconds wait_ms(200);
|
||||||
@ -17,8 +16,7 @@ TEST_CASE("stopwatch1", "[stopwatch]")
|
|||||||
REQUIRE(sw.elapsed() <= diff_ms + tolerance_ms);
|
REQUIRE(sw.elapsed() <= diff_ms + tolerance_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("stopwatch2", "[stopwatch]")
|
TEST_CASE("stopwatch2", "[stopwatch]") {
|
||||||
{
|
|
||||||
using spdlog::sinks::test_sink_st;
|
using spdlog::sinks::test_sink_st;
|
||||||
using std::chrono::duration_cast;
|
using std::chrono::duration_cast;
|
||||||
using std::chrono::milliseconds;
|
using std::chrono::milliseconds;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "spdlog/sinks/systemd_sink.h"
|
#include "spdlog/sinks/systemd_sink.h"
|
||||||
|
|
||||||
TEST_CASE("systemd", "[all]")
|
TEST_CASE("systemd", "[all]") {
|
||||||
{
|
|
||||||
auto systemd_sink = std::make_shared<spdlog::sinks::systemd_sink_st>();
|
auto systemd_sink = std::make_shared<spdlog::sinks::systemd_sink_st>();
|
||||||
spdlog::logger logger("spdlog_systemd_test", systemd_sink);
|
spdlog::logger logger("spdlog_systemd_test", systemd_sink);
|
||||||
logger.set_level(spdlog::level::trace);
|
logger.set_level(spdlog::level::trace);
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
#include "test_sink.h"
|
#include "test_sink.h"
|
||||||
#include "spdlog/async.h"
|
#include "spdlog/async.h"
|
||||||
|
|
||||||
TEST_CASE("time_point1", "[time_point log_msg]")
|
TEST_CASE("time_point1", "[time_point log_msg]") {
|
||||||
{
|
|
||||||
std::shared_ptr<spdlog::sinks::test_sink_st> test_sink(new spdlog::sinks::test_sink_st);
|
std::shared_ptr<spdlog::sinks::test_sink_st> test_sink(new spdlog::sinks::test_sink_st);
|
||||||
spdlog::logger logger("test-time_point", test_sink);
|
spdlog::logger logger("test-time_point", test_sink);
|
||||||
|
|
||||||
@ -13,8 +12,7 @@ TEST_CASE("time_point1", "[time_point log_msg]")
|
|||||||
|
|
||||||
// all the following should have the same time
|
// all the following should have the same time
|
||||||
test_sink->set_delay(std::chrono::milliseconds(10));
|
test_sink->set_delay(std::chrono::milliseconds(10));
|
||||||
for (int i = 0; i < 5; i++)
|
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);
|
test_sink->log(msg);
|
||||||
}
|
}
|
||||||
@ -23,7 +21,8 @@ TEST_CASE("time_point1", "[time_point log_msg]")
|
|||||||
logger.log(tp, source, spdlog::level::info, "formatted message");
|
logger.log(tp, source, spdlog::level::info, "formatted message");
|
||||||
logger.log(tp, source, spdlog::level::info, "formatted message");
|
logger.log(tp, source, spdlog::level::info, "formatted message");
|
||||||
logger.log(tp, source, spdlog::level::info, "formatted message");
|
logger.log(tp, source, spdlog::level::info, "formatted message");
|
||||||
logger.log(source, spdlog::level::info, "formatted message"); // last line has different time_point
|
logger.log(source, spdlog::level::info,
|
||||||
|
"formatted message"); // last line has different time_point
|
||||||
|
|
||||||
// now the real test... that the times are the same.
|
// now the real test... that the times are the same.
|
||||||
std::vector<std::string> lines = test_sink->lines();
|
std::vector<std::string> lines = test_sink->lines();
|
||||||
|
@ -1,41 +1,35 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
# include <sys/types.h>
|
#include <sys/types.h>
|
||||||
# include <dirent.h>
|
#include <dirent.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void prepare_logdir()
|
void prepare_logdir() {
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
system("rmdir /S /Q test_logs");
|
system("rmdir /S /Q test_logs");
|
||||||
#else
|
#else
|
||||||
auto rv = system("rm -rf test_logs");
|
auto rv = system("rm -rf test_logs");
|
||||||
if (rv != 0)
|
if (rv != 0) {
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to rm -rf test_logs");
|
throw std::runtime_error("Failed to rm -rf test_logs");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string file_contents(const std::string &filename)
|
std::string file_contents(const std::string &filename) {
|
||||||
{
|
|
||||||
std::ifstream ifs(filename, std::ios_base::binary);
|
std::ifstream ifs(filename, std::ios_base::binary);
|
||||||
if (!ifs)
|
if (!ifs) {
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed open file ");
|
throw std::runtime_error("Failed open file ");
|
||||||
}
|
}
|
||||||
return std::string((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
return std::string((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t count_lines(const std::string &filename)
|
std::size_t count_lines(const std::string &filename) {
|
||||||
{
|
|
||||||
std::ifstream ifs(filename);
|
std::ifstream ifs(filename);
|
||||||
if (!ifs)
|
if (!ifs) {
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed open file ");
|
throw std::runtime_error("Failed open file ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,23 +40,17 @@ std::size_t count_lines(const std::string &filename)
|
|||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void require_message_count(const std::string &filename, const std::size_t messages)
|
void require_message_count(const std::string &filename, const std::size_t messages) {
|
||||||
{
|
if (strlen(spdlog::details::os::default_eol) == 0) {
|
||||||
if (strlen(spdlog::details::os::default_eol) == 0)
|
|
||||||
{
|
|
||||||
REQUIRE(count_lines(filename) == 1);
|
REQUIRE(count_lines(filename) == 1);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
REQUIRE(count_lines(filename) == messages);
|
REQUIRE(count_lines(filename) == messages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t get_filesize(const std::string &filename)
|
std::size_t get_filesize(const std::string &filename) {
|
||||||
{
|
|
||||||
std::ifstream ifs(filename, std::ifstream::ate | std::ifstream::binary);
|
std::ifstream ifs(filename, std::ifstream::ate | std::ifstream::binary);
|
||||||
if (!ifs)
|
if (!ifs) {
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed open file ");
|
throw std::runtime_error("Failed open file ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,10 +58,8 @@ std::size_t get_filesize(const std::string &filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// source: https://stackoverflow.com/a/2072890/192001
|
// source: https://stackoverflow.com/a/2072890/192001
|
||||||
bool ends_with(std::string const &value, std::string const &ending)
|
bool ends_with(std::string const &value, std::string const &ending) {
|
||||||
{
|
if (ending.size() > value.size()) {
|
||||||
if (ending.size() > value.size())
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||||
@ -81,24 +67,20 @@ bool ends_with(std::string const &value, std::string const &ending)
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Based on: https://stackoverflow.com/a/37416569/192001
|
// Based on: https://stackoverflow.com/a/37416569/192001
|
||||||
std::size_t count_files(const std::string &folder)
|
std::size_t count_files(const std::string &folder) {
|
||||||
{
|
|
||||||
size_t counter = 0;
|
size_t counter = 0;
|
||||||
WIN32_FIND_DATAA ffd;
|
WIN32_FIND_DATAA ffd;
|
||||||
|
|
||||||
// Start iterating over the files in the folder directory.
|
// Start iterating over the files in the folder directory.
|
||||||
HANDLE hFind = ::FindFirstFileA((folder + "\\*").c_str(), &ffd);
|
HANDLE hFind = ::FindFirstFileA((folder + "\\*").c_str(), &ffd);
|
||||||
if (hFind != INVALID_HANDLE_VALUE)
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
{
|
|
||||||
do // Managed to locate and create an handle to that folder.
|
do // Managed to locate and create an handle to that folder.
|
||||||
{
|
{
|
||||||
if (ffd.cFileName[0] != '.')
|
if (ffd.cFileName[0] != '.')
|
||||||
counter++;
|
counter++;
|
||||||
} while (::FindNextFileA(hFind, &ffd) != 0);
|
} while (::FindNextFileA(hFind, &ffd) != 0);
|
||||||
::FindClose(hFind);
|
::FindClose(hFind);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed open folder " + folder);
|
throw std::runtime_error("Failed open folder " + folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,18 +88,15 @@ std::size_t count_files(const std::string &folder)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Based on: https://stackoverflow.com/a/2802255/192001
|
// Based on: https://stackoverflow.com/a/2802255/192001
|
||||||
std::size_t count_files(const std::string &folder)
|
std::size_t count_files(const std::string &folder) {
|
||||||
{
|
|
||||||
size_t counter = 0;
|
size_t counter = 0;
|
||||||
DIR *dp = opendir(folder.c_str());
|
DIR *dp = opendir(folder.c_str());
|
||||||
if (dp == nullptr)
|
if (dp == nullptr) {
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed open folder " + folder);
|
throw std::runtime_error("Failed open folder " + folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dirent *ep = nullptr;
|
struct dirent *ep = nullptr;
|
||||||
while ((ep = readdir(dp)) != nullptr)
|
while ((ep = readdir(dp)) != nullptr) {
|
||||||
{
|
|
||||||
if (ep->d_name[0] != '.')
|
if (ep->d_name[0] != '.')
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user