Commit f9019870 authored by gabime's avatar gabime

Merge branch 'v1.x' of https://github.com/gabime/spdlog into v1.x

parents 00546824 60ca07c2
......@@ -4,7 +4,7 @@
#
cmake_minimum_required(VERSION 3.1)
project(spdlog VERSION 0.16.3 LANGUAGES CXX)
project(spdlog VERSION 1.0.0 LANGUAGES CXX)
include(CTest)
include(CMakeDependentOption)
include(GNUInstallDirs)
......
This diff is collapsed.
CXX ?= g++
CXXFLAGS = -march=native -Wall -Wextra -pedantic -std=c++11 -pthread -I../include
CXX_RELEASE_FLAGS = -O3 -flto -DNDEBUG
CXX = g++
CXXFLAGS = -march=native -Wall -Wextra -pedantic -std=c++11 -pthread -I../include -fmax-errors=1
CXX_RELEASE_FLAGS = -O3 -flto
binaries=bench spdlog-null-async
binaries=bench latency
all: $(binaries)
bench: bench.cpp
$(CXX) bench.cpp -o bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
spdlog-null-async: spdlog-null-async.cpp
$(CXX) spdlog-null-async.cpp -o spdlog-null-async $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
latency: latency.cpp
$(CXX) latency.cpp -o latency $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
.PHONY: clean
......
......@@ -7,10 +7,10 @@
// bench.cpp : spdlog benchmarks
//
#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/simple_file_sink.h"
#include "spdlog/spdlog.h"
#include "utils.h"
#include <atomic>
......@@ -32,8 +32,9 @@ void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count
int main(int argc, char *argv[])
{
int queue_size = 1048576;
int howmany = 1000000;
int queue_size = howmany + 2;
int threads = 10;
int file_size = 30 * 1024 * 1024;
int rotating_files = 5;
......@@ -52,16 +53,24 @@ int main(int argc, char *argv[])
cout << "Single thread, " << format(howmany) << " iterations" << endl;
cout << "*******************************************************************************\n";
auto basic_st = spdlog::basic_logger_mt("basic_st", "logs/basic_st.log", true);
bench(howmany, basic_st);
auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files);
bench(howmany, rotating_st);
auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log");
bench(howmany, daily_st);
bench(howmany, spdlog::create<null_sink_st>("null_st"));
cout << "\n*******************************************************************************\n";
cout << threads << " threads sharing same logger, " << format(howmany) << " iterations" << endl;
cout << "*******************************************************************************\n";
auto basic_mt = spdlog::basic_logger_mt("basic_mt", "logs/basic_mt.log", true);
bench_mt(howmany, basic_mt, threads);
auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files);
bench_mt(howmany, rotating_mt, threads);
......@@ -76,9 +85,9 @@ int main(int argc, char *argv[])
for (int i = 0; i < 3; ++i)
{
spdlog::init_thread_pool(queue_size, 1);
auto as = spdlog::basic_logger_mt<spdlog::create_async>("as", "logs/basic_async.log", true);
auto as = spdlog::basic_logger_mt<spdlog::async_factory>("async", "logs/basic_async.log", true);
bench_mt(howmany, as, threads);
spdlog::drop("as");
spdlog::drop("async");
}
}
catch (std::exception &ex)
......@@ -92,34 +101,31 @@ int main(int argc, char *argv[])
void bench(int howmany, std::shared_ptr<spdlog::logger> log)
{
using std::chrono::high_resolution_clock;
cout << log->name() << "...\t\t" << flush;
auto start = system_clock::now();
auto start = high_resolution_clock::now();
for (auto i = 0; i < howmany; ++i)
{
log->info("Hello logger: msg number {}", i);
}
auto delta = system_clock::now() - start;
auto delta = high_resolution_clock::now() - start;
auto delta_d = duration_cast<duration<double>>(delta).count();
cout << "Elapsed: " << delta_d << "\t" << format(int(howmany / delta_d)) << "/sec" << endl;
}
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
{
using std::chrono::high_resolution_clock;
cout << log->name() << "...\t\t" << flush;
std::atomic<int> msg_counter{0};
vector<thread> threads;
auto start = system_clock::now();
auto start = high_resolution_clock::now();
for (int t = 0; t < thread_count; ++t)
{
threads.push_back(std::thread([&]() {
for (;;)
for (int j = 0; j < howmany / thread_count; j++)
{
int counter = ++msg_counter;
if (counter > howmany)
break;
log->info("Hello logger: msg number {}", counter);
log->info("Hello logger: msg number {}", j);
}
}));
}
......@@ -129,7 +135,7 @@ void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count
t.join();
};
auto delta = system_clock::now() - start;
auto delta = high_resolution_clock::now() - start;
auto delta_d = duration_cast<duration<double>>(delta).count();
cout << "Elapsed: " << delta_d << "\t" << format(int(howmany / delta_d)) << "/sec" << endl;
}
//
// Copyright(c) 2018 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
//
// latency.cpp : spdlog latency benchmarks
//
#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/spdlog.h"
#include "utils.h"
#include <atomic>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
using namespace std;
using namespace std::chrono;
using namespace spdlog;
using namespace spdlog::sinks;
using namespace utils;
void bench(int howmany, std::shared_ptr<spdlog::logger> log);
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);
int main(int , char *[])
{
std::srand(std::time(nullptr)); // use current time as seed for random generator
int howmany = 1000000;
int queue_size = howmany + 2;
int threads = 10;
int file_size = 30 * 1024 * 1024;
int rotating_files = 5;
try
{
cout << "*******************************************************************************\n";
cout << "Single thread\n";
cout << "*******************************************************************************\n";
auto basic_st = spdlog::basic_logger_mt("basic_st", "logs/basic_st.log", true);
bench(howmany, basic_st);
auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files);
bench(howmany, rotating_st);
auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log");
bench(howmany, daily_st);
bench(howmany, spdlog::create<null_sink_st>("null_st"));
cout << "\n*******************************************************************************\n";
cout << threads << " threads sharing same logger\n";
cout << "*******************************************************************************\n";
auto basic_mt = spdlog::basic_logger_mt("basic_mt", "logs/basic_mt.log", true);
bench_mt(howmany, basic_mt, threads);
auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files);
bench_mt(howmany, rotating_mt, threads);
auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt.log");
bench_mt(howmany, daily_mt, threads);
bench(howmany, spdlog::create<null_sink_st>("null_mt"));
cout << "\n*******************************************************************************\n";
cout << "async logging.. " << threads << " threads sharing same logger\n";
cout << "*******************************************************************************\n";
for (int i = 0; i < 3; ++i)
{
spdlog::init_thread_pool(queue_size, 1);
auto as = spdlog::basic_logger_mt<spdlog::async_factory>("async", "logs/basic_async.log", true);
bench_mt(howmany, as, threads);
spdlog::drop("async");
}
}
catch (std::exception &ex)
{
std::cerr << "Error: " << ex.what() << std::endl;
perror("Last error");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
void bench(int howmany, std::shared_ptr<spdlog::logger> log)
{
using namespace std::chrono;
using chrono::high_resolution_clock;
using chrono::milliseconds;
using chrono::nanoseconds;
cout << log->name() << "...\t\t" << flush;
nanoseconds total_nanos = nanoseconds::zero();
for (auto i = 0; i < howmany; ++i)
{
auto start = high_resolution_clock::now();
log->info("Hello logger: msg number {}", i);
auto delta_nanos = chrono::duration_cast<nanoseconds>(high_resolution_clock::now() - start);
total_nanos+= delta_nanos;
}
auto avg = total_nanos.count()/howmany;
cout << format(avg) << " ns/call" << endl;
}
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
{
using namespace std::chrono;
using chrono::high_resolution_clock;
using chrono::milliseconds;
using chrono::nanoseconds;
cout << log->name() << "...\t\t" << flush;
vector<thread> threads;
std::atomic<nanoseconds::rep> total_nanos{0};
for (int t = 0; t < thread_count; ++t)
{
threads.push_back(std::thread([&]() {
for (int j = 0; j < howmany / thread_count; j++)
{
auto start = high_resolution_clock::now();
log->info("Hello logger: msg number {}", j);
auto delta_nanos = chrono::duration_cast<nanoseconds>(high_resolution_clock::now() - start);
total_nanos+= delta_nanos.count();
}
}));
}
for (auto &t : threads)
{
t.join();
};
auto avg = total_nanos/howmany;
cout << format(avg) << " ns/call" << endl;
}
......@@ -11,7 +11,7 @@
#include <vector>
#include "spdlog/async.h"
#include "spdlog/sinks/simple_file_sink.h"
#include "spdlog/sinks/basic_file_sink.h"
using namespace std;
......@@ -27,7 +27,7 @@ int main(int argc, char *argv[])
int howmany = 1000000;
spdlog::init_thread_pool(howmany, 1);
auto logger = spdlog::create_async_logger<spdlog::sinks::simple_file_sink_mt>("file_logger", "logs/spdlog-bench-async.log", false);
auto logger = spdlog::create_async_logger<spdlog::sinks::basic_file_sink_mt>("file_logger", "logs/spdlog-bench-async.log", false);
logger->set_pattern("[%Y-%m-%d %T.%F]: %L %t %v");
std::cout << "To stop, press <Enter>" << std::endl;
......
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
//
// bench.cpp : spdlog benchmarks
//
#include "spdlog/async.h"
#include "spdlog/async_logger.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/spdlog.h"
#include "utils.h"
#include <atomic>
#include <cstdlib> // EXIT_FAILURE
#include <iostream>
#include <memory>
#include <string>
#include <thread>
using namespace std;
using namespace std::chrono;
using namespace spdlog;
using namespace spdlog::sinks;
using namespace utils;
size_t bench_as(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);
int main(int argc, char *argv[])
{
int howmany;
int tp_queue_size;
int tp_threads = 1;
int client_threads = 10;
int iters = 10;
try
{
if (argc < 2)
{
cout << "Usage: " << argv[0] << " <howmany> [client_threads] [q_size] [tp_threads]" << endl;
return (1);
}
howmany = atoi(argv[1]);
if (argc > 2)
client_threads = atoi(argv[2]);
if (argc > 3)
tp_queue_size = atoi(argv[3]);
else
tp_queue_size = howmany;
if (argc > 4)
tp_threads = atoi(argv[4]);
cout << "\n*******************************************************************************\n";
cout << "messages:\t" << format(howmany) << endl;
cout << "client_threads:\t" << client_threads << endl;
cout << "tp queue:\t" << format(tp_queue_size) << endl;
cout << "tp threads:\t" << tp_threads << endl;
cout << "*******************************************************************************\n";
size_t total_rate = 0;
for (int i = 0; i < iters; ++i)
{
spdlog::init_thread_pool(tp_queue_size, tp_threads);
auto as = spdlog::create_async_logger<null_sink_mt>("async(null-sink)");
total_rate += bench_as(howmany, as, client_threads);
spdlog::drop("async(null-sink)");
}
std::cout << endl;
std::cout << "Avg rate: " << format(total_rate / iters) << "/sec" << std::endl;
}
catch (std::exception &ex)
{
std::cerr << "Error: " << ex.what() << std::endl;
perror("Last error");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
// return rate/sec
size_t bench_as(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
{
cout << log->name() << "...\t\t" << flush;
std::atomic<int> msg_counter{0};
vector<thread> threads;
auto start = system_clock::now();
for (int t = 0; t < thread_count; ++t)
{
threads.push_back(std::thread([&]() {
for (;;)
{
int counter = ++msg_counter;
if (counter > howmany)
break;
log->info("Hello logger: msg number {}", counter);
}
}));
}
for (auto &t : threads)
{
t.join();
}
auto delta = system_clock::now() - start;
auto delta_d = duration_cast<duration<double>>(delta).count();
auto per_sec = size_t(howmany / delta_d);
cout << format(per_sec) << "/sec" << endl;
return per_sec;
}
CXX = g++
CXX_FLAGS = -Wall -Wextra -pedantic -std=c++11 -pthread -I../include
CXX_FLAGS = -Wall -Wextra -pedantic -std=c++11 -pthread -I../include -fmax-errors=1
CXX_RELEASE_FLAGS = -O3 -march=native
CXX_DEBUG_FLAGS= -g
......
This diff is collapsed.
......@@ -15,8 +15,8 @@ int main(int, char *[])
// Each sink can have it's own log level and a message will be logged.
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(std::make_shared<spdlog::sinks::stdout_sink_mt>());
sinks.push_back(std::make_shared<spdlog::sinks::simple_file_sink_mt>("./log_regular_file.txt"));
sinks.push_back(std::make_shared<spdlog::sinks::simple_file_sink_mt>("./log_debug_file.txt"));
sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>("./log_regular_file.txt"));
sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>("./log_debug_file.txt"));
spdlog::logger console_multisink("multisink", sinks.begin(), sinks.end());
console_multisink.set_level(spdlog::level::warn);
......
......@@ -23,7 +23,7 @@ namespace spdlog {
// async logger factory - creates async loggers backed with thread pool.
// if a global thread pool doesn't already exist, create it with default queue size of 8192 items and single thread.
struct create_async
struct async_factory
{
template<typename Sink, typename... SinkArgs>
static std::shared_ptr<async_logger> create(const std::string &logger_name, SinkArgs &&... args)
......@@ -39,16 +39,16 @@ struct create_async
}
auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
auto new_logger = std::make_shared<async_logger>(logger_name, std::move(sink), std::move(tp), async_overflow_policy::block_retry);
auto new_logger = std::make_shared<async_logger>(logger_name, std::move(sink), std::move(tp), async_overflow_policy::block);
registry::instance().register_and_init(new_logger);
return new_logger;
}
};
template<typename Sink, typename... SinkArgs>
inline std::shared_ptr<spdlog::logger> create_async_logger(const std::string &logger_name, SinkArgs &&... sink_args)
inline std::shared_ptr<spdlog::logger> create_async(const std::string &logger_name, SinkArgs &&... sink_args)
{
return create_async::create<Sink>(logger_name, std::forward<SinkArgs>(sink_args)...);
return async_factory::create<Sink>(logger_name, std::forward<SinkArgs>(sink_args)...);
}
// set global thread pool.
......
......@@ -34,13 +34,13 @@ class async_logger SPDLOG_FINAL : public std::enable_shared_from_this<async_logg
public:
template<class It>
async_logger(const std::string &logger_name, const It &begin, const It &end, std::weak_ptr<details::thread_pool> tp,
async_overflow_policy overflow_policy = async_overflow_policy::block_retry);
async_overflow_policy overflow_policy = async_overflow_policy::block);
async_logger(const std::string &logger_name, sinks_init_list sinks, std::weak_ptr<details::thread_pool> tp,
async_overflow_policy overflow_policy = async_overflow_policy::block_retry);
async_overflow_policy overflow_policy = async_overflow_policy::block);
async_logger(const std::string &logger_name, sink_ptr single_sink, std::weak_ptr<details::thread_pool> tp,
async_overflow_policy overflow_policy = async_overflow_policy::block_retry);
async_overflow_policy overflow_policy = async_overflow_policy::block);
protected:
void sink_it_(details::log_msg &msg) override;
......
......@@ -5,7 +5,7 @@
#pragma once
#define SPDLOG_VERSION "0.16.4-rc"
#define SPDLOG_VERSION "1.0.0-rc"
#include "spdlog/tweakme.h"
......@@ -63,6 +63,7 @@ using log_clock = std::chrono::system_clock;
using sink_ptr = std::shared_ptr<sinks::sink>;
using sinks_init_list = std::initializer_list<sink_ptr>;
using formatter_ptr = std::shared_ptr<spdlog::formatter>;
#if defined(SPDLOG_NO_ATOMIC_LEVELS)
using level_t = details::null_atomic_int;
#else
......@@ -126,8 +127,8 @@ using level_hasher = std::hash<int>;
//
enum class async_overflow_policy
{
block_retry, // Block until message can be enqueued
overrun_oldeset // Discard oldest message in the queue if full when trying to add new item.
block, // Block until message can be enqueued
overrun_oldest // Discard oldest message in the queue if full when trying to add new item.
};
//
......
......@@ -60,7 +60,7 @@ inline void spdlog::async_logger::flush_()
}
else
{
throw spdlog_ex("async flush: thread pool doens't exist anymore");
throw spdlog_ex("async flush: thread pool doesn't exist anymore");
}
}
......
......@@ -7,7 +7,7 @@
#include "stdio.h"
namespace spdlog {
namespace details {
struct console_stdout_trait
struct console_stdout_stream
{
static FILE *stream()
{
......@@ -21,7 +21,7 @@ struct console_stdout_trait
#endif
};
struct console_stderr_trait
struct console_stderr_stream
{
static FILE *stream()
{
......@@ -35,7 +35,7 @@ struct console_stderr_trait
#endif
};
struct console_mutex_trait
struct console_global_mutex
{
using mutex_t = std::mutex;
static mutex_t &console_mutex()
......@@ -45,7 +45,7 @@ struct console_mutex_trait
}
};
struct console_null_mutex_trait
struct console_global_nullmutex
{
using mutex_t = null_mutex;
static mutex_t &console_mutex()
......
......@@ -8,13 +8,16 @@
namespace spdlog {
namespace details {
namespace fmt_helper {
inline void append_str(const std::string &str, fmt::memory_buffer &dest)
template <size_t Buffer_Size>
inline void append_str(const std::string &str, fmt::basic_memory_buffer<char, Buffer_Size> &dest)
{
auto *str_ptr = str.data();
dest.append(str_ptr, str_ptr + str.size());
}
inline void append_c_str(const char *c_str, fmt::memory_buffer &dest)
template <size_t Buffer_Size>
inline void append_c_str(const char *c_str, fmt::basic_memory_buffer<char, Buffer_Size> &dest)
{
char ch;
while ((ch = *c_str) != '\0')
......@@ -24,21 +27,22 @@ inline void append_c_str(const char *c_str, fmt::memory_buffer &dest)
}
}
template<size_t N1, size_t N2>
inline void append_buf(const fmt::basic_memory_buffer<char, N1> &buf, fmt::basic_memory_buffer<char, N2> &dest)
template<size_t Buffer_Size1, size_t Buffer_Size2>
inline void append_buf(const fmt::basic_memory_buffer<char, Buffer_Size1> &buf, fmt::basic_memory_buffer<char, Buffer_Size2> &dest)
{
auto *buf_ptr = buf.data();
dest.append(buf_ptr, buf_ptr + buf.size());
}
template<typename T>
inline void append_int(T n, fmt::memory_buffer &dest)
template<typename T, size_t Buffer_Size>
inline void append_int(T n, fmt::basic_memory_buffer<char, Buffer_Size> &dest)
{
fmt::format_int i(n);
dest.append(i.data(), i.data() + i.size());
}
inline void pad2(int n, fmt::memory_buffer &dest)
template <size_t Buffer_Size>
inline void pad2(int n, fmt::basic_memory_buffer<char, Buffer_Size> &dest)
{
if (n > 99)
{
......@@ -61,7 +65,8 @@ inline void pad2(int n, fmt::memory_buffer &dest)
fmt::format_to(dest, "{:02}", n);
}
inline void pad3(int n, fmt::memory_buffer &dest)
template <size_t Buffer_Size>
inline void pad3(int n, fmt::basic_memory_buffer<char, Buffer_Size> &dest)
{
if (n > 99)
{
......@@ -86,8 +91,13 @@ inline void pad3(int n, fmt::memory_buffer &dest)
fmt::format_to(dest, "{:03}", n);
}
inline void pad6(size_t n, fmt::memory_buffer &dest)
template <size_t Buffer_Size>
inline void pad6(size_t n, fmt::basic_memory_buffer<char, Buffer_Size> &dest)
{
// todo: maybe replace this implementation with
// pad3(n / 1000, dest);
// pad3(n % 1000, dest);
if (n > 99999)
{
append_int(n, dest);
......@@ -122,7 +132,7 @@ inline void pad6(size_t n, fmt::memory_buffer &dest)
dest.push_back('0');
dest.push_back('0');
dest.push_back('0');
}
}
append_int(n, dest);
}
......
......@@ -46,9 +46,9 @@ inline void spdlog::logger::set_formatter(const Args &... args)
}
}
inline void spdlog::logger::set_pattern(const std::string &pattern, pattern_time_type pattern_time)
inline void spdlog::logger::set_pattern(const std::string &pattern, pattern_time_type time_type)
{
set_formatter<spdlog::pattern_formatter>(pattern, pattern_time);
set_formatter<spdlog::pattern_formatter>(pattern, time_type);
}
template<typename... Args>
......@@ -100,40 +100,40 @@ inline void spdlog::logger::log(level::level_enum lvl, const T &msg)
SPDLOG_CATCH_AND_HANDLE
}
template<typename Arg1, typename... Args>
inline void spdlog::logger::trace(const char *fmt, const Arg1 &arg1, const Args &... args)
template<typename... Args>
inline void spdlog::logger::trace(const char *fmt, const Args &... args)
{
log(level::trace, fmt, arg1, args...);
log(level::trace, fmt, args...);
}
template<typename Arg1, typename... Args>
inline void spdlog::logger::debug(const char *fmt, const Arg1 &arg1, const Args &... args)
template<typename... Args>
inline void spdlog::logger::debug(const char *fmt, const Args &... args)
{
log(level::debug, fmt, arg1, args...);
log(level::debug, fmt, args...);
}
template<typename Arg1, typename... Args>
inline void spdlog::logger::info(const char *fmt, const Arg1 &arg1, const Args &... args)
template<typename... Args>
inline void spdlog::logger::info(const char *fmt, const Args &... args)
{
log(level::info, fmt, arg1, args...);
log(level::info, fmt, args...);
}
template<typename Arg1, typename... Args>
inline void spdlog::logger::warn(const char *fmt, const Arg1 &arg1, const Args &... args)
template<typename... Args>
inline void spdlog::logger::warn(const char *fmt, const Args &... args)
{
log(level::warn, fmt, arg1, args...);
log(level::warn, fmt, args...);
}
template<typename Arg1, typename... Args>
inline void spdlog::logger::error(const char *fmt, const Arg1 &arg1, const Args &... args)
template<typename... Args>
inline void spdlog::logger::error(const char *fmt, const Args &... args)
{
log(level::err, fmt, arg1, args...);
log(level::err, fmt, args...);
}
template<typename Arg1, typename... Args>
inline void spdlog::logger::critical(const char *fmt, const Arg1 &arg1, const Args &... args)
template<typename... Args>
inline void spdlog::logger::critical(const char *fmt, const Args &... args)
{
log(level::critical, fmt, arg1, args...);
log(level::critical, fmt, args...);
}
template<typename T>
......
......@@ -120,7 +120,16 @@ class c_formatter SPDLOG_FINAL : public flag_formatter
{
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{
fmt::format_to(dest, "{} {} {} ", days[tm_time.tm_wday], months[tm_time.tm_mon], tm_time.tm_mday); //
//fmt::format_to(dest, "{} {} {} ", days[tm_time.tm_wday], months[tm_time.tm_mon], tm_time.tm_mday);
// date
fmt_helper::append_str(days[tm_time.tm_wday], dest);
dest.push_back(' ');
fmt_helper::append_str(months[tm_time.tm_mon], dest);
dest.push_back(' ');
fmt_helper::append_int(tm_time.tm_mday, dest);
dest.push_back(' ');
// time
fmt_helper::pad2(tm_time.tm_hour, dest);
dest.push_back(':');
fmt_helper::pad2(tm_time.tm_min, dest);
......@@ -176,7 +185,6 @@ class d_formatter SPDLOG_FINAL : public flag_formatter
{
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{
// fmt::format_to(dest, "{:02}", tm_time.tm_mday);
fmt_helper::pad2(tm_time.tm_mday, dest);
}
};
......@@ -265,7 +273,7 @@ class p_formatter SPDLOG_FINAL : public flag_formatter
{
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{
fmt::format_to(dest, "{}", ampm(tm_time));
fmt_helper::append_c_str(ampm(tm_time), dest);
}
};
......@@ -274,13 +282,13 @@ class r_formatter SPDLOG_FINAL : public flag_formatter
{
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{
// fmt::format_to(dest, "{:02}:{:02}:{:02} {}", to12h(tm_time), tm_time.tm_min, tm_time.tm_sec, ampm(tm_time));
fmt_helper::pad2(to12h(tm_time), dest);
dest.push_back(':');
fmt_helper::pad2(tm_time.tm_min, dest);
dest.push_back(':');
fmt_helper::pad2(tm_time.tm_sec, dest);
fmt::format_to(dest, " {}", ampm(tm_time));
dest.push_back(' ');
fmt_helper::append_c_str(ampm(tm_time), dest);
}
};
......@@ -330,23 +338,19 @@ public:
int total_minutes = os::utc_minutes_offset(tm_time);
#endif
bool is_negative = total_minutes < 0;
char sign;
if (is_negative)
{
total_minutes = -total_minutes;
sign = '-';
dest.push_back('-');
}
else
{
sign = '+';
dest.push_back('+');
}
int h = total_minutes / 60;
int m = total_minutes % 60;
dest.push_back(sign);
fmt_helper::pad2(h, dest);
fmt_helper::pad2(total_minutes / 60, dest); // hours
dest.push_back(':');
fmt_helper::pad2(m, dest);
fmt_helper::pad2(total_minutes % 60, dest); // minutes
}
private:
......@@ -371,7 +375,6 @@ class t_formatter SPDLOG_FINAL : public flag_formatter
{
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{
fmt_helper::pad6(msg.thread_id, dest);
}
};
......@@ -390,7 +393,6 @@ class i_formatter SPDLOG_FINAL : public flag_formatter
{
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{
fmt_helper::pad6(msg.msg_id, dest);
}
};
......@@ -462,39 +464,48 @@ class full_formatter SPDLOG_FINAL : public flag_formatter
{
#ifndef SPDLOG_NO_DATETIME
// each second cache the header
// cache the date/time part for the next second.
auto duration = msg.time.time_since_epoch();
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
if (cached_header_.size() == 0 || cached_seconds_ts_ != seconds)
std::chrono::seconds seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);
if (cache_timestamp_ != seconds || cached_datetime_.size() == 0)
{
cached_header_ = fmt::memory_buffer();
cached_header_.push_back('[');
fmt_helper::append_int(tm_time.tm_year + 1900, cached_header_);
cached_header_.push_back('-');
cached_datetime_.resize(0);
cached_datetime_.push_back('[');
fmt_helper::append_int(tm_time.tm_year + 1900, cached_datetime_);
cached_datetime_.push_back('-');
fmt_helper::pad2(tm_time.tm_mon + 1, cached_header_);
cached_header_.push_back('-');
fmt_helper::pad2(tm_time.tm_mon + 1, cached_datetime_);
cached_datetime_.push_back('-');
fmt_helper::pad2(tm_time.tm_mday, cached_header_);
cached_header_.push_back(' ');
fmt_helper::pad2(tm_time.tm_mday, cached_datetime_);
cached_datetime_.push_back(' ');
fmt_helper::pad2(tm_time.tm_hour, cached_header_);
cached_header_.push_back(':');
fmt_helper::pad2(tm_time.tm_hour, cached_datetime_);
cached_datetime_.push_back(':');
fmt_helper::pad2(tm_time.tm_min, cached_header_);
cached_header_.push_back(':');
fmt_helper::pad2(tm_time.tm_min, cached_datetime_);
cached_datetime_.push_back(':');
fmt_helper::pad2(tm_time.tm_sec, cached_header_);
cached_header_.push_back('.');
fmt_helper::pad2(tm_time.tm_sec, cached_datetime_);
cached_datetime_.push_back('.');
cached_seconds_ts_ = seconds;
cache_timestamp_ = seconds;
}
fmt_helper::append_buf(cached_header_, dest);
fmt_helper::append_buf(cached_datetime_, dest);
// cache the millis part for the next milli.
auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() % 1000;
fmt_helper::pad3(static_cast<int>(millis), dest);
dest.push_back(']');
dest.push_back(' ');
if(millis != millis_cache_timestamp_ || cached_millis_.size() == 0)
{
cached_millis_.resize(0);
fmt_helper::pad3(millis, cached_millis_);
cached_millis_.push_back(']');
cached_millis_.push_back(' ');
millis_cache_timestamp_ = millis;
}
fmt_helper::append_buf(cached_millis_, dest);
#else // no datetime needed
(void)tm_time;
#endif
......@@ -517,8 +528,10 @@ class full_formatter SPDLOG_FINAL : public flag_formatter
}
private:
std::chrono::seconds::rep cached_seconds_ts_{0};
fmt::memory_buffer cached_header_;
std::chrono::seconds cache_timestamp_ {0};
std::chrono::milliseconds::rep millis_cache_timestamp_ {0};
fmt::basic_memory_buffer<char, 128> cached_datetime_;
fmt::basic_memory_buffer<char, 8> cached_millis_;
};
} // namespace details
......@@ -526,14 +539,14 @@ private:
class pattern_formatter SPDLOG_FINAL : public formatter
{
public:
explicit pattern_formatter(const std::string &pattern, pattern_time_type pattern_time = pattern_time_type::local,
explicit pattern_formatter(const std::string &pattern, pattern_time_type time_type = pattern_time_type::local,
std::string eol = spdlog::details::os::default_eol)
: eol_(std::move(eol))
, pattern_time_(pattern_time)
, pattern_time_type_(time_type)
, last_log_secs_(0)
{
std::memset(&cached_tm_, 0, sizeof(cached_tm_));
compile_pattern(pattern);
compile_pattern_(pattern);
}
pattern_formatter(const pattern_formatter &) = default;
......@@ -544,7 +557,7 @@ public:
auto secs = std::chrono::duration_cast<std::chrono::seconds>(msg.time.time_since_epoch());
if (secs != last_log_secs_)
{
cached_tm_ = get_time(msg);
cached_tm_ = get_time_(msg);
last_log_secs_ = secs;
}
#endif
......@@ -558,21 +571,22 @@ public:
private:
const std::string eol_;
const pattern_time_type pattern_time_;
pattern_time_type pattern_time_type_;
std::tm cached_tm_;
std::chrono::seconds last_log_secs_;
std::vector<std::unique_ptr<details::flag_formatter>> formatters_;
std::tm get_time(const details::log_msg &msg)
std::tm get_time_(const details::log_msg &msg)
{
if (pattern_time_ == pattern_time_type::local)
if (pattern_time_type_ == pattern_time_type::local)
{
return details::os::localtime(log_clock::to_time_t(msg.time));
}
return details::os::gmtime(log_clock::to_time_t(msg.time));
}
void handle_flag(char flag)
void handle_flag_(char flag)
{
switch (flag)
{
......@@ -717,7 +731,7 @@ private:
}
}
void compile_pattern(const std::string &pattern)
void compile_pattern_(const std::string &pattern)
{
auto end = pattern.end();
std::unique_ptr<details::aggregate_formatter> user_chars;
......@@ -732,7 +746,7 @@ private:
// if(
if (++it != end)
{
handle_flag(*it);
handle_flag_(*it);
}
else
{
......
......@@ -36,7 +36,7 @@ public:
{
std::lock_guard<Mutex> lock(mutex_);
auto logger_name = new_logger->name();
throw_if_exists(logger_name);
throw_if_exists_(logger_name);
loggers_[logger_name] = new_logger;
}
......@@ -44,11 +44,11 @@ public:
{
std::lock_guard<Mutex> lock(mutex_);
auto logger_name = new_logger->name();
throw_if_exists(logger_name);
throw_if_exists_(logger_name);
// create default formatter if not exists
new_logger->set_pattern(formatter_pattern_);
new_logger->set_formatter<pattern_formatter>(formatter_pattern_, pattern_time_type_);
if (err_handler_)
{
......@@ -81,13 +81,14 @@ public:
return tp_;
}
void set_pattern(const std::string &pattern)
void set_pattern(const std::string &pattern, pattern_time_type time_type)
{
std::lock_guard<Mutex> lock(mutex_);
formatter_pattern_ = pattern;
pattern_time_type_ = time_type;
for (auto &l : loggers_)
{
l.second->set_pattern(pattern);
l.second->set_pattern(pattern, time_type);
}
}
......@@ -162,7 +163,7 @@ public:
private:
registry_t<Mutex>() = default;
void throw_if_exists(const std::string &logger_name)
void throw_if_exists_(const std::string &logger_name)
{
if (loggers_.find(logger_name) != loggers_.end())
{
......@@ -174,6 +175,7 @@ private:
Mutex tp_mutex_;
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
std::string formatter_pattern_ = "%+";
pattern_time_type pattern_time_type_ = pattern_time_type::local;
level::level_enum level_ = level::info;
level::level_enum flush_level_ = level::off;
log_err_handler err_handler_;
......
......@@ -29,7 +29,7 @@ struct async_msg
level::level_enum level;
log_clock::time_point time;
size_t thread_id;
fmt::basic_memory_buffer<char, 128> raw;
fmt::basic_memory_buffer<char, 176> raw;
size_t msg_id;
async_logger_ptr worker_ptr;
......@@ -95,7 +95,7 @@ public:
}
for (size_t i = 0; i < threads_n; i++)
{
threads_.emplace_back(std::bind(&thread_pool::worker_loop, this));
threads_.emplace_back(std::bind(&thread_pool::worker_loop_, this));
}
}
......@@ -106,14 +106,13 @@ public:
{
for (size_t i = 0; i < threads_.size(); i++)
{
post_async_msg(async_msg(async_msg_type::terminate), async_overflow_policy::block_retry);
post_async_msg_(async_msg(async_msg_type::terminate), async_overflow_policy::block);
}
for (auto &t : threads_)
{
t.join();
}
// std::cout << "~thread_pool() msg_counter_: " << msg_counter_ << std::endl;
}
catch (...)
{
......@@ -123,12 +122,12 @@ public:
void post_log(async_logger_ptr &&worker_ptr, details::log_msg &&msg, async_overflow_policy overflow_policy)
{
async_msg async_m(std::forward<async_logger_ptr>(worker_ptr), async_msg_type::log, std::forward<log_msg>(msg));
post_async_msg(std::move(async_m), overflow_policy);
post_async_msg_(std::move(async_m), overflow_policy);
}
void 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);
}
private:
......@@ -136,9 +135,9 @@ private:
std::vector<std::thread> threads_;
void post_async_msg(async_msg &&new_msg, async_overflow_policy overflow_policy)
void post_async_msg_(async_msg &&new_msg, async_overflow_policy overflow_policy)
{
if (overflow_policy == async_overflow_policy::block_retry)
if (overflow_policy == async_overflow_policy::block)
{
q_.enqueue(std::move(new_msg));
}
......@@ -148,14 +147,14 @@ private:
}
}
void worker_loop()
void worker_loop_()
{
while (process_next_msg()) {};
while (process_next_msg_()) {};
}
// process next message in the queue
// return true if this thread should still be active (while no terminate msg was received)
bool process_next_msg()
bool process_next_msg_()
{
async_msg incoming_async_msg;
bool dequeued = q_.dequeue_for(incoming_async_msg, std::chrono::seconds(10));
......
......@@ -196,12 +196,22 @@
FMT_BEGIN_NAMESPACE
// An implementation of declval for pre-C++11 compilers such as gcc 4.
namespace internal {
// An implementation of declval for pre-C++11 compilers such as gcc 4.
template<typename T>
typename std::add_rvalue_reference<T>::type declval() FMT_NOEXCEPT;
// Casts nonnegative integer to unsigned.
template<typename Int>
FMT_CONSTEXPR typename std::make_unsigned<Int>::type to_unsigned(Int value)
{
FMT_ASSERT(value >= 0, "negative value");
return static_cast<typename std::make_unsigned<Int>::type>(value);
}
} // namespace internal
/**
An implementation of ``std::basic_string_view`` for pre-C++17. It provides a
subset of the API. ``fmt::basic_string_view`` is used for format strings even
......@@ -242,7 +252,7 @@ public:
FMT_CONSTEXPR basic_string_view() FMT_NOEXCEPT : data_(FMT_NULL), size_(0) {}
/** Constructs a string reference object from a C string and a size. */
FMT_CONSTEXPR basic_string_view(const Char *s, size_t str_size) FMT_NOEXCEPT : data_(s), size_(str_size) {}
FMT_CONSTEXPR basic_string_view(const Char *s, size_t count) FMT_NOEXCEPT : data_(s), size_(count) {}
/**
\rst
......@@ -354,11 +364,7 @@ private:
std::size_t capacity_;
protected:
basic_buffer(T *p = FMT_NULL, std::size_t buf_size = 0, std::size_t buf_capacity = 0) FMT_NOEXCEPT : ptr_(p),
size_(buf_size),
capacity_(buf_capacity)
{
}
basic_buffer(T *p = FMT_NULL, std::size_t sz = 0, std::size_t cap = 0) FMT_NOEXCEPT : ptr_(p), size_(sz), capacity_(cap) {}
/** Sets the buffer data and capacity. */
void set(T *buf_data, std::size_t buf_capacity) FMT_NOEXCEPT
......@@ -418,11 +424,11 @@ public:
size_ = new_size;
}
/** Reserves space to store at least *buf_capacity* elements. */
void reserve(std::size_t buf_capacity)
/** Reserves space to store at least *capacity* elements. */
void reserve(std::size_t new_capacity)
{
if (buf_capacity > capacity_)
grow(buf_capacity);
if (new_capacity > capacity_)
grow(new_capacity);
}
void push_back(const T &value)
......@@ -893,7 +899,7 @@ public:
// Advances the begin iterator to ``it``.
FMT_CONSTEXPR void advance_to(iterator it)
{
format_str_.remove_prefix(it - begin());
format_str_.remove_prefix(internal::to_unsigned(it - begin()));
}
// Returns the next argument index.
......@@ -1135,13 +1141,13 @@ struct get_type
};
template<typename Context>
FMT_CONSTEXPR uint64_t get_types()
FMT_CONSTEXPR unsigned long long get_types()
{
return 0;
}
template<typename Context, typename Arg, typename... Args>
FMT_CONSTEXPR uint64_t get_types()
FMT_CONSTEXPR unsigned long long get_types()
{
return get_type<Context, Arg>::value | (get_types<Context, Args...>() << 4);
}
......@@ -1187,27 +1193,29 @@ private:
typedef typename std::conditional<IS_PACKED, internal::value<Context>, basic_format_arg<Context>>::type value_type;
// If the arguments are not packed, add one more element to mark the end.
value_type data_[NUM_ARGS + (IS_PACKED && NUM_ARGS != 0 ? 0 : 1)];
static const size_t DATA_SIZE = NUM_ARGS + (IS_PACKED && NUM_ARGS != 0 ? 0 : 1);
value_type data_[DATA_SIZE];
friend class basic_format_args<Context>;
static FMT_CONSTEXPR int64_t get_types()
static FMT_CONSTEXPR long long get_types()
{
return IS_PACKED ? static_cast<int64_t>(internal::get_types<Context, Args...>()) : -static_cast<int64_t>(NUM_ARGS);
return IS_PACKED ? static_cast<long long>(internal::get_types<Context, Args...>()) : -static_cast<long long>(NUM_ARGS);
}
public:
#if FMT_USE_CONSTEXPR
static constexpr int64_t TYPES = get_types();
static constexpr long long TYPES = get_types();
#else
static const int64_t TYPES;
static const long long TYPES;
#endif
#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 405
// Workaround an array initialization bug in gcc 4.5 and earlier.
#if (FMT_GCC_VERSION && FMT_GCC_VERSION <= 405) || (FMT_MSC_VER && FMT_MSC_VER <= 1800)
// Workaround array initialization issues in gcc <= 4.5 and MSVC <= 2013.
format_arg_store(const Args &... args)
{
data_ = {internal::make_arg<IS_PACKED, Context>(args)...};
value_type init[DATA_SIZE] = {internal::make_arg<IS_PACKED, Context>(args)...};
std::memcpy(data_, init, sizeof(init));
}
#else
format_arg_store(const Args &... args)
......@@ -1219,7 +1227,7 @@ public:
#if !FMT_USE_CONSTEXPR
template<typename Context, typename... Args>
const int64_t format_arg_store<Context, Args...>::TYPES = get_types();
const long long format_arg_store<Context, Args...>::TYPES = get_types();
#endif
/**
......@@ -1252,7 +1260,7 @@ public:
private:
// To reduce compiled code size per formatting function call, types of first
// max_packed_args arguments are passed in the types_ field.
uint64_t types_;
unsigned long long types_;
union
{
// If the number of arguments is less than max_packed_args, the argument
......@@ -1267,7 +1275,7 @@ private:
typename internal::type type(unsigned index) const
{
unsigned shift = index * 4;
uint64_t mask = 0xf;
unsigned long long mask = 0xf;
return static_cast<typename internal::type>((types_ & (mask << shift)) >> shift);
}
......@@ -1284,10 +1292,10 @@ private:
format_arg do_get(size_type index) const
{
int64_t signed_types = static_cast<int64_t>(types_);
long long signed_types = static_cast<long long>(types_);
if (signed_types < 0)
{
uint64_t num_args = -signed_types;
unsigned long long num_args = static_cast<unsigned long long>(-signed_types);
return index < num_args ? args_[index] : format_arg();
}
format_arg arg;
......@@ -1314,7 +1322,7 @@ public:
*/
template<typename... Args>
basic_format_args(const format_arg_store<Context, Args...> &store)
: types_(store.TYPES)
: types_(static_cast<unsigned long long>(store.TYPES))
{
set_data(store.data_);
}
......@@ -1328,8 +1336,8 @@ public:
unsigned max_size() const
{
int64_t signed_types = static_cast<int64_t>(types_);
return static_cast<unsigned>(signed_types < 0 ? -signed_types : static_cast<int64_t>(internal::max_packed_args));
long long signed_types = static_cast<long long>(types_);
return static_cast<unsigned>(signed_types < 0 ? -signed_types : static_cast<long long>(internal::max_packed_args));
}
};
......@@ -1414,6 +1422,8 @@ inline internal::named_arg<T, wchar_t> arg(wstring_view name, const T &arg)
template<typename S, typename T, typename Char>
void arg(S, internal::named_arg<T, Char>) FMT_DELETED;
#ifndef FMT_EXTENDED_COLORS
// color and (v)print_colored are deprecated.
enum color
{
black,
......@@ -1425,27 +1435,19 @@ enum color
cyan,
white
};
FMT_API void vprint_colored(color c, string_view format, format_args args);
FMT_API void vprint_colored(color c, wstring_view format, wformat_args args);
/**
Formats a string and prints it to stdout using ANSI escape sequences to
specify color (experimental).
Example:
fmt::print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23);
*/
template<typename... Args>
inline void print_colored(color c, string_view format_str, const Args &... args)
{
vprint_colored(c, format_str, make_format_args(args...));
}
template<typename... Args>
inline void print_colored(color c, wstring_view format_str, const Args &... args)
{
vprint_colored(c, format_str, make_format_args<wformat_context>(args...));
}
#endif
format_context::iterator vformat_to(internal::buffer &buf, string_view format_str, format_args args);
wformat_context::iterator vformat_to(internal::wbuffer &buf, wstring_view format_str, wformat_args args);
......
......@@ -89,9 +89,6 @@ inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...)
#define FMT_SWPRINTF swprintf
#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
const char RESET_COLOR[] = "\x1b[0m";
const wchar_t WRESET_COLOR[] = L"\x1b[0m";
typedef void (*FormatFunc)(internal::buffer &, int, string_view);
// Portable thread-safe version of strerror.
......@@ -300,6 +297,11 @@ const int16_t basic_data<T>::POW10_EXPONENTS[] = {-1220, -1193, -1166, -1140, -1
-289, -263, -236, -210, -183, -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, 375,
402, 428, 455, 481, 508, 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
template<typename T>
const char basic_data<T>::RESET_COLOR[] = "\x1b[0m";
template<typename T>
const wchar_t basic_data<T>::WRESET_COLOR[] = L"\x1b[0m";
FMT_FUNC fp operator*(fp x, fp y)
{
// Multiply 32-bit parts of significands.
......@@ -502,13 +504,14 @@ FMT_FUNC void vprint(wstring_view format_str, wformat_args args)
vprint(stdout, format_str, args);
}
#ifndef FMT_EXTENDED_COLORS
FMT_FUNC void vprint_colored(color c, string_view format, format_args args)
{
char escape[] = "\x1b[30m";
escape[3] = static_cast<char>('0' + c);
std::fputs(escape, stdout);
vprint(format, args);
std::fputs(RESET_COLOR, stdout);
std::fputs(internal::data::RESET_COLOR, stdout);
}
FMT_FUNC void vprint_colored(color c, wstring_view format, wformat_args args)
......@@ -517,8 +520,48 @@ FMT_FUNC void vprint_colored(color c, wstring_view format, wformat_args args)
escape[3] = static_cast<wchar_t>('0' + c);
std::fputws(escape, stdout);
vprint(format, args);
std::fputws(WRESET_COLOR, stdout);
std::fputws(internal::data::WRESET_COLOR, stdout);
}
#else
namespace internal {
FMT_CONSTEXPR void to_esc(uint8_t c, char out[], int offset)
{
out[offset + 0] = static_cast<char>('0' + c / 100);
out[offset + 1] = static_cast<char>('0' + c / 10 % 10);
out[offset + 2] = static_cast<char>('0' + c % 10);
}
} // namespace internal
FMT_FUNC void vprint_rgb(rgb fd, string_view format, format_args args)
{
char escape_fd[] = "\x1b[38;2;000;000;000m";
internal::to_esc(fd.r, escape_fd, 7);
internal::to_esc(fd.g, escape_fd, 11);
internal::to_esc(fd.b, escape_fd, 15);
std::fputs(escape_fd, stdout);
vprint(format, args);
std::fputs(internal::data::RESET_COLOR, stdout);
}
FMT_FUNC void vprint_rgb(rgb fd, rgb bg, string_view format, format_args args)
{
char escape_fd[] = "\x1b[38;2;000;000;000m"; // foreground color
char escape_bg[] = "\x1b[48;2;000;000;000m"; // background color
internal::to_esc(fd.r, escape_fd, 7);
internal::to_esc(fd.g, escape_fd, 11);
internal::to_esc(fd.b, escape_fd, 15);
internal::to_esc(bg.r, escape_bg, 7);
internal::to_esc(bg.g, escape_bg, 11);
internal::to_esc(bg.b, escape_bg, 15);
std::fputs(escape_fd, stdout);
std::fputs(escape_bg, stdout);
vprint(format, args);
std::fputs(internal::data::RESET_COLOR, stdout);
}
#endif
FMT_FUNC locale locale_provider::locale()
{
......
// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#include "fmt/format-inl.h"
namespace fmt {
template struct internal::basic_data<void>;
// Explicit instantiations for char.
template FMT_API char internal::thousands_sep(locale_provider *lp);
template void basic_fixed_buffer<char>::grow(std::size_t);
template void internal::arg_map<format_context>::init(
const basic_format_args<format_context> &args);
template FMT_API int internal::char_traits<char>::format_float(
char *buffer, std::size_t size, const char *format,
unsigned width, int precision, double value);
template FMT_API int internal::char_traits<char>::format_float(
char *buffer, std::size_t size, const char *format,
unsigned width, int precision, long double value);
// Explicit instantiations for wchar_t.
template FMT_API wchar_t internal::thousands_sep(locale_provider *lp);
template void basic_fixed_buffer<wchar_t>::grow(std::size_t);
template void internal::arg_map<wformat_context>::init(const wformat_args &args);
template FMT_API int internal::char_traits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format,
unsigned width, int precision, double value);
template FMT_API int internal::char_traits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format,
unsigned width, int precision, long double value);
} // namespace fmt
This diff is collapsed.
......@@ -290,27 +290,38 @@ public:
{
}
using base::operator();
/** Formats an argument of type ``bool``. */
iterator operator()(bool value)
template<typename T>
typename std::enable_if<std::is_integral<T>::value, iterator>::type operator()(T value)
{
format_specs &fmt_spec = this->spec();
if (fmt_spec.type_ != 's')
return (*this)(value ? 1 : 0);
fmt_spec.type_ = 0;
this->write(value);
// MSVC2013 fails to compile separate overloads for bool and char_type so
// use std::is_same instead.
if (std::is_same<T, bool>::value)
{
format_specs &fmt_spec = this->spec();
if (fmt_spec.type_ != 's')
return base::operator()(value ? 1 : 0);
fmt_spec.type_ = 0;
this->write(value != 0);
}
else if (std::is_same<T, char_type>::value)
{
format_specs &fmt_spec = this->spec();
if (fmt_spec.type_ && fmt_spec.type_ != 'c')
return (*this)(static_cast<int>(value));
fmt_spec.flags_ = 0;
fmt_spec.align_ = ALIGN_RIGHT;
return base::operator()(value);
}
else
{
return base::operator()(value);
}
return this->out();
}
/** Formats a character. */
iterator operator()(char_type value)
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, iterator>::type operator()(T value)
{
format_specs &fmt_spec = this->spec();
if (fmt_spec.type_ && fmt_spec.type_ != 'c')
return (*this)(static_cast<int>(value));
fmt_spec.flags_ = 0;
fmt_spec.align_ = ALIGN_RIGHT;
return base::operator()(value);
}
......@@ -338,6 +349,16 @@ public:
return this->out();
}
iterator operator()(basic_string_view<char_type> value)
{
return base::operator()(value);
}
iterator operator()(monostate value)
{
return base::operator()(value);
}
/** Formats a pointer. */
iterator operator()(const void *value)
{
......
......@@ -114,12 +114,14 @@ struct is_range_ : std::false_type
{
};
#if !FMT_MSC_VER || FMT_MSC_VER > 1800
template<typename T>
struct is_range_<T, typename std::conditional<false,
conditional_helper<decltype(internal::declval<T>().begin()), decltype(internal::declval<T>().end())>, void>::type>
: std::true_type
{
};
#endif
/// tuple_size and tuple_element check.
template<typename T>
......@@ -171,7 +173,7 @@ using make_index_sequence = make_integer_sequence<std::size_t, N>;
#endif
template<class Tuple, class F, size_t... Is>
void for_each(index_sequence<Is...>, Tuple &&tup, F &&f) noexcept
void for_each(index_sequence<Is...>, Tuple &&tup, F &&f) FMT_NOEXCEPT
{
using std::get;
// using free function get<I>(T) now.
......
......@@ -17,5 +17,3 @@ public:
virtual void format(const details::log_msg &msg, fmt::memory_buffer &dest) = 0;
};
} // namespace spdlog
#include "details/pattern_formatter_impl.h"
......@@ -45,23 +45,23 @@ public:
template<typename... Args>
void log(level::level_enum lvl, const char *msg);
template<typename Arg1, typename... Args>
void trace(const char *fmt, const Arg1 &, const Args &... args);
template<typename... Args>
void trace(const char *fmt, const Args &... args);
template<typename Arg1, typename... Args>
void debug(const char *fmt, const Arg1 &, const Args &... args);
template<typename... Args>
void debug(const char *fmt, const Args &... args);
template<typename Arg1, typename... Args>
void info(const char *fmt, const Arg1 &, const Args &... args);
template<typename... Args>
void info(const char *fmt, const Args &... args);
template<typename Arg1, typename... Args>
void warn(const char *fmt, const Arg1 &, const Args &... args);
template<typename... Args>
void warn(const char *fmt, const Args &... args);
template<typename Arg1, typename... Args>
void error(const char *fmt, const Arg1 &, const Args &... args);
template<typename... Args>
void error(const char *fmt, const Args &... args);
template<typename Arg1, typename... Args>
void critical(const char *fmt, const Arg1 &, const Args &... args);
template<typename... Args>
void critical(const char *fmt, const Args &... args);
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
template<typename... Args>
......@@ -117,10 +117,10 @@ public:
// create a pattern formatter all the sinks in this logger.
// each sink gets itw own private copy of a formatter object.
void set_pattern(const std::string &pattern, pattern_time_type pattern_time = pattern_time_type::local);
void set_pattern(const std::string &pattern, pattern_time_type time_type = pattern_time_type::local);
// create a FormatterT formatter all the sinks in this logger.
// each sink gets itw own private copy of a formatter object.
// create a FormatterT formatter for each sink in this logger.
// each sink gets its own private copy of a formatter object.
template<class FormatterT, typename... Args>
void set_formatter(const Args &... args);
......
......@@ -38,7 +38,7 @@ public:
void log(const details::log_msg &msg) override
{
const android_LogPriority priority = convert_to_android(msg.level);
const android_LogPriority priority = convert_to_android_(msg.level);
fmt::memory_buffer formatted;
if (use_raw_msg_)
{
......@@ -70,7 +70,7 @@ public:
void flush() override {}
private:
static android_LogPriority convert_to_android(spdlog::level::level_enum level)
static android_LogPriority convert_to_android_(spdlog::level::level_enum level)
{
switch (level)
{
......
......@@ -5,9 +5,9 @@
#pragma once
#include "spdlog/details/console_globals.h"
#include "spdlog/details/null_mutex.h"
#include "spdlog/details/os.h"
#include "spdlog/details/traits.h"
#include <memory>
#include <mutex>
......@@ -22,14 +22,14 @@ namespace sinks {
* of the message.
* If no color terminal detected, omit the escape codes.
*/
template<class StreamTrait, class ConsoleMutexTrait>
template<class TargetStream, class ConsoleMutex>
class ansicolor_sink : public sink
{
public:
using mutex_t = typename ConsoleMutexTrait::mutex_t;
using mutex_t = typename ConsoleMutex::mutex_t;
ansicolor_sink()
: target_file_(StreamTrait::stream())
, mutex_(ConsoleMutexTrait::console_mutex())
: target_file_(TargetStream::stream())
, mutex_(ConsoleMutex::console_mutex())
{
should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal();
......@@ -132,10 +132,11 @@ private:
std::unordered_map<level::level_enum, std::string, level::level_hasher> colors_;
};
using ansicolor_stdout_sink_mt = ansicolor_sink<details::console_stdout_trait, details::console_mutex_trait>;
using ansicolor_stdout_sink_st = ansicolor_sink<details::console_stdout_trait, details::console_null_mutex_trait>;
using ansicolor_stderr_sink_mt = ansicolor_sink<details::console_stderr_trait, details::console_mutex_trait>;
using ansicolor_stderr_sink_st = ansicolor_sink<details::console_stderr_trait, details::console_null_mutex_trait>;
using ansicolor_stdout_sink_mt = ansicolor_sink<details::console_stdout_stream, details::console_global_mutex>;
using ansicolor_stdout_sink_st = ansicolor_sink<details::console_stdout_stream, details::console_global_nullmutex>;
using ansicolor_stderr_sink_mt = ansicolor_sink<details::console_stderr_stream, details::console_global_mutex>;
using ansicolor_stderr_sink_st = ansicolor_sink<details::console_stderr_stream, details::console_global_nullmutex>;
} // namespace sinks
......
......@@ -6,8 +6,8 @@
#pragma once
//
// base sink templated over a mutex (either dummy or real)
// concrete implementation should only override the sink_it_ method.
// all locking is taken care of here so no locking needed by the implementers..
// concrete implementation should override the sink_it_() and flush_() methods.
// locking is taken care of in this class - no locking needed by the implementers..
//
#include "spdlog/common.h"
......@@ -26,16 +26,6 @@ public:
{
}
base_sink(const std::string &formatter_pattern)
: sink(formatter_pattern)
{
}
base_sink(std::unique_ptr<spdlog::formatter> sink_formatter)
: sink(std::move(sink_formatter))
{
}
base_sink(const base_sink &) = delete;
base_sink &operator=(const base_sink &) = delete;
......
......@@ -18,28 +18,18 @@ namespace sinks {
* Trivial file sink with single file as target
*/
template<class Mutex>
class simple_file_sink SPDLOG_FINAL : public base_sink<Mutex>
class basic_file_sink SPDLOG_FINAL : public base_sink<Mutex>
{
public:
explicit simple_file_sink(const filename_t &filename, bool truncate = false)
: force_flush_(false)
explicit basic_file_sink(const filename_t &filename, bool truncate = false)
{
file_helper_.open(filename, truncate);
}
void set_force_flush(bool force_flush)
{
force_flush_ = force_flush;
}
protected:
void sink_it_(const details::log_msg &, const fmt::memory_buffer &formatted) override
{
file_helper_.write(formatted);
if (force_flush_)
{
file_helper_.flush();
}
}
void flush_() override
......@@ -49,11 +39,10 @@ protected:
private:
details::file_helper file_helper_;
bool force_flush_;
};
using simple_file_sink_mt = simple_file_sink<std::mutex>;
using simple_file_sink_st = simple_file_sink<details::null_mutex>;
using basic_file_sink_mt = basic_file_sink<std::mutex>;
using basic_file_sink_st = basic_file_sink<details::null_mutex>;
} // namespace sinks
......@@ -63,13 +52,13 @@ using simple_file_sink_st = simple_file_sink<details::null_mutex>;
template<typename Factory = default_factory>
inline std::shared_ptr<logger> basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false)
{
return Factory::template create<sinks::simple_file_sink_mt>(logger_name, filename, truncate);
return Factory::template create<sinks::basic_file_sink_mt>(logger_name, filename, truncate);
}
template<typename Factory = default_factory>
inline std::shared_ptr<logger> basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false)
{
return Factory::template create<sinks::simple_file_sink_st>(logger_name, filename, truncate);
return Factory::template create<sinks::basic_file_sink_st>(logger_name, filename, truncate);
}
} // namespace spdlog
......@@ -7,7 +7,6 @@
#include "spdlog/details/log_msg.h"
#include "spdlog/details/null_mutex.h"
#include "spdlog/sink/base_sink.h"
#include <algorithm>
#include <memory>
......@@ -18,22 +17,18 @@
namespace spdlog {
namespace sinks {
template<class Mutex>
class dist_sink : public base_sink<Mutex>
template<typename Mutex>
class dist_sink : public sink
{
public:
explicit dist_sink()
: sinks_()
{
}
dist_sink() = default;
dist_sink(const dist_sink &) = delete;
dist_sink &operator=(const dist_sink &) = delete;
protected:
std::vector<std::shared_ptr<sink>> sinks_;
void sink_it_(const details::log_msg &msg) override
void log(const details::log_msg &msg) SPDLOG_FINAL override
{
std::lock_guard<Mutex> lock(mutex_);
for (auto &sink : sinks_)
{
if (sink->should_log(msg.level))
......@@ -43,24 +38,28 @@ protected:
}
}
void flush_() override
void flush() SPDLOG_FINAL override
{
std::lock_guard<Mutex> lock(mutex_);
for (auto &sink : sinks_)
sink->flush();
}
public:
void add_sink(std::shared_ptr<sink> sink)
{
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
std::lock_guard<Mutex> lock(mutex_);
sinks_.push_back(sink);
}
void remove_sink(std::shared_ptr<sink> sink)
{
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
std::lock_guard<Mutex> lock(mutex_);
sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink), sinks_.end());
}
private:
Mutex mutex_;
std::vector<std::shared_ptr<sink>> sinks_;
};
using dist_sink_mt = dist_sink<std::mutex>;
......
......@@ -27,9 +27,9 @@ public:
explicit msvc_sink() {}
protected:
void sink_it_(const details::log_msg &msg) override
void sink_it_(const details::log_msg &, const fmt::memory_buffer &formatted) override
{
OutputDebugStringA(msg.formatted.c_str());
OutputDebugStringA(fmt::to_string(formatted).c_str());
}
void flush_() override {}
......@@ -38,6 +38,9 @@ protected:
using msvc_sink_mt = msvc_sink<std::mutex>;
using msvc_sink_st = msvc_sink<details::null_mutex>;
using windebug_sink_mt = msvc_sink_mt;
using windebug_sink_st = msvc_sink_st;
} // namespace sinks
} // namespace spdlog
......
......@@ -6,6 +6,7 @@
#pragma once
#include "spdlog/details/log_msg.h"
#include "spdlog/details/pattern_formatter.h"
#include "spdlog/formatter.h"
namespace spdlog {
......@@ -19,17 +20,6 @@ public:
{
}
explicit sink(const std::string &formatter_pattern)
: formatter_(std::unique_ptr<spdlog::formatter>(new pattern_formatter(formatter_pattern)))
{
}
// sink with custom formatter
explicit sink(std::unique_ptr<spdlog::formatter> sink_formatter)
: formatter_(std::move(sink_formatter))
{
}
virtual ~sink() = default;
virtual void log(const details::log_msg &msg) = 0;
......@@ -39,10 +29,12 @@ public:
{
return msg_level >= level_.load(std::memory_order_relaxed);
}
void set_level(level::level_enum log_level)
{
level_.store(log_level);
}
level::level_enum level() const
{
return static_cast<spdlog::level::level_enum>(level_.load(std::memory_order_relaxed));
......@@ -58,11 +50,6 @@ public:
formatter_ = std::move(sink_formatter);
}
spdlog::formatter *formatter()
{
return formatter_.get();
}
protected:
level_t level_{level::trace};
std::unique_ptr<spdlog::formatter> formatter_;
......
......@@ -5,26 +5,27 @@
#pragma once
#include "spdlog/details/console_globals.h"
#include "spdlog/details/null_mutex.h"
#include "spdlog/details/traits.h"
#include "spdlog/spdlog.h"
#include <cstdio>
#include <memory>
#include <mutex>
#include <spdlog/details/console_globals.h>
namespace spdlog {
namespace sinks {
template<class StdoutTrait, class ConsoleMutexTrait>
template<class TargetStream, class ConsoleMutex>
class stdout_sink : public sink
{
public:
using mutex_t = typename ConsoleMutexTrait::mutex_t;
using mutex_t = typename ConsoleMutex::mutex_t;
stdout_sink()
: mutex_(ConsoleMutexTrait::console_mutex())
, file_(StdoutTrait::stream())
: mutex_(ConsoleMutex::console_mutex())
, file_(TargetStream::stream())
{
}
~stdout_sink() = default;
......@@ -35,14 +36,16 @@ public:
void log(const details::log_msg &msg) override
{
std::lock_guard<mutex_t> lock(mutex_);
fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), file_);
fflush(StdoutTrait::stream());
fmt::memory_buffer formatted;
formatter_->format(msg, formatted);
fwrite(formatted.data(), sizeof(char), formatted.size(), file_);
fflush(TargetStream::stream());
}
void flush() override
{
std::lock_guard<mutex_t> lock(mutex_);
fflush(StdoutTrait::stream());
fflush(TargetStream::stream());
}
private:
......@@ -50,10 +53,11 @@ private:
FILE *file_;
};
using stdout_sink_mt = stdout_sink<details::console_stdout_trait, details::console_mutex_trait>;
using stdout_sink_st = stdout_sink<details::console_stdout_trait, details::console_null_mutex_trait>;
using stderr_sink_mt = stdout_sink<details::console_stderr_trait, details::console_mutex_trait>;
using stderr_sink_st = stdout_sink<details::console_stderr_trait, details::console_null_mutex_trait>;
using stdout_sink_mt = stdout_sink<details::console_stdout_stream, details::console_global_mutex>;
using stdout_sink_st = stdout_sink<details::console_stdout_stream, details::console_global_nullmutex>;
using stderr_sink_mt = stdout_sink<details::console_stderr_stream, details::console_global_mutex>;
using stderr_sink_st = stdout_sink<details::console_stderr_stream, details::console_global_nullmutex>;
} // namespace sinks
......
......@@ -7,8 +7,8 @@
#include "../fmt/fmt.h"
#include "spdlog/common.h"
#include "spdlog/details/console_globals.h"
#include "spdlog/details/null_mutex.h"
#include "spdlog/details/traits.h"
#include "spdlog/sinks/sink.h"
#include <memory>
......@@ -22,7 +22,7 @@ namespace sinks {
/*
* Windows color console sink. Uses WriteConsoleA to write to the console with colors
*/
template<class HandleTrait, class ConsoleMutexTrait>
template<class OutHandle, class ConsoleMutex>
class wincolor_sink : public sink
{
public:
......@@ -34,8 +34,8 @@ public:
const WORD YELLOW = FOREGROUND_RED | FOREGROUND_GREEN;
wincolor_sink()
: out_handle_(HandleTrait::handle())
, mutex_(ConsoleMutexTrait::console_mutex())
: out_handle_(OutHandle::handle())
, mutex_(ConsoleMutex::console_mutex())
{
colors_[level::trace] = WHITE;
colors_[level::debug] = CYAN;
......@@ -90,7 +90,7 @@ public:
}
private:
using mutex_t = typename ConsoleMutexTrait::mutex_t;
using mutex_t = typename ConsoleMutex::mutex_t;
// set color and return the orig console attributes (for resetting later)
WORD set_console_attribs(WORD attribs)
{
......@@ -116,11 +116,11 @@ private:
std::unordered_map<level::level_enum, WORD, level::level_hasher> colors_;
};
using wincolor_stdout_sink_mt = wincolor_sink<details::console_stdout_trait, details::console_mutex_trait>;
using wincolor_stdout_sink_st = wincolor_sink<details::console_stdout_trait, details::console_null_mutex_trait>;
using wincolor_stdout_sink_mt = wincolor_sink<details::console_stdout_stream, details::console_global_mutex>;
using wincolor_stdout_sink_st = wincolor_sink<details::console_stdout_stream, details::console_global_nullmutex>;
using wincolor_stderr_sink_mt = wincolor_sink<details::console_stderr_trait, details::console_mutex_trait>;
using wincolor_stderr_sink_st = wincolor_sink<details::console_stderr_trait, details::console_null_mutex_trait>;
using wincolor_stderr_sink_mt = wincolor_sink<details::console_stderr_stream, details::console_global_mutex>;
using wincolor_stderr_sink_st = wincolor_sink<details::console_stderr_stream, details::console_global_nullmutex>;
} // namespace sinks
} // namespace spdlog
//
// Copyright(c) 2017 Alexander Dalshov.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#if defined(_WIN32)
#include "spdlog/sinks/msvc_sink.h"
namespace spdlog {
namespace sinks {
/*
* Windows debug sink (logging using OutputDebugStringA, synonym for msvc_sink)
*/
template<class Mutex>
using windebug_sink = msvc_sink<Mutex>;
using windebug_sink_mt = msvc_sink_mt;
using windebug_sink_st = msvc_sink_st;
} // namespace sinks
} // namespace spdlog
#endif
......@@ -19,7 +19,7 @@
namespace spdlog {
// Default logger factory- creates synchronous loggers
struct create_synchronous
struct synchronous_factory
{
template<typename Sink, typename... SinkArgs>
......@@ -32,7 +32,7 @@ struct create_synchronous
}
};
using default_factory = create_synchronous;
using default_factory = synchronous_factory;
// Create and register a logger with a templated sink type
// The logger's level, formatter and flush level will be set according the global settings.
......@@ -57,9 +57,9 @@ inline std::shared_ptr<logger> get(const std::string &name)
// Set global formatting
// example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v");
//
inline void set_pattern(const std::string &format_string)
inline void set_pattern(const std::string &format_string, pattern_time_type time_type = pattern_time_type::local)
{
details::registry::instance().set_pattern(format_string);
details::registry::instance().set_pattern(format_string, time_type);
}
//
......
......@@ -24,7 +24,7 @@ TEST_CASE("default_error_handler", "[errors]]")
prepare_logdir();
std::string filename = "logs/simple_log.txt";
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("test-error", filename, true);
auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("test-error", filename, true);
logger->set_pattern("%v");
logger->info("Test message {} {}", 1);
logger->info("Test message {}", 2);
......@@ -41,7 +41,7 @@ TEST_CASE("custom_error_handler", "[errors]]")
{
prepare_logdir();
std::string filename = "logs/simple_log.txt";
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
logger->flush_on(spdlog::level::info);
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
logger->info("Good message #1");
......@@ -75,7 +75,7 @@ TEST_CASE("async_error_handler", "[errors]]")
std::string filename = "logs/simple_async_log.txt";
{
spdlog::init_thread_pool(128, 1);
auto logger = spdlog::create_async_logger<spdlog::sinks::simple_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 &) {
std::ofstream ofs("logs/custom_err.txt");
if (!ofs)
......@@ -99,7 +99,7 @@ TEST_CASE("async_error_handler2", "[errors]]")
std::string err_msg("This is async handler error message");
{
spdlog::init_thread_pool(128, 1);
auto logger = spdlog::create_async_logger<failing_sink>("failed_logger");
auto logger = spdlog::create_async<failing_sink>("failed_logger");
logger->set_error_handler([=](const std::string &) {
std::ofstream ofs("logs/custom_err2.txt");
if (!ofs)
......
......@@ -8,7 +8,7 @@ TEST_CASE("simple_file_logger", "[simple_logger]]")
prepare_logdir();
std::string filename = "logs/simple_log";
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename);
auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename);
logger->set_pattern("%v");
logger->info("Test message {}", 1);
......@@ -24,7 +24,7 @@ TEST_CASE("flush_on", "[flush_on]]")
prepare_logdir();
std::string filename = "logs/simple_log";
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename);
auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename);
logger->set_pattern("%v");
logger->set_level(spdlog::level::trace);
logger->flush_on(spdlog::level::info);
......
......@@ -13,10 +13,10 @@
#define SPDLOG_DEBUG_ON
#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/sinks/ostream_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/simple_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"
#include "includes.h"
#include "spdlog/async.h"
#include "spdlog/sinks/simple_file_sink.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "test_sink.h"
TEST_CASE("basic async test ", "[async]")
......@@ -11,7 +11,7 @@ TEST_CASE("basic async test ", "[async]")
size_t messages = 256;
{
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block_retry);
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block);
for (size_t i = 0; i < messages; i++)
{
logger->info("Hello message #{}", i);
......@@ -30,7 +30,7 @@ TEST_CASE("discard policy ", "[async]")
size_t messages = 1024;
{
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::overrun_oldeset);
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::overrun_oldest);
for (size_t i = 0; i < messages; i++)
{
logger->info("Hello message #{}", i);
......@@ -48,7 +48,7 @@ TEST_CASE("flush", "[async]")
size_t messages = 256;
{
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block_retry);
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block);
for (size_t i = 0; i < messages; i++)
{
logger->info("Hello message #{}", i);
......@@ -69,7 +69,7 @@ TEST_CASE("tp->wait_empty() ", "[async]")
size_t messages = 100;
auto tp = std::make_shared<details::thread_pool>(messages, 2);
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block_retry);
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block);
for (size_t i = 0; i < messages; i++)
{
logger->info("Hello message #{}", i);
......@@ -90,7 +90,7 @@ TEST_CASE("multi threads", "[async]")
size_t n_threads = 10;
{
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block_retry);
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block);
std::vector<std::thread> threads;
for (size_t i = 0; i < n_threads; i++)
......@@ -121,7 +121,7 @@ TEST_CASE("to_file", "[async]")
size_t tp_threads = 1;
std::string filename = "logs/async_test.log";
{
auto file_sink = std::make_shared<spdlog::sinks::simple_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 logger = std::make_shared<spdlog::async_logger>("as", std::move(file_sink), std::move(tp));
......@@ -143,7 +143,7 @@ TEST_CASE("to_file multi-workers", "[async]")
size_t tp_threads = 10;
std::string filename = "logs/async_test.log";
{
auto file_sink = std::make_shared<spdlog::sinks::simple_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 logger = std::make_shared<spdlog::async_logger>("as", std::move(file_sink), std::move(tp));
......
......@@ -9,12 +9,11 @@ TEST_CASE("debug and trace w/o format string", "[macros]]")
prepare_logdir();
std::string filename = "logs/simple_log";
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename);
auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename);
logger->set_pattern("%v");
logger->set_level(spdlog::level::trace);
SPDLOG_TRACE(logger, "Test message 1");
// SPDLOG_DEBUG(logger, "Test message 2");
SPDLOG_DEBUG(logger, "Test message 2");
logger->flush();
......@@ -27,7 +26,7 @@ TEST_CASE("debug and trace with format strings", "[macros]]")
prepare_logdir();
std::string filename = "logs/simple_log";
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename);
auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename);
logger->set_pattern("%v");
logger->set_level(spdlog::level::trace);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment