Commit d163b8c4 authored by gabime's avatar gabime

astyle

parent 58308df3
#!/bin/bash #!/bin/bash
find . -name "*\.h" -o -name "*\.cpp"|xargs dos2unix find . -name "*\.h" -o -name "*\.cpp"|xargs dos2unix
find . -name "*\.h" -o -name "*\.cpp"|xargs astyle -n -A1 find . -name "*\.h" -o -name "*\.cpp"|xargs astyle -n -c -t4 -A1
...@@ -18,17 +18,17 @@ namespace keywords = boost::log::keywords; ...@@ -18,17 +18,17 @@ namespace keywords = boost::log::keywords;
void init() void init()
{ {
logging::add_file_log logging::add_file_log
( (
keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/ keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/
keywords::auto_flush = false, keywords::auto_flush = false,
keywords::format = "[%TimeStamp%]: %Message%" keywords::format = "[%TimeStamp%]: %Message%"
); );
logging::core::get()->set_filter logging::core::get()->set_filter
( (
logging::trivial::severity >= logging::trivial::info logging::trivial::severity >= logging::trivial::info
); );
} }
...@@ -37,43 +37,43 @@ using namespace std; ...@@ -37,43 +37,43 @@ using namespace std;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int thread_count = 10; int thread_count = 10;
if(argc > 1) if(argc > 1)
thread_count = atoi(argv[1]); thread_count = atoi(argv[1]);
int howmany = 1000000; int howmany = 1000000;
init(); init();
logging::add_common_attributes(); logging::add_common_attributes();
using namespace logging::trivial; using namespace logging::trivial;
src::severity_logger_mt< severity_level > lg; src::severity_logger_mt< severity_level > lg;
std::atomic<int > msg_counter {0}; std::atomic<int > msg_counter {0};
vector<thread> threads; vector<thread> threads;
for (int t = 0; t < thread_count; ++t) for (int t = 0; t < thread_count; ++t)
{ {
threads.push_back(std::thread([&]() threads.push_back(std::thread([&]()
{ {
while (true) while (true)
{ {
int counter = ++msg_counter; int counter = ++msg_counter;
if (counter > howmany) break; if (counter > howmany) break;
BOOST_LOG_SEV(lg, info) << "boost message #" << counter << ": This is some text for your pleasure"; BOOST_LOG_SEV(lg, info) << "boost message #" << counter << ": This is some text for your pleasure";
} }
})); }));
} }
for(auto &t:threads) for(auto &t:threads)
{ {
t.join(); t.join();
}; };
return 0; return 0;
} }
...@@ -15,30 +15,30 @@ namespace keywords = boost::log::keywords; ...@@ -15,30 +15,30 @@ namespace keywords = boost::log::keywords;
void init() void init()
{ {
logging::add_file_log logging::add_file_log
( (
keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/ keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/
keywords::auto_flush = false, keywords::auto_flush = false,
keywords::format = "[%TimeStamp%]: %Message%" keywords::format = "[%TimeStamp%]: %Message%"
); );
logging::core::get()->set_filter logging::core::get()->set_filter
( (
logging::trivial::severity >= logging::trivial::info logging::trivial::severity >= logging::trivial::info
); );
} }
int main(int argc, char* []) int main(int argc, char* [])
{ {
int howmany = 1000000; int howmany = 1000000;
init(); init();
logging::add_common_attributes(); logging::add_common_attributes();
using namespace logging::trivial; using namespace logging::trivial;
src::severity_logger_mt< severity_level > lg; src::severity_logger_mt< severity_level > lg;
for(int i = 0 ; i < howmany; ++i) for(int i = 0 ; i < howmany; ++i)
BOOST_LOG_SEV(lg, info) << "boost message #" << i << ": This is some text for your pleasure"; BOOST_LOG_SEV(lg, info) << "boost message #" << i << ": This is some text for your pleasure";
return 0; return 0;
} }
...@@ -11,37 +11,37 @@ using namespace std; ...@@ -11,37 +11,37 @@ using namespace std;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int thread_count = 10; int thread_count = 10;
if(argc > 1) if(argc > 1)
thread_count = atoi(argv[1]); thread_count = atoi(argv[1]);
int howmany = 1000000; int howmany = 1000000;
// Load configuration from file // Load configuration from file
el::Configurations conf("easyl.conf"); el::Configurations conf("easyl.conf");
el::Loggers::reconfigureLogger("default", conf); el::Loggers::reconfigureLogger("default", conf);
std::atomic<int > msg_counter {0}; std::atomic<int > msg_counter {0};
vector<thread> threads; vector<thread> threads;
for (int t = 0; t < thread_count; ++t) for (int t = 0; t < thread_count; ++t)
{ {
threads.push_back(std::thread([&]() threads.push_back(std::thread([&]()
{ {
while (true) while (true)
{ {
int counter = ++msg_counter; int counter = ++msg_counter;
if (counter > howmany) break; if (counter > howmany) break;
LOG(INFO) << "easylog message #" << counter << ": This is some text for your pleasure"; LOG(INFO) << "easylog message #" << counter << ": This is some text for your pleasure";
} }
})); }));
} }
for(auto &t:threads) for(auto &t:threads)
{ {
t.join(); t.join();
}; };
return 0; return 0;
} }
...@@ -5,12 +5,12 @@ _INITIALIZE_EASYLOGGINGPP ...@@ -5,12 +5,12 @@ _INITIALIZE_EASYLOGGINGPP
int main(int, char* []) int main(int, char* [])
{ {
int howmany = 1000000; int howmany = 1000000;
// Load configuration from file // Load configuration from file
el::Configurations conf("easyl.conf"); el::Configurations conf("easyl.conf");
el::Loggers::reconfigureLogger("default", conf); el::Loggers::reconfigureLogger("default", conf);
for(int i = 0 ; i < howmany; ++i) for(int i = 0 ; i < howmany; ++i)
LOG(INFO) << "easylog message #" << i << ": This is some text for your pleasure"; LOG(INFO) << "easylog message #" << i << ": This is some text for your pleasure";
return 0; return 0;
} }
...@@ -14,44 +14,44 @@ int main(int argc, char* argv[]) ...@@ -14,44 +14,44 @@ int main(int argc, char* argv[])
{ {
using namespace std::chrono; using namespace std::chrono;
using clock=steady_clock; using clock=steady_clock;
int thread_count = 10; int thread_count = 10;
if(argc > 1)
thread_count = atoi(argv[1]);
int howmany = 1000000;
g2LogWorker g2log(argv[0], "logs"); if(argc > 1)
g2::initializeLogging(&g2log); thread_count = atoi(argv[1]);
int howmany = 1000000;
g2LogWorker g2log(argv[0], "logs");
g2::initializeLogging(&g2log);
std::atomic<int > msg_counter {0};
vector<thread> threads; std::atomic<int > msg_counter {0};
vector<thread> threads;
auto start = clock::now(); auto start = clock::now();
for (int t = 0; t < thread_count; ++t) for (int t = 0; t < thread_count; ++t)
{ {
threads.push_back(std::thread([&]() threads.push_back(std::thread([&]()
{ {
while (true) while (true)
{ {
int counter = ++msg_counter; int counter = ++msg_counter;
if (counter > howmany) break; if (counter > howmany) break;
LOG(INFO) << "g2log message #" << counter << ": This is some text for your pleasure"; LOG(INFO) << "g2log message #" << counter << ": This is some text for your pleasure";
} }
})); }));
} }
for(auto &t:threads) for(auto &t:threads)
{ {
t.join(); t.join();
}; };
duration<float> delta = clock::now() - start; duration<float> delta = clock::now() - start;
float deltaf = delta.count(); float deltaf = delta.count();
auto rate = howmany/deltaf; auto rate = howmany/deltaf;
cout << "Total: " << howmany << std::endl; cout << "Total: " << howmany << std::endl;
cout << "Threads: " << thread_count << std::endl; cout << "Threads: " << thread_count << std::endl;
std::cout << "Delta = " << deltaf << " seconds" << std::endl; std::cout << "Delta = " << deltaf << " seconds" << std::endl;
std::cout << "Rate = " << rate << "/sec" << std::endl; std::cout << "Rate = " << rate << "/sec" << std::endl;
} }
...@@ -9,37 +9,37 @@ using namespace std; ...@@ -9,37 +9,37 @@ using namespace std;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int thread_count = 10; int thread_count = 10;
if(argc > 1) if(argc > 1)
thread_count = atoi(argv[1]); thread_count = atoi(argv[1]);
int howmany = 1000000; int howmany = 1000000;
FLAGS_logtostderr = 0; FLAGS_logtostderr = 0;
FLAGS_log_dir = "logs"; FLAGS_log_dir = "logs";
google::InitGoogleLogging(argv[0]); google::InitGoogleLogging(argv[0]);
std::atomic<int > msg_counter {0}; std::atomic<int > msg_counter {0};
vector<thread> threads; vector<thread> threads;
for (int t = 0; t < thread_count; ++t) for (int t = 0; t < thread_count; ++t)
{ {
threads.push_back(std::thread([&]() threads.push_back(std::thread([&]()
{ {
while (true) while (true)
{ {
int counter = ++msg_counter; int counter = ++msg_counter;
if (counter > howmany) break; if (counter > howmany) break;
LOG(INFO) << "glog message #" << counter << ": This is some text for your pleasure"; LOG(INFO) << "glog message #" << counter << ": This is some text for your pleasure";
} }
})); }));
} }
for(auto &t:threads) for(auto &t:threads)
{ {
t.join(); t.join();
}; };
return 0; return 0;
} }
...@@ -4,14 +4,14 @@ ...@@ -4,14 +4,14 @@
int main(int, char* argv[]) int main(int, char* argv[])
{ {
int howmany = 1000000; int howmany = 1000000;
FLAGS_logtostderr = 0; FLAGS_logtostderr = 0;
FLAGS_log_dir = "logs"; FLAGS_log_dir = "logs";
google::InitGoogleLogging(argv[0]); google::InitGoogleLogging(argv[0]);
for(int i = 0 ; i < howmany; ++i) for(int i = 0 ; i < howmany; ++i)
LOG(INFO) << "glog message # " << i << ": This is some text for your pleasure"; LOG(INFO) << "glog message # " << i << ": This is some text for your pleasure";
return 0; return 0;
} }
...@@ -11,48 +11,48 @@ using namespace std; ...@@ -11,48 +11,48 @@ using namespace std;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
using namespace std::chrono; using namespace std::chrono;
using clock=steady_clock; using clock=steady_clock;
namespace spd = spdlog; namespace spd = spdlog;
int thread_count = 10; int thread_count = 10;
if(argc > 1) if(argc > 1)
thread_count = atoi(argv[1]); thread_count = atoi(argv[1]);
int howmany = 1000000; int howmany = 1000000;
spd::set_async_mode(1048576); spd::set_async_mode(1048576);
auto logger = spdlog::create<spd::sinks::simple_file_sink_mt>("file_logger", "logs/spd-bench-async.txt", false); auto logger = spdlog::create<spd::sinks::simple_file_sink_mt>("file_logger", "logs/spd-bench-async.txt", false);
logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); logger->set_pattern("[%Y-%b-%d %T.%e]: %v");
std::atomic<int > msg_counter {0}; std::atomic<int > msg_counter {0};
vector<thread> threads; vector<thread> threads;
auto start = clock::now(); auto start = clock::now();
for (int t = 0; t < thread_count; ++t) for (int t = 0; t < thread_count; ++t)
{ {
threads.push_back(std::thread([&]() threads.push_back(std::thread([&]()
{ {
while (true) while (true)
{ {
int counter = ++msg_counter; int counter = ++msg_counter;
if (counter > howmany) break; if (counter > howmany) break;
logger->info() << "spdlog message #" << counter << ": This is some text for your pleasure"; logger->info() << "spdlog message #" << counter << ": This is some text for your pleasure";
} }
})); }));
} }
for(auto &t:threads) for(auto &t:threads)
{ {
t.join(); t.join();
}; };
duration<float> delta = clock::now() - start; duration<float> delta = clock::now() - start;
float deltaf = delta.count(); float deltaf = delta.count();
auto rate = howmany/deltaf; auto rate = howmany/deltaf;
cout << "Total: " << howmany << std::endl; cout << "Total: " << howmany << std::endl;
cout << "Threads: " << thread_count << std::endl; cout << "Threads: " << thread_count << std::endl;
std::cout << "Delta = " << deltaf << " seconds" << std::endl; std::cout << "Delta = " << deltaf << " seconds" << std::endl;
std::cout << "Rate = " << rate << "/sec" << std::endl; std::cout << "Rate = " << rate << "/sec" << std::endl;
} }
...@@ -10,41 +10,41 @@ using namespace std; ...@@ -10,41 +10,41 @@ using namespace std;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int thread_count = 10; int thread_count = 10;
if(argc > 1) if(argc > 1)
thread_count = atoi(argv[1]); thread_count = atoi(argv[1]);
int howmany = 1000000; int howmany = 1000000;
namespace spd = spdlog; namespace spd = spdlog;
auto logger = spdlog::create<spd::sinks::simple_file_sink_mt>("file_logger", "logs/spd-bench-mt.txt", false); auto logger = spdlog::create<spd::sinks::simple_file_sink_mt>("file_logger", "logs/spd-bench-mt.txt", false);
logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); logger->set_pattern("[%Y-%b-%d %T.%e]: %v");
std::atomic<int > msg_counter {0}; std::atomic<int > msg_counter {0};
vector<thread> threads; vector<thread> threads;
for (int t = 0; t < thread_count; ++t) for (int t = 0; t < thread_count; ++t)
{ {
threads.push_back(std::thread([&]() threads.push_back(std::thread([&]()
{ {
while (true) while (true)
{ {
int counter = ++msg_counter; int counter = ++msg_counter;
if (counter > howmany) break; if (counter > howmany) break;
logger->info() << "spdlog message #" << counter << ": This is some text for your pleasure"; logger->info() << "spdlog message #" << counter << ": This is some text for your pleasure";
} }
})); }));
} }
for(auto &t:threads) for(auto &t:threads)
{ {
t.join(); t.join();
}; };
return 0; return 0;
} }
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
int main(int, char* []) int main(int, char* [])
{ {
int howmany = 1000000; int howmany = 1000000;
namespace spd = spdlog; namespace spd = spdlog;
///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 logger = spdlog::create<spd::sinks::simple_file_sink_st>("file_logger", "logs/spd-bench-st.txt", false); auto logger = spdlog::create<spd::sinks::simple_file_sink_st>("file_logger", "logs/spd-bench-st.txt", false);
logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); logger->set_pattern("[%Y-%b-%d %T.%e]: %v");
for(int i = 0 ; i < howmany; ++i) for(int i = 0 ; i < howmany; ++i)
logger->info() << "spdlog message #" << i << ": This is some text for your pleasure"; logger->info() << "spdlog message #" << i << ": This is some text for your pleasure";
return 0; return 0;
} }
...@@ -50,110 +50,110 @@ void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count ...@@ -50,110 +50,110 @@ void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int howmany = 1048576; int howmany = 1048576;
int threads = 10; int threads = 10;
bool auto_flush = false; bool auto_flush = false;
int file_size = 30 * 1024 * 1024; int file_size = 30 * 1024 * 1024;
int rotating_files = 5; int rotating_files = 5;
try try
{ {
if(argc > 1) if(argc > 1)
howmany = atoi(argv[1]); howmany = atoi(argv[1]);
if (argc > 2) if (argc > 2)
threads = atoi(argv[2]); threads = atoi(argv[2]);
cout << "*******************************************************************************\n"; cout << "*******************************************************************************\n";
cout << "Single thread, " << format(howmany) << " iterations, auto flush=" << auto_flush << endl; cout << "Single thread, " << format(howmany) << " iterations, auto flush=" << auto_flush << endl;
cout << "*******************************************************************************\n"; cout << "*******************************************************************************\n";
auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st", file_size, rotating_files, auto_flush); auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st", file_size, rotating_files, auto_flush);
bench(howmany, rotating_st); bench(howmany, rotating_st);
auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st", auto_flush); auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st", auto_flush);
bench(howmany, daily_st); bench(howmany, daily_st);
bench(howmany, spdlog::create<null_sink_st>("null_st")); bench(howmany, spdlog::create<null_sink_st>("null_st"));
cout << "\n*******************************************************************************\n"; cout << "\n*******************************************************************************\n";
cout << threads << " threads sharing same logger, " << format(howmany) << " iterations, auto_flush=" << auto_flush << endl; cout << threads << " threads sharing same logger, " << format(howmany) << " iterations, auto_flush=" << auto_flush << endl;
cout << "*******************************************************************************\n"; cout << "*******************************************************************************\n";
auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt", file_size, rotating_files, auto_flush); auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt", file_size, rotating_files, auto_flush);
bench_mt(howmany, rotating_mt, threads); bench_mt(howmany, rotating_mt, threads);
auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt", auto_flush); auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt", auto_flush);
bench_mt(howmany, daily_mt, threads); bench_mt(howmany, daily_mt, threads);
bench(howmany, spdlog::create<null_sink_st>("null_mt")); bench(howmany, spdlog::create<null_sink_st>("null_mt"));
cout << "\n*******************************************************************************\n"; cout << "\n*******************************************************************************\n";
cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " iterations, auto_flush=" << auto_flush << endl; cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " iterations, auto_flush=" << auto_flush << endl;
cout << "*******************************************************************************\n"; cout << "*******************************************************************************\n";
spdlog::set_async_mode(howmany); spdlog::set_async_mode(howmany);
for(int i = 0; i < 3; ++i) for(int i = 0; i < 3; ++i)
{ {
auto as = spdlog::daily_logger_st("as", "logs/daily_async", auto_flush); auto as = spdlog::daily_logger_st("as", "logs/daily_async", auto_flush);
bench_mt(howmany, as, threads); bench_mt(howmany, as, threads);
spdlog::drop("as"); spdlog::drop("as");
} }
} }
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 0; return 0;
} }
void bench(int howmany, std::shared_ptr<spdlog::logger> log) void bench(int howmany, std::shared_ptr<spdlog::logger> log)
{ {
cout << log->name() << "...\t\t" << flush; cout << log->name() << "...\t\t" << flush;
auto start = system_clock::now(); auto start = system_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 = system_clock::now() - start; auto delta = system_clock::now() - start;
auto delta_d = duration_cast<duration<double>> (delta).count(); auto delta_d = duration_cast<duration<double>> (delta).count();
cout << format(int(howmany / delta_d)) << "/sec" << endl; cout << format(int(howmany / delta_d)) << "/sec" << endl;
} }
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)
{ {
cout << log->name() << "...\t\t" << flush; cout << log->name() << "...\t\t" << flush;
std::atomic<int > msg_counter {0}; std::atomic<int > msg_counter {0};
vector<thread> threads; vector<thread> threads;
auto start = system_clock::now(); auto start = system_clock::now();
for (int t = 0; t < thread_count; ++t) for (int t = 0; t < thread_count; ++t)
{ {
threads.push_back(std::thread([&]() threads.push_back(std::thread([&]()
{ {
for(;;) for(;;)
{ {
int counter = ++msg_counter; int counter = ++msg_counter;
if (counter > howmany) break; if (counter > howmany) break;
log->info("Hello logger: msg number {}", counter); log->info("Hello logger: msg number {}", counter);
} }
})); }));
} }
for(auto &t:threads) for(auto &t:threads)
{ {
t.join(); t.join();
}; };
auto delta = system_clock::now() - start; auto delta = system_clock::now() - start;
auto delta_d = duration_cast<duration<double>> (delta).count(); auto delta_d = duration_cast<duration<double>> (delta).count();
cout << format(int(howmany / delta_d)) << "/sec" << endl; cout << format(int(howmany / delta_d)) << "/sec" << endl;
} }
...@@ -30,61 +30,61 @@ ...@@ -30,61 +30,61 @@
int main(int, char* []) int main(int, char* [])
{ {
namespace spd = spdlog; namespace spd = spdlog;
try try
{ {
// Set log level to all loggers to debug and above // Set log level to all loggers to debug and above
spd::set_level(spd::level::debug); spd::set_level(spd::level::debug);
// Create console, multithreaded logger // Create console, multithreaded logger
auto console = spd::stdout_logger_mt("console"); auto console = spd::stdout_logger_mt("console");
console->info("Welcome to spdlog!") ; console->info("Welcome to spdlog!") ;
console->info("An info message example {}..", 1); console->info("An info message example {}..", 1);
console->info() << "Streams are supported too " << 1; console->info() << "Streams are supported too " << 1;
console->info("Easy padding in numbers like {:08d}", 12); console->info("Easy padding in numbers like {:08d}", 12);
console->info("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); console->info("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
console->info("Support for floats {:03.2f}", 1.23456); console->info("Support for floats {:03.2f}", 1.23456);
console->info("Positional args are {1} {0}..", "too", "supported"); console->info("Positional args are {1} {0}..", "too", "supported");
console->info("{:<30}", "left aligned"); console->info("{:<30}", "left aligned");
console->info("{:>30}", "right aligned"); console->info("{:>30}", "right aligned");
console->info("{:^30}", "centered"); console->info("{:^30}", "centered");
// Create a file rotating logger with 5mb size max and 3 rotated files
auto file_logger = spd::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3);
file_logger->set_level(spd::level::info);
for(int i = 0; i < 10; ++i)
file_logger->info("{} * {} equals {:>10}", i, i, i*i);
// Customize msg format for all messages // Create a file rotating logger with 5mb size max and 3 rotated files
spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); auto file_logger = spd::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3);
file_logger->info("This is another message with custom format"); file_logger->set_level(spd::level::info);
for(int i = 0; i < 10; ++i)
file_logger->info("{} * {} equals {:>10}", i, i, i*i);
spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"); // Customize msg format for all messages
spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
file_logger->info("This is another message with custom format");
SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23); spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");
SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);
// SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23);
// Asynchronous logging is very fast.. SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
//
size_t q_size = 1048576; //queue size must be power of 2
spdlog::set_async_mode(q_size);
auto async_file= spd::daily_logger_st("async_file_logger", "logs/async_log.txt");
async_file->info() << "This is async log.." << "Should be very fast!";
// syslog example. linux only..
#ifdef __linux__
std::string ident = "spdlog-example";
auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID);
syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!");
#endif
} //
catch (const spd::spdlog_ex& ex) // Asynchronous logging is very fast..
{ // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
std::cout << "Log failed: " << ex.what() << std::endl; //
} size_t q_size = 1048576; //queue size must be power of 2
spdlog::set_async_mode(q_size);
auto async_file= spd::daily_logger_st("async_file_logger", "logs/async_log.txt");
async_file->info() << "This is async log.." << "Should be very fast!";
// syslog example. linux only..
#ifdef __linux__
std::string ident = "spdlog-example";
auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID);
syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!");
#endif
}
catch (const spd::spdlog_ex& ex)
{
std::cout << "Log failed: " << ex.what() << std::endl;
}
} }
...@@ -34,21 +34,21 @@ namespace utils ...@@ -34,21 +34,21 @@ 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);
ss << value; ss << 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);
ss << std::fixed << std::setprecision(1) << value; ss << std::fixed << std::setprecision(1) << value;
return ss.str(); return ss.str();
} }
} }
...@@ -50,20 +50,20 @@ class async_log_helper; ...@@ -50,20 +50,20 @@ class async_log_helper;
class async_logger :public logger class async_logger :public logger
{ {
public: public:
template<class It> template<class It>
async_logger(const std::string& name, const It& begin, const It& end, size_t queue_size); async_logger(const std::string& name, const It& begin, const It& end, size_t queue_size);
async_logger(const std::string& logger_name, sinks_init_list sinks, size_t queue_size); async_logger(const std::string& logger_name, sinks_init_list sinks, size_t queue_size);
async_logger(const std::string& logger_name, sink_ptr single_sink, size_t queue_size); async_logger(const std::string& logger_name, sink_ptr single_sink, size_t queue_size);
protected: protected:
void _log_msg(details::log_msg& msg) override; void _log_msg(details::log_msg& msg) override;
void _set_formatter(spdlog::formatter_ptr msg_formatter) override; void _set_formatter(spdlog::formatter_ptr msg_formatter) override;
void _set_pattern(const std::string& pattern) override; void _set_pattern(const std::string& pattern) override;
void _stop() override; void _stop() override;
private: private:
std::unique_ptr<details::async_log_helper> _async_log_helper; std::unique_ptr<details::async_log_helper> _async_log_helper;
}; };
} }
......
...@@ -39,7 +39,8 @@ namespace spdlog ...@@ -39,7 +39,8 @@ namespace spdlog
class formatter; class formatter;
namespace sinks { namespace sinks
{
class sink; class sink;
} }
...@@ -70,7 +71,7 @@ static const char* level_names[] { "trace", "debug", "info", "notice", "warning" ...@@ -70,7 +71,7 @@ static const char* level_names[] { "trace", "debug", "info", "notice", "warning"
inline const char* to_str(spdlog::level::level_enum l) inline const char* to_str(spdlog::level::level_enum l)
{ {
return level_names[l]; return level_names[l];
} }
} //level } //level
...@@ -80,13 +81,13 @@ inline const char* to_str(spdlog::level::level_enum l) ...@@ -80,13 +81,13 @@ inline const char* to_str(spdlog::level::level_enum l)
class spdlog_ex : public std::exception class spdlog_ex : public std::exception
{ {
public: public:
spdlog_ex(const std::string& msg) :_msg(msg) {} spdlog_ex(const std::string& msg) :_msg(msg) {}
const char* what() const SPDLOG_NOEXCEPT override const char* what() const SPDLOG_NOEXCEPT override
{ {
return _msg.c_str(); return _msg.c_str();
} }
private: private:
std::string _msg; std::string _msg;
}; };
......
...@@ -52,93 +52,93 @@ namespace details ...@@ -52,93 +52,93 @@ namespace details
class async_log_helper class async_log_helper
{ {
// Async msg to move to/from the queue // Async msg to move to/from the queue
// Movable only. should never be copied // Movable only. should never be copied
struct async_msg struct async_msg
{ {
std::string logger_name; std::string logger_name;
level::level_enum level; level::level_enum level;
log_clock::time_point time; log_clock::time_point time;
std::string txt; std::string txt;
async_msg() = default; async_msg() = default;
~async_msg() = default; ~async_msg() = default;
async_msg(const async_msg&) = delete; async_msg(const async_msg&) = delete;
async_msg& operator=(async_msg& other) = delete; async_msg& operator=(async_msg& other) = delete;
async_msg(const details::log_msg& m) : async_msg(const details::log_msg& m) :
logger_name(m.logger_name), logger_name(m.logger_name),
level(m.level), level(m.level),
time(m.time), time(m.time),
txt(m.raw.data(), m.raw.size()) txt(m.raw.data(), m.raw.size())
{} {}
async_msg(async_msg&& other) : async_msg(async_msg&& other) :
logger_name(std::move(other.logger_name)), logger_name(std::move(other.logger_name)),
level(std::move(other.level)), level(std::move(other.level)),
time(std::move(other.time)), time(std::move(other.time)),
txt(std::move(other.txt)) txt(std::move(other.txt))
{} {}
async_msg& operator=(async_msg&& other) async_msg& operator=(async_msg&& other)
{ {
logger_name = std::move(other.logger_name); logger_name = std::move(other.logger_name);
level = other.level; level = other.level;
time = std::move(other.time); time = std::move(other.time);
txt = std::move(other.txt); txt = std::move(other.txt);
return *this; return *this;
} }
void fill_log_msg(log_msg &msg) void fill_log_msg(log_msg &msg)
{ {
msg.clear(); msg.clear();
msg.logger_name = logger_name; msg.logger_name = logger_name;
msg.level = level; msg.level = level;
msg.time = time; msg.time = time;
msg.raw << txt; msg.raw << txt;
} }
}; };
public: public:
using item_type = async_msg; using item_type = async_msg;
using q_type = details::mpmc_bounded_queue<item_type>; using q_type = details::mpmc_bounded_queue<item_type>;
using clock = std::chrono::steady_clock; using clock = std::chrono::steady_clock;
async_log_helper(formatter_ptr formatter, const std::vector<sink_ptr>& sinks, size_t queue_size); async_log_helper(formatter_ptr formatter, const std::vector<sink_ptr>& sinks, size_t queue_size);
void log(const details::log_msg& msg); void log(const details::log_msg& msg);
//Stop logging and join the back thread //Stop logging and join the back thread
~async_log_helper(); ~async_log_helper();
void set_formatter(formatter_ptr); void set_formatter(formatter_ptr);
private: private:
formatter_ptr _formatter; formatter_ptr _formatter;
std::vector<std::shared_ptr<sinks::sink>> _sinks; std::vector<std::shared_ptr<sinks::sink>> _sinks;
q_type _q; q_type _q;
std::thread _worker_thread; std::thread _worker_thread;
// last exception thrown from the worker thread // last exception thrown from the worker thread
std::shared_ptr<spdlog_ex> _last_workerthread_ex; std::shared_ptr<spdlog_ex> _last_workerthread_ex;
// throw last worker thread exception or if worker thread is not active // throw last worker thread exception or if worker thread is not active
void throw_if_bad_worker(); void throw_if_bad_worker();
// worker thread main loop // worker thread main loop
void worker_loop(); void worker_loop();
//pop next message from the queue and process it //pop next message from the queue and process it
//return true if a message was available (queue was not empty), will set the last_pop to the pop time //return true if a message was available (queue was not empty), will set the last_pop to the pop time
bool process_next_msg(clock::time_point& last_pop); bool process_next_msg(clock::time_point& last_pop);
// guess how much to sleep if queue is empty/full using last succesful op time as hint // guess how much to sleep if queue is empty/full using last succesful op time as hint
static void sleep_or_yield(const clock::time_point& last_op_time); static void sleep_or_yield(const clock::time_point& last_op_time);
}; };
} }
...@@ -148,10 +148,10 @@ private: ...@@ -148,10 +148,10 @@ private:
// async_sink class implementation // async_sink class implementation
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
inline spdlog::details::async_log_helper::async_log_helper(formatter_ptr formatter, const std::vector<sink_ptr>& sinks, size_t queue_size): inline spdlog::details::async_log_helper::async_log_helper(formatter_ptr formatter, const std::vector<sink_ptr>& sinks, size_t queue_size):
_formatter(formatter), _formatter(formatter),
_sinks(sinks), _sinks(sinks),
_q(queue_size), _q(queue_size),
_worker_thread(&async_log_helper::worker_loop, this) _worker_thread(&async_log_helper::worker_loop, this)
{} {}
// Send to the worker thread termination message(level=off) // Send to the worker thread termination message(level=off)
...@@ -159,48 +159,48 @@ inline spdlog::details::async_log_helper::async_log_helper(formatter_ptr formatt ...@@ -159,48 +159,48 @@ inline spdlog::details::async_log_helper::async_log_helper(formatter_ptr formatt
inline spdlog::details::async_log_helper::~async_log_helper() inline spdlog::details::async_log_helper::~async_log_helper()
{ {
try try
{ {
log(log_msg(level::off)); log(log_msg(level::off));
_worker_thread.join(); _worker_thread.join();
} }
catch (...) //Dont crash if thread not joinable catch (...) //Dont crash if thread not joinable
{} {}
} }
//Try to push and block until succeeded //Try to push and block until succeeded
inline void spdlog::details::async_log_helper::log(const details::log_msg& msg) inline void spdlog::details::async_log_helper::log(const details::log_msg& msg)
{ {
throw_if_bad_worker(); throw_if_bad_worker();
async_msg new_msg(msg); async_msg new_msg(msg);
if (!_q.enqueue(std::move(new_msg))) if (!_q.enqueue(std::move(new_msg)))
{ {
auto last_op_time = clock::now(); auto last_op_time = clock::now();
do do
{ {
sleep_or_yield(last_op_time); sleep_or_yield(last_op_time);
} }
while (!_q.enqueue(std::move(new_msg))); while (!_q.enqueue(std::move(new_msg)));
} }
} }
inline void spdlog::details::async_log_helper::worker_loop() inline void spdlog::details::async_log_helper::worker_loop()
{ {
try try
{ {
clock::time_point last_pop = clock::now(); clock::time_point last_pop = clock::now();
while(process_next_msg(last_pop)); while(process_next_msg(last_pop));
} }
catch (const std::exception& ex) catch (const std::exception& ex)
{ {
_last_workerthread_ex = std::make_shared<spdlog_ex>(std::string("async_logger worker thread exception: ") + ex.what()); _last_workerthread_ex = std::make_shared<spdlog_ex>(std::string("async_logger worker thread exception: ") + ex.what());
} }
catch (...) catch (...)
{ {
_last_workerthread_ex = std::make_shared<spdlog_ex>("async_logger worker thread exception"); _last_workerthread_ex = std::make_shared<spdlog_ex>("async_logger worker thread exception");
} }
} }
// Process next message in the queue // Process next message in the queue
...@@ -208,66 +208,66 @@ inline void spdlog::details::async_log_helper::worker_loop() ...@@ -208,66 +208,66 @@ inline void spdlog::details::async_log_helper::worker_loop()
inline bool spdlog::details::async_log_helper::process_next_msg(clock::time_point& last_pop) inline bool spdlog::details::async_log_helper::process_next_msg(clock::time_point& last_pop)
{ {
async_msg incoming_async_msg; async_msg incoming_async_msg;
log_msg incoming_log_msg; log_msg incoming_log_msg;
if (_q.dequeue(incoming_async_msg)) if (_q.dequeue(incoming_async_msg))
{ {
last_pop = clock::now(); last_pop = clock::now();
if(incoming_async_msg.level == level::off) if(incoming_async_msg.level == level::off)
return false; return false;
incoming_async_msg.fill_log_msg(incoming_log_msg); incoming_async_msg.fill_log_msg(incoming_log_msg);
_formatter->format(incoming_log_msg); _formatter->format(incoming_log_msg);
for (auto &s : _sinks) for (auto &s : _sinks)
s->log(incoming_log_msg); s->log(incoming_log_msg);
} }
else //empty queue else //empty queue
{ {
sleep_or_yield(last_pop); sleep_or_yield(last_pop);
} }
return true; return true;
} }
inline void spdlog::details::async_log_helper::set_formatter(formatter_ptr msg_formatter) inline void spdlog::details::async_log_helper::set_formatter(formatter_ptr msg_formatter)
{ {
_formatter = msg_formatter; _formatter = msg_formatter;
} }
// Sleep,yield or return immediatly using the time passed since last message as a hint // Sleep,yield or return immediatly using the time passed since last message as a hint
inline void spdlog::details::async_log_helper::sleep_or_yield(const clock::time_point& last_op_time) inline void spdlog::details::async_log_helper::sleep_or_yield(const clock::time_point& last_op_time)
{ {
using std::chrono::milliseconds; using std::chrono::milliseconds;
using namespace std::this_thread; using namespace std::this_thread;
auto time_since_op = clock::now() - last_op_time; auto time_since_op = clock::now() - last_op_time;
//spin upto 1 ms //spin upto 1 ms
if (time_since_op <= milliseconds(1)) if (time_since_op <= milliseconds(1))
return; return;
// yield upto 10ms // yield upto 10ms
if (time_since_op <= milliseconds(10)) if (time_since_op <= milliseconds(10))
return yield(); return yield();
// sleep for half of duration since last op // sleep for half of duration since last op
if (time_since_op <= milliseconds(100)) if (time_since_op <= milliseconds(100))
return sleep_for(time_since_op / 2); return sleep_for(time_since_op / 2);
return sleep_for(milliseconds(100)); return sleep_for(milliseconds(100));
} }
//throw if the worker thread threw an exception or not active //throw if the worker thread threw an exception or not active
inline void spdlog::details::async_log_helper::throw_if_bad_worker() inline void spdlog::details::async_log_helper::throw_if_bad_worker()
{ {
if (_last_workerthread_ex) if (_last_workerthread_ex)
{ {
auto ex = std::move(_last_workerthread_ex); auto ex = std::move(_last_workerthread_ex);
throw *ex; throw *ex;
} }
} }
......
...@@ -35,38 +35,38 @@ ...@@ -35,38 +35,38 @@
template<class It> template<class It>
inline spdlog::async_logger::async_logger(const std::string& logger_name, const It& begin, const It& end, size_t queue_size) : inline spdlog::async_logger::async_logger(const std::string& logger_name, const It& begin, const It& end, size_t queue_size) :
logger(logger_name, begin, end), logger(logger_name, begin, end),
_async_log_helper(new details::async_log_helper(_formatter, _sinks, queue_size)) _async_log_helper(new details::async_log_helper(_formatter, _sinks, queue_size))
{ {
} }
inline spdlog::async_logger::async_logger(const std::string& logger_name, sinks_init_list sinks, size_t queue_size) : inline spdlog::async_logger::async_logger(const std::string& logger_name, sinks_init_list sinks, size_t queue_size) :
async_logger(logger_name, sinks.begin(), sinks.end(), queue_size) {} async_logger(logger_name, sinks.begin(), sinks.end(), queue_size) {}
inline spdlog::async_logger::async_logger(const std::string& logger_name, sink_ptr single_sink, size_t queue_size) : inline spdlog::async_logger::async_logger(const std::string& logger_name, sink_ptr single_sink, size_t queue_size) :
async_logger(logger_name, { single_sink }, queue_size) {} async_logger(logger_name, { single_sink }, queue_size) {}
inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_formatter) inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_formatter)
{ {
_formatter = msg_formatter; _formatter = msg_formatter;
_async_log_helper->set_formatter(_formatter); _async_log_helper->set_formatter(_formatter);
} }
inline void spdlog::async_logger::_set_pattern(const std::string& pattern) inline void spdlog::async_logger::_set_pattern(const std::string& pattern)
{ {
_formatter = std::make_shared<pattern_formatter>(pattern); _formatter = std::make_shared<pattern_formatter>(pattern);
_async_log_helper->set_formatter(_formatter); _async_log_helper->set_formatter(_formatter);
} }
inline void spdlog::async_logger::_stop() inline void spdlog::async_logger::_stop()
{ {
set_level(level::off); set_level(level::off);
} }
inline void spdlog::async_logger::_log_msg(details::log_msg& msg) inline void spdlog::async_logger::_log_msg(details::log_msg& msg)
{ {
_async_log_helper->log(msg); _async_log_helper->log(msg);
} }
...@@ -45,93 +45,93 @@ namespace details ...@@ -45,93 +45,93 @@ namespace details
class file_helper class file_helper
{ {
public: public:
const int open_tries = 5; const int open_tries = 5;
const int open_interval = 10; const int open_interval = 10;
explicit file_helper(bool auto_flush): explicit file_helper(bool auto_flush):
_fd(nullptr), _fd(nullptr),
_auto_flush(auto_flush) _auto_flush(auto_flush)
{} {}
file_helper(const file_helper&) = delete; file_helper(const file_helper&) = delete;
file_helper& operator=(const file_helper&) = delete; file_helper& operator=(const file_helper&) = delete;
~file_helper() ~file_helper()
{ {
close(); close();
} }
void open(const std::string& fname, bool truncate=false) void open(const std::string& fname, bool truncate=false)
{ {
close(); close();
const char* mode = truncate ? "wb" : "ab"; const char* mode = truncate ? "wb" : "ab";
_filename = fname; _filename = fname;
for (int tries = 0; tries < open_tries; ++tries) for (int tries = 0; tries < open_tries; ++tries)
{ {
if(!os::fopen_s(&_fd, fname, mode)) if(!os::fopen_s(&_fd, fname, mode))
return; return;
std::this_thread::sleep_for(std::chrono::milliseconds(open_interval)); std::this_thread::sleep_for(std::chrono::milliseconds(open_interval));
} }
throw spdlog_ex("Failed opening file " + fname + " for writing"); throw spdlog_ex("Failed opening file " + fname + " for writing");
} }
void reopen(bool truncate) void reopen(bool truncate)
{ {
if(_filename.empty()) if(_filename.empty())
throw spdlog_ex("Failed re opening file - was not opened before"); throw spdlog_ex("Failed re opening file - was not opened before");
open(_filename, truncate); open(_filename, truncate);
} }
void close() void close()
{ {
if (_fd) if (_fd)
{ {
std::fclose(_fd); std::fclose(_fd);
_fd = nullptr; _fd = nullptr;
} }
} }
void write(const log_msg& msg) void write(const log_msg& msg)
{ {
size_t size = msg.formatted.size(); size_t size = msg.formatted.size();
auto data = msg.formatted.data(); auto data = msg.formatted.data();
if(std::fwrite(data, 1, size, _fd) != size) if(std::fwrite(data, 1, size, _fd) != size)
throw spdlog_ex("Failed writing to file " + _filename); throw spdlog_ex("Failed writing to file " + _filename);
if(_auto_flush) if(_auto_flush)
std::fflush(_fd); std::fflush(_fd);
} }
const std::string& filename() const const std::string& filename() const
{ {
return _filename; return _filename;
} }
static bool file_exists(const std::string& name) static bool file_exists(const std::string& name)
{ {
FILE* file; FILE* file;
if (!os::fopen_s(&file, name.c_str(), "r")) if (!os::fopen_s(&file, name.c_str(), "r"))
{ {
fclose(file); fclose(file);
return true; return true;
} }
else else
{ {
return false; return false;
} }
} }
private: private:
FILE* _fd; FILE* _fd;
std::string _filename; std::string _filename;
bool _auto_flush; bool _auto_flush;
}; };
......
This diff is collapsed.
...@@ -38,73 +38,73 @@ namespace details ...@@ -38,73 +38,73 @@ namespace details
class line_logger class line_logger
{ {
public: public:
line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled): line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled):
_callback_logger(callback_logger), _callback_logger(callback_logger),
_log_msg(msg_level), _log_msg(msg_level),
_enabled(enabled) _enabled(enabled)
{} {}
// No copy intended. Only move // No copy intended. Only move
line_logger(const line_logger& other) = delete; line_logger(const line_logger& other) = delete;
line_logger& operator=(const line_logger&) = delete; line_logger& operator=(const line_logger&) = delete;
line_logger& operator=(line_logger&&) = delete; line_logger& operator=(line_logger&&) = delete;
line_logger(line_logger&& other) : line_logger(line_logger&& other) :
_callback_logger(other._callback_logger), _callback_logger(other._callback_logger),
_log_msg(std::move(other._log_msg)), _log_msg(std::move(other._log_msg)),
_enabled(other._enabled) _enabled(other._enabled)
{ {
other.disable(); other.disable();
} }
//Log the log message using the callback logger //Log the log message using the callback logger
~line_logger() ~line_logger()
{ {
if (_enabled) if (_enabled)
{ {
_log_msg.logger_name = _callback_logger->name(); _log_msg.logger_name = _callback_logger->name();
_log_msg.time = log_clock::now(); _log_msg.time = log_clock::now();
_callback_logger->_log_msg(_log_msg); _callback_logger->_log_msg(_log_msg);
} }
} }
template <typename... Args> template <typename... Args>
void write(const char* fmt, const Args&... args) void write(const char* fmt, const Args&... args)
{ {
if (!_enabled) if (!_enabled)
return; return;
try try
{ {
_log_msg.raw.write(fmt, args...); _log_msg.raw.write(fmt, args...);
} }
catch (const fmt::FormatError& e) catch (const fmt::FormatError& e)
{ {
throw spdlog_ex(fmt::format("formatting error while processing format string '{}': {}", fmt, e.what())); throw spdlog_ex(fmt::format("formatting error while processing format string '{}': {}", fmt, e.what()));
} }
} }
template<typename T> template<typename T>
line_logger& operator<<(const T& what) line_logger& operator<<(const T& what)
{ {
if (_enabled) if (_enabled)
_log_msg.raw << what; _log_msg.raw << what;
return *this; return *this;
} }
void disable() void disable()
{ {
_enabled = false; _enabled = false;
} }
private: private:
logger* _callback_logger; logger* _callback_logger;
log_msg _log_msg; log_msg _log_msg;
bool _enabled; bool _enabled;
}; };
} //Namespace details } //Namespace details
} // Namespace spdlog } // Namespace spdlog
...@@ -33,63 +33,62 @@ namespace details ...@@ -33,63 +33,62 @@ namespace details
{ {
struct log_msg struct log_msg
{ {
log_msg() = default; log_msg() = default;
log_msg(level::level_enum l): log_msg(level::level_enum l):
logger_name(), logger_name(),
level(l), level(l),
time(), time(),
raw(), raw(),
formatted() {} formatted() {}
log_msg(const log_msg& other) : log_msg(const log_msg& other) :
logger_name(other.logger_name), logger_name(other.logger_name),
level(other.level), level(other.level),
time(other.time) time(other.time)
{ {
if (other.raw.size()) if (other.raw.size())
raw << fmt::BasicStringRef<char>(other.raw.data(), other.raw.size()); raw << fmt::BasicStringRef<char>(other.raw.data(), other.raw.size());
if (other.formatted.size()) if (other.formatted.size())
formatted << fmt::BasicStringRef<char>(other.formatted.data(), other.formatted.size()); formatted << fmt::BasicStringRef<char>(other.formatted.data(), other.formatted.size());
}
} log_msg(log_msg&& other) :
logger_name(std::move(other.logger_name)),
level(other.level),
time(std::move(other.time)),
raw(std::move(other.raw)),
formatted(std::move(other.formatted))
{
other.clear();
}
log_msg(log_msg&& other) : log_msg& operator=(log_msg&& other)
logger_name(std::move(other.logger_name)), {
level(other.level), if (this == &other)
time(std::move(other.time)), return *this;
raw(std::move(other.raw)),
formatted(std::move(other.formatted))
{
other.clear();
}
log_msg& operator=(log_msg&& other) logger_name = std::move(other.logger_name);
{ level = other.level;
if (this == &other) time = std::move(other.time);
return *this; raw = std::move(other.raw);
formatted = std::move(other.formatted);
other.clear();
return *this;
}
logger_name = std::move(other.logger_name); void clear()
level = other.level; {
time = std::move(other.time); level = level::off;
raw = std::move(other.raw); raw.clear();
formatted = std::move(other.formatted); formatted.clear();
other.clear(); }
return *this;
}
void clear() std::string logger_name;
{ level::level_enum level;
level = level::off; log_clock::time_point time;
raw.clear(); fmt::MemoryWriter raw;
formatted.clear(); fmt::MemoryWriter formatted;
}
std::string logger_name;
level::level_enum level;
log_clock::time_point time;
fmt::MemoryWriter raw;
fmt::MemoryWriter formatted;
}; };
} }
} }
...@@ -34,23 +34,23 @@ ...@@ -34,23 +34,23 @@
// all other ctors will call this one // all other ctors will call this one
template<class It> template<class It>
inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end) : inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end) :
_name(logger_name), _name(logger_name),
_sinks(begin, end), _sinks(begin, end),
_formatter(std::make_shared<pattern_formatter>("%+")) _formatter(std::make_shared<pattern_formatter>("%+"))
{ {
// no support under vs2013 for member initialization for std::atomic // no support under vs2013 for member initialization for std::atomic
_level = level::info; _level = level::info;
} }
// ctor with sinks as init list // ctor with sinks as init list
inline spdlog::logger::logger(const std::string& logger_name, sinks_init_list sinks_list) : inline spdlog::logger::logger(const std::string& logger_name, sinks_init_list sinks_list) :
logger(logger_name, sinks_list.begin(), sinks_list.end()) {} logger(logger_name, sinks_list.begin(), sinks_list.end()) {}
// ctor with single sink // ctor with single sink
inline spdlog::logger::logger(const std::string& logger_name, spdlog::sink_ptr single_sink) : inline spdlog::logger::logger(const std::string& logger_name, spdlog::sink_ptr single_sink) :
logger(logger_name, { single_sink }) {} logger(logger_name, { single_sink }) {}
inline spdlog::logger::~logger() = default; inline spdlog::logger::~logger() = default;
...@@ -58,12 +58,12 @@ inline spdlog::logger::~logger() = default; ...@@ -58,12 +58,12 @@ inline spdlog::logger::~logger() = default;
inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter) inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter)
{ {
_set_formatter(msg_formatter); _set_formatter(msg_formatter);
} }
inline void spdlog::logger::set_pattern(const std::string& pattern) inline void spdlog::logger::set_pattern(const std::string& pattern)
{ {
_set_pattern(pattern); _set_pattern(pattern);
} }
// //
...@@ -74,15 +74,15 @@ inline void spdlog::logger::set_pattern(const std::string& pattern) ...@@ -74,15 +74,15 @@ inline void spdlog::logger::set_pattern(const std::string& pattern)
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args)
{ {
bool msg_enabled = should_log(lvl); bool msg_enabled = should_log(lvl);
details::line_logger l(this, lvl, msg_enabled); details::line_logger l(this, lvl, msg_enabled);
l.write(fmt, args...); l.write(fmt, args...);
return l; return l;
} }
inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl) inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl)
{ {
return details::line_logger(this, lvl, should_log(lvl)); return details::line_logger(this, lvl, should_log(lvl));
} }
...@@ -92,55 +92,55 @@ inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level ...@@ -92,55 +92,55 @@ inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::trace(const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::trace(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::trace, fmt, args...); return _log_if_enabled(level::trace, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::debug(const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::debug(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::debug, fmt, args...); return _log_if_enabled(level::debug, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::info(const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::info(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::info, fmt, args...); return _log_if_enabled(level::info, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::notice(const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::notice(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::notice, fmt, args...); return _log_if_enabled(level::notice, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::warn(const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::warn(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::warn, fmt, args...); return _log_if_enabled(level::warn, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::error(const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::error(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::err, fmt, args...); return _log_if_enabled(level::err, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::critical(const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::critical(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::critical, fmt, args...); return _log_if_enabled(level::critical, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::alert(const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::alert(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::alert, fmt, args...); return _log_if_enabled(level::alert, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::emerg(const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::emerg(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::emerg, fmt, args...); return _log_if_enabled(level::emerg, fmt, args...);
} }
...@@ -152,48 +152,48 @@ inline spdlog::details::line_logger spdlog::logger::emerg(const char* fmt, const ...@@ -152,48 +152,48 @@ inline spdlog::details::line_logger spdlog::logger::emerg(const char* fmt, const
inline spdlog::details::line_logger spdlog::logger::trace() inline spdlog::details::line_logger spdlog::logger::trace()
{ {
return _log_if_enabled(level::trace); return _log_if_enabled(level::trace);
} }
inline spdlog::details::line_logger spdlog::logger::debug() inline spdlog::details::line_logger spdlog::logger::debug()
{ {
return _log_if_enabled(level::debug); return _log_if_enabled(level::debug);
} }
inline spdlog::details::line_logger spdlog::logger::info() inline spdlog::details::line_logger spdlog::logger::info()
{ {
return _log_if_enabled(level::info); return _log_if_enabled(level::info);
} }
inline spdlog::details::line_logger spdlog::logger::notice() inline spdlog::details::line_logger spdlog::logger::notice()
{ {
return _log_if_enabled(level::notice); return _log_if_enabled(level::notice);
} }
inline spdlog::details::line_logger spdlog::logger::warn() inline spdlog::details::line_logger spdlog::logger::warn()
{ {
return _log_if_enabled(level::warn); return _log_if_enabled(level::warn);
} }
inline spdlog::details::line_logger spdlog::logger::error() inline spdlog::details::line_logger spdlog::logger::error()
{ {
return _log_if_enabled(level::err); return _log_if_enabled(level::err);
} }
inline spdlog::details::line_logger spdlog::logger::critical() inline spdlog::details::line_logger spdlog::logger::critical()
{ {
return _log_if_enabled(level::critical); return _log_if_enabled(level::critical);
} }
inline spdlog::details::line_logger spdlog::logger::alert() inline spdlog::details::line_logger spdlog::logger::alert()
{ {
return _log_if_enabled(level::alert); return _log_if_enabled(level::alert);
} }
inline spdlog::details::line_logger spdlog::logger::emerg() inline spdlog::details::line_logger spdlog::logger::emerg()
{ {
return _log_if_enabled(level::emerg); return _log_if_enabled(level::emerg);
} }
...@@ -201,9 +201,9 @@ inline spdlog::details::line_logger spdlog::logger::emerg() ...@@ -201,9 +201,9 @@ inline spdlog::details::line_logger spdlog::logger::emerg()
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::force_log(level::level_enum lvl, const char* fmt, const Args&... args) inline spdlog::details::line_logger spdlog::logger::force_log(level::level_enum lvl, const char* fmt, const Args&... args)
{ {
details::line_logger l(this, lvl, true); details::line_logger l(this, lvl, true);
l.write(fmt, args...); l.write(fmt, args...);
return l; return l;
} }
// //
...@@ -211,27 +211,27 @@ inline spdlog::details::line_logger spdlog::logger::force_log(level::level_enum ...@@ -211,27 +211,27 @@ inline spdlog::details::line_logger spdlog::logger::force_log(level::level_enum
// //
inline const std::string& spdlog::logger::name() const inline const std::string& spdlog::logger::name() const
{ {
return _name; return _name;
} }
inline void spdlog::logger::set_level(spdlog::level::level_enum log_level) inline void spdlog::logger::set_level(spdlog::level::level_enum log_level)
{ {
_level.store(log_level); _level.store(log_level);
} }
inline spdlog::level::level_enum spdlog::logger::level() const inline spdlog::level::level_enum spdlog::logger::level() const
{ {
return static_cast<spdlog::level::level_enum>(_level.load()); return static_cast<spdlog::level::level_enum>(_level.load());
} }
inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) const inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) const
{ {
return msg_level >= _level.load(); return msg_level >= _level.load();
} }
inline void spdlog::logger::stop() inline void spdlog::logger::stop()
{ {
_stop(); _stop();
} }
// //
...@@ -239,23 +239,23 @@ inline void spdlog::logger::stop() ...@@ -239,23 +239,23 @@ inline void spdlog::logger::stop()
// //
inline void spdlog::logger::_log_msg(details::log_msg& msg) inline void spdlog::logger::_log_msg(details::log_msg& msg)
{ {
_formatter->format(msg); _formatter->format(msg);
for (auto &sink : _sinks) for (auto &sink : _sinks)
sink->log(msg); sink->log(msg);
} }
inline void spdlog::logger::_set_pattern(const std::string& pattern) inline void spdlog::logger::_set_pattern(const std::string& pattern)
{ {
_formatter = std::make_shared<pattern_formatter>(pattern); _formatter = std::make_shared<pattern_formatter>(pattern);
} }
inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter) inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter)
{ {
_formatter = msg_formatter; _formatter = msg_formatter;
} }
inline void spdlog::logger::_stop() inline void spdlog::logger::_stop()
{ {
set_level(level::off); set_level(level::off);
} }
......
...@@ -74,101 +74,101 @@ class mpmc_bounded_queue ...@@ -74,101 +74,101 @@ class mpmc_bounded_queue
{ {
public: public:
using item_type = T; using item_type = T;
mpmc_bounded_queue(size_t buffer_size) mpmc_bounded_queue(size_t buffer_size)
: buffer_(new cell_t [buffer_size]), : buffer_(new cell_t [buffer_size]),
buffer_mask_(buffer_size - 1) buffer_mask_(buffer_size - 1)
{ {
//queue size must be power of two //queue size must be power of two
if(!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0))) if(!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0)))
throw spdlog_ex("async logger queue size must be power of two"); throw spdlog_ex("async logger queue size must be power of two");
for (size_t i = 0; i != buffer_size; i += 1) for (size_t i = 0; i != buffer_size; i += 1)
buffer_[i].sequence_.store(i, std::memory_order_relaxed); buffer_[i].sequence_.store(i, std::memory_order_relaxed);
enqueue_pos_.store(0, std::memory_order_relaxed); enqueue_pos_.store(0, std::memory_order_relaxed);
dequeue_pos_.store(0, std::memory_order_relaxed); dequeue_pos_.store(0, std::memory_order_relaxed);
} }
~mpmc_bounded_queue() ~mpmc_bounded_queue()
{ {
delete [] buffer_; delete [] buffer_;
} }
bool enqueue(T&& data) bool enqueue(T&& data)
{ {
cell_t* cell; cell_t* cell;
size_t pos = enqueue_pos_.load(std::memory_order_relaxed); size_t pos = enqueue_pos_.load(std::memory_order_relaxed);
for (;;) for (;;)
{ {
cell = &buffer_[pos & buffer_mask_]; cell = &buffer_[pos & buffer_mask_];
size_t seq = cell->sequence_.load(std::memory_order_acquire); size_t seq = cell->sequence_.load(std::memory_order_acquire);
intptr_t dif = (intptr_t)seq - (intptr_t)pos; intptr_t dif = (intptr_t)seq - (intptr_t)pos;
if (dif == 0) if (dif == 0)
{ {
if (enqueue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) if (enqueue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed))
break; break;
} }
else if (dif < 0) else if (dif < 0)
{ {
return false; return false;
} }
else else
{ {
pos = enqueue_pos_.load(std::memory_order_relaxed); pos = enqueue_pos_.load(std::memory_order_relaxed);
} }
} }
cell->data_ = std::move(data); cell->data_ = std::move(data);
cell->sequence_.store(pos + 1, std::memory_order_release); cell->sequence_.store(pos + 1, std::memory_order_release);
return true; return true;
} }
bool dequeue(T& data) bool dequeue(T& data)
{ {
cell_t* cell; cell_t* cell;
size_t pos = dequeue_pos_.load(std::memory_order_relaxed); size_t pos = dequeue_pos_.load(std::memory_order_relaxed);
for (;;) for (;;)
{ {
cell = &buffer_[pos & buffer_mask_]; cell = &buffer_[pos & buffer_mask_];
size_t seq = size_t seq =
cell->sequence_.load(std::memory_order_acquire); cell->sequence_.load(std::memory_order_acquire);
intptr_t dif = (intptr_t)seq - (intptr_t)(pos + 1); intptr_t dif = (intptr_t)seq - (intptr_t)(pos + 1);
if (dif == 0) if (dif == 0)
{ {
if (dequeue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) if (dequeue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed))
break; break;
} }
else if (dif < 0) else if (dif < 0)
return false; return false;
else else
pos = dequeue_pos_.load(std::memory_order_relaxed); pos = dequeue_pos_.load(std::memory_order_relaxed);
} }
data = std::move(cell->data_); data = std::move(cell->data_);
cell->sequence_.store(pos + buffer_mask_ + 1, std::memory_order_release); cell->sequence_.store(pos + buffer_mask_ + 1, std::memory_order_release);
return true; return true;
} }
private: private:
struct cell_t struct cell_t
{ {
std::atomic<size_t> sequence_; std::atomic<size_t> sequence_;
T data_; T data_;
}; };
static size_t const cacheline_size = 64; static size_t const cacheline_size = 64;
typedef char cacheline_pad_t [cacheline_size]; typedef char cacheline_pad_t [cacheline_size];
cacheline_pad_t pad0_; cacheline_pad_t pad0_;
cell_t* const buffer_; cell_t* const buffer_;
size_t const buffer_mask_; size_t const buffer_mask_;
cacheline_pad_t pad1_; cacheline_pad_t pad1_;
std::atomic<size_t> enqueue_pos_; std::atomic<size_t> enqueue_pos_;
cacheline_pad_t pad2_; cacheline_pad_t pad2_;
std::atomic<size_t> dequeue_pos_; std::atomic<size_t> dequeue_pos_;
cacheline_pad_t pad3_; cacheline_pad_t pad3_;
mpmc_bounded_queue(mpmc_bounded_queue const&); mpmc_bounded_queue(mpmc_bounded_queue const&);
void operator = (mpmc_bounded_queue const&); void operator = (mpmc_bounded_queue const&);
}; };
} // ns details } // ns details
......
...@@ -32,12 +32,12 @@ namespace details ...@@ -32,12 +32,12 @@ namespace details
{ {
struct null_mutex struct null_mutex
{ {
void lock() {} void lock() {}
void unlock() {} void unlock() {}
bool try_lock() bool try_lock()
{ {
return true; return true;
} }
}; };
} }
} }
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
#endif #endif
namespace spdlog namespace spdlog
{ {
...@@ -44,19 +44,19 @@ inline std::tm localtime(const std::time_t &time_tt) ...@@ -44,19 +44,19 @@ inline std::tm localtime(const std::time_t &time_tt)
{ {
#ifdef _WIN32 #ifdef _WIN32
std::tm tm; std::tm tm;
localtime_s(&tm, &time_tt); localtime_s(&tm, &time_tt);
#else #else
std::tm tm; std::tm tm;
localtime_r(&time_tt, &tm); localtime_r(&time_tt, &tm);
#endif #endif
return tm; return tm;
} }
inline std::tm localtime() inline std::tm localtime()
{ {
std::time_t now_t = time(0); std::time_t now_t = time(0);
return localtime(now_t); return localtime(now_t);
} }
...@@ -64,57 +64,57 @@ inline std::tm gmtime(const std::time_t &time_tt) ...@@ -64,57 +64,57 @@ inline std::tm gmtime(const std::time_t &time_tt)
{ {
#ifdef _WIN32 #ifdef _WIN32
std::tm tm; std::tm tm;
gmtime_s(&tm, &time_tt); gmtime_s(&tm, &time_tt);
#else #else
std::tm tm; std::tm tm;
gmtime_r(&time_tt, &tm); gmtime_r(&time_tt, &tm);
#endif #endif
return tm; return tm;
} }
inline std::tm gmtime() inline std::tm gmtime()
{ {
std::time_t now_t = time(0); std::time_t now_t = time(0);
return gmtime(now_t); return gmtime(now_t);
} }
inline bool operator==(const std::tm& tm1, const std::tm& tm2) inline bool operator==(const std::tm& tm1, const std::tm& tm2)
{ {
return (tm1.tm_sec == tm2.tm_sec && return (tm1.tm_sec == tm2.tm_sec &&
tm1.tm_min == tm2.tm_min && tm1.tm_min == tm2.tm_min &&
tm1.tm_hour == tm2.tm_hour && tm1.tm_hour == tm2.tm_hour &&
tm1.tm_mday == tm2.tm_mday && tm1.tm_mday == tm2.tm_mday &&
tm1.tm_mon == tm2.tm_mon && tm1.tm_mon == tm2.tm_mon &&
tm1.tm_year == tm2.tm_year && tm1.tm_year == tm2.tm_year &&
tm1.tm_isdst == tm2.tm_isdst); tm1.tm_isdst == tm2.tm_isdst);
} }
inline bool operator!=(const std::tm& tm1, const std::tm& tm2) inline bool operator!=(const std::tm& tm1, const std::tm& tm2)
{ {
return !(tm1 == tm2); return !(tm1 == tm2);
} }
#ifdef _WIN32 #ifdef _WIN32
inline const char* eol() inline const char* eol()
{ {
return "\r\n"; return "\r\n";
} }
#else #else
constexpr inline const char* eol() constexpr inline const char* eol()
{ {
return "\n"; return "\n";
} }
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
inline unsigned short eol_size() inline unsigned short eol_size()
{ {
return 2; return 2;
} }
#else #else
constexpr inline unsigned short eol_size() constexpr inline unsigned short eol_size()
{ {
return 1; return 1;
} }
#endif #endif
...@@ -122,11 +122,11 @@ constexpr inline unsigned short eol_size() ...@@ -122,11 +122,11 @@ constexpr inline unsigned short eol_size()
inline int fopen_s(FILE** fp, const std::string& filename, const char* mode) inline int fopen_s(FILE** fp, const std::string& filename, const char* mode)
{ {
#ifdef _WIN32 #ifdef _WIN32
*fp = _fsopen((filename.c_str()), mode, _SH_DENYWR); *fp = _fsopen((filename.c_str()), mode, _SH_DENYWR);
return *fp == nullptr; return *fp == nullptr;
#else #else
*fp = fopen((filename.c_str()), mode); *fp = fopen((filename.c_str()), mode);
return *fp == nullptr; return *fp == nullptr;
#endif #endif
...@@ -137,14 +137,14 @@ inline int utc_minutes_offset(const std::tm& tm = details::os::localtime()) ...@@ -137,14 +137,14 @@ inline int utc_minutes_offset(const std::tm& tm = details::os::localtime())
{ {
#ifdef _WIN32 #ifdef _WIN32
(void)tm; // avoid unused param warning (void)tm; // avoid unused param warning
DYNAMIC_TIME_ZONE_INFORMATION tzinfo; DYNAMIC_TIME_ZONE_INFORMATION tzinfo;
auto rv = GetDynamicTimeZoneInformation(&tzinfo); auto rv = GetDynamicTimeZoneInformation(&tzinfo);
if (!rv) if (!rv)
return -1; return -1;
return -1 * (tzinfo.Bias + tzinfo.DaylightBias); return -1 * (tzinfo.Bias + tzinfo.DaylightBias);
#else #else
return static_cast<int>(tm.tm_gmtoff / 60); return static_cast<int>(tm.tm_gmtoff / 60);
#endif #endif
} }
......
...@@ -44,114 +44,114 @@ namespace details ...@@ -44,114 +44,114 @@ namespace details
class registry class registry
{ {
public: public:
std::shared_ptr<logger> get(const std::string& logger_name) std::shared_ptr<logger> get(const std::string& logger_name)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
auto found = _loggers.find(logger_name); auto found = _loggers.find(logger_name);
return found == _loggers.end() ? nullptr : found->second; return found == _loggers.end() ? nullptr : found->second;
} }
template<class It> template<class It>
std::shared_ptr<logger> create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) std::shared_ptr<logger> create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
//If already exists, just return it //If already exists, just return it
auto found = _loggers.find(logger_name); auto found = _loggers.find(logger_name);
if (found != _loggers.end()) if (found != _loggers.end())
return found->second; return found->second;
std::shared_ptr<logger> new_logger; std::shared_ptr<logger> new_logger;
if (_async_mode) if (_async_mode)
new_logger = std::make_shared<async_logger>(logger_name, sinks_begin, sinks_end, _async_q_size); new_logger = std::make_shared<async_logger>(logger_name, sinks_begin, sinks_end, _async_q_size);
else else
new_logger = std::make_shared<logger>(logger_name, sinks_begin, sinks_end); new_logger = std::make_shared<logger>(logger_name, sinks_begin, sinks_end);
if (_formatter) if (_formatter)
new_logger->set_formatter(_formatter); new_logger->set_formatter(_formatter);
new_logger->set_level(_level); new_logger->set_level(_level);
_loggers[logger_name] = new_logger; _loggers[logger_name] = new_logger;
return new_logger; return new_logger;
} }
void drop(const std::string& logger_name) void drop(const std::string& logger_name)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
_loggers.erase(logger_name); _loggers.erase(logger_name);
} }
std::shared_ptr<logger> create(const std::string& logger_name, sinks_init_list sinks) std::shared_ptr<logger> create(const std::string& logger_name, sinks_init_list sinks)
{ {
return create(logger_name, sinks.begin(), sinks.end()); return create(logger_name, sinks.begin(), sinks.end());
} }
std::shared_ptr<logger> create(const std::string& logger_name, sink_ptr sink) std::shared_ptr<logger> create(const std::string& logger_name, sink_ptr sink)
{ {
return create(logger_name, { sink }); return create(logger_name, { sink });
} }
void formatter(formatter_ptr f) void formatter(formatter_ptr f)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
_formatter = f; _formatter = f;
for (auto& l : _loggers) for (auto& l : _loggers)
l.second->set_formatter(_formatter); l.second->set_formatter(_formatter);
} }
void set_pattern(const std::string& pattern) void set_pattern(const std::string& pattern)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
_formatter = std::make_shared<pattern_formatter>(pattern); _formatter = std::make_shared<pattern_formatter>(pattern);
for (auto& l : _loggers) for (auto& l : _loggers)
l.second->set_formatter(_formatter); l.second->set_formatter(_formatter);
} }
void set_level(level::level_enum log_level) void set_level(level::level_enum log_level)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
for (auto& l : _loggers) for (auto& l : _loggers)
l.second->set_level(log_level); l.second->set_level(log_level);
} }
void set_async_mode(size_t q_size) void set_async_mode(size_t q_size)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
_async_mode = true; _async_mode = true;
_async_q_size = q_size; _async_q_size = q_size;
} }
void set_sync_mode() void set_sync_mode()
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
_async_mode = false; _async_mode = false;
} }
void stop_all() void stop_all()
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
_level = level::off; _level = level::off;
for (auto& l : _loggers) for (auto& l : _loggers)
l.second->stop(); l.second->stop();
} }
static registry& instance() static registry& instance()
{ {
static registry s_instance; static registry s_instance;
return s_instance; return s_instance;
} }
private: private:
registry() = default; registry() = default;
registry(const registry&) = delete; registry(const registry&) = delete;
registry& operator=(const registry&) = delete; registry& operator=(const registry&) = delete;
std::mutex _mutex; std::mutex _mutex;
std::unordered_map <std::string, std::shared_ptr<logger>> _loggers; std::unordered_map <std::string, std::shared_ptr<logger>> _loggers;
formatter_ptr _formatter; formatter_ptr _formatter;
level::level_enum _level = level::info; level::level_enum _level = level::info;
bool _async_mode = false; bool _async_mode = false;
size_t _async_q_size = 0; size_t _async_q_size = 0;
}; };
} }
} }
...@@ -34,62 +34,62 @@ ...@@ -34,62 +34,62 @@
inline std::shared_ptr<spdlog::logger> spdlog::get(const std::string& name) inline std::shared_ptr<spdlog::logger> spdlog::get(const std::string& name)
{ {
return details::registry::instance().get(name); return details::registry::instance().get(name);
} }
inline void spdlog::drop(const std::string &name) inline void spdlog::drop(const std::string &name)
{ {
details::registry::instance().drop(name); details::registry::instance().drop(name);
} }
// Create multi/single threaded rotating file logger // Create multi/single threaded rotating file logger
inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_mt(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool auto_flush) inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_mt(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool auto_flush)
{ {
return create<spdlog::sinks::rotating_file_sink_mt>(logger_name, filename, "txt", max_file_size, max_files, auto_flush); return create<spdlog::sinks::rotating_file_sink_mt>(logger_name, filename, "txt", max_file_size, max_files, auto_flush);
} }
inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_st(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool auto_flush) inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_st(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool auto_flush)
{ {
return create<spdlog::sinks::rotating_file_sink_st>(logger_name, filename, "txt", max_file_size, max_files, auto_flush); return create<spdlog::sinks::rotating_file_sink_st>(logger_name, filename, "txt", max_file_size, max_files, auto_flush);
} }
// Create file logger which creates new file at midnight): // Create file logger which creates new file at midnight):
inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_mt(const std::string& logger_name, const std::string& filename, bool auto_flush) inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_mt(const std::string& logger_name, const std::string& filename, bool auto_flush)
{ {
return create<spdlog::sinks::daily_file_sink_mt>(logger_name, filename, "txt", auto_flush); return create<spdlog::sinks::daily_file_sink_mt>(logger_name, filename, "txt", auto_flush);
} }
inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_st(const std::string& logger_name, const std::string& filename, bool auto_flush) inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_st(const std::string& logger_name, const std::string& filename, bool auto_flush)
{ {
return create<spdlog::sinks::daily_file_sink_st>(logger_name, filename, "txt", auto_flush); return create<spdlog::sinks::daily_file_sink_st>(logger_name, filename, "txt", auto_flush);
} }
// Create stdout/stderr loggers // Create stdout/stderr loggers
inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt(const std::string& logger_name)
{ {
return create<spdlog::sinks::stdout_sink_mt>(logger_name); return create<spdlog::sinks::stdout_sink_mt>(logger_name);
} }
inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st(const std::string& logger_name)
{ {
return create<spdlog::sinks::stdout_sink_st>(logger_name); return create<spdlog::sinks::stdout_sink_st>(logger_name);
} }
inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt(const std::string& logger_name)
{ {
return create<spdlog::sinks::stderr_sink_mt>(logger_name); return create<spdlog::sinks::stderr_sink_mt>(logger_name);
} }
inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::string& logger_name)
{ {
return create<spdlog::sinks::stderr_sink_st>(logger_name); return create<spdlog::sinks::stderr_sink_st>(logger_name);
} }
#ifdef __linux__ #ifdef __linux__
// Create syslog logger // Create syslog logger
inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option) inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option)
{ {
return create<spdlog::sinks::syslog_sink>(logger_name, syslog_ident, syslog_option); return create<spdlog::sinks::syslog_sink>(logger_name, syslog_ident, syslog_option);
} }
#endif #endif
...@@ -98,51 +98,51 @@ inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string& ...@@ -98,51 +98,51 @@ inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string&
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks) inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks)
{ {
return details::registry::instance().create(logger_name, sinks); return details::registry::instance().create(logger_name, sinks);
} }
template <typename Sink, typename... Args> template <typename Sink, typename... Args>
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const Args&... args) inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const Args&... args)
{ {
sink_ptr sink = std::make_shared<Sink>(args...); sink_ptr sink = std::make_shared<Sink>(args...);
return details::registry::instance().create(logger_name, { sink }); return details::registry::instance().create(logger_name, { sink });
} }
template<class It> template<class It>
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end)
{ {
return details::registry::instance().create(logger_name, sinks_begin, sinks_end); return details::registry::instance().create(logger_name, sinks_begin, sinks_end);
} }
inline void spdlog::set_formatter(spdlog::formatter_ptr f) inline void spdlog::set_formatter(spdlog::formatter_ptr f)
{ {
details::registry::instance().formatter(f); details::registry::instance().formatter(f);
} }
inline void spdlog::set_pattern(const std::string& format_string) inline void spdlog::set_pattern(const std::string& format_string)
{ {
return details::registry::instance().set_pattern(format_string); return details::registry::instance().set_pattern(format_string);
} }
inline void spdlog::set_level(level::level_enum log_level) inline void spdlog::set_level(level::level_enum log_level)
{ {
return details::registry::instance().set_level(log_level); return details::registry::instance().set_level(log_level);
} }
inline void spdlog::set_async_mode(size_t queue_size) inline void spdlog::set_async_mode(size_t queue_size)
{ {
details::registry::instance().set_async_mode(queue_size); details::registry::instance().set_async_mode(queue_size);
} }
inline void spdlog::set_sync_mode() inline void spdlog::set_sync_mode()
{ {
details::registry::instance().set_sync_mode(); details::registry::instance().set_sync_mode();
} }
inline void spdlog::stop() inline void spdlog::stop()
{ {
return details::registry::instance().stop_all(); return details::registry::instance().stop_all();
} }
...@@ -34,23 +34,23 @@ class flag_formatter; ...@@ -34,23 +34,23 @@ class flag_formatter;
class formatter class formatter
{ {
public: public:
virtual ~formatter() {} virtual ~formatter() {}
virtual void format(details::log_msg& msg) = 0; virtual void format(details::log_msg& msg) = 0;
}; };
class pattern_formatter : public formatter class pattern_formatter : public formatter
{ {
public: public:
explicit pattern_formatter(const std::string& pattern); explicit pattern_formatter(const std::string& pattern);
pattern_formatter(const pattern_formatter&) = delete; pattern_formatter(const pattern_formatter&) = delete;
pattern_formatter& operator=(const pattern_formatter&) = delete; pattern_formatter& operator=(const pattern_formatter&) = delete;
void format(details::log_msg& msg) override; void format(details::log_msg& msg) override;
private: private:
const std::string _pattern; const std::string _pattern;
std::vector<std::unique_ptr<details::flag_formatter>> _formatters; std::vector<std::unique_ptr<details::flag_formatter>> _formatters;
void handle_flag(char flag); void handle_flag(char flag);
void compile_pattern(const std::string& pattern); void compile_pattern(const std::string& pattern);
}; };
} }
......
...@@ -47,88 +47,88 @@ class line_logger; ...@@ -47,88 +47,88 @@ class line_logger;
class logger class logger
{ {
public: public:
logger(const std::string& logger_name, sink_ptr single_sink); logger(const std::string& logger_name, sink_ptr single_sink);
logger(const std::string& name, sinks_init_list); logger(const std::string& name, sinks_init_list);
template<class It> template<class It>
logger(const std::string& name, const It& begin, const It& end); logger(const std::string& name, const It& begin, const It& end);
virtual ~logger(); virtual ~logger();
logger(const logger&) = delete; logger(const logger&) = delete;
logger& operator=(const logger&) = delete; logger& operator=(const logger&) = delete;
void set_level(level::level_enum); void set_level(level::level_enum);
level::level_enum level() const; level::level_enum level() const;
const std::string& name() const; const std::string& name() const;
bool should_log(level::level_enum) const; bool should_log(level::level_enum) const;
//Stop logging //Stop logging
void stop(); void stop();
template <typename... Args> template <typename... Args>
details::line_logger trace(const char* fmt, const Args&... args); details::line_logger trace(const char* fmt, const Args&... args);
template <typename... Args> template <typename... Args>
details::line_logger debug(const char* fmt, const Args&... args); details::line_logger debug(const char* fmt, const Args&... args);
template <typename... Args> template <typename... Args>
details::line_logger info(const char* fmt, const Args&... args); details::line_logger info(const char* fmt, const Args&... args);
template <typename... Args> template <typename... Args>
details::line_logger notice(const char* fmt, const Args&... args); details::line_logger notice(const char* fmt, const Args&... args);
template <typename... Args> template <typename... Args>
details::line_logger warn(const char* fmt, const Args&... args); details::line_logger warn(const char* fmt, const Args&... args);
template <typename... Args>details::line_logger error(const char* fmt, const Args&... args); template <typename... Args>details::line_logger error(const char* fmt, const Args&... args);
template <typename... Args> template <typename... Args>
details::line_logger critical(const char* fmt, const Args&... args); details::line_logger critical(const char* fmt, const Args&... args);
template <typename... Args> template <typename... Args>
details::line_logger alert(const char* fmt, const Args&... args); details::line_logger alert(const char* fmt, const Args&... args);
template <typename... Args> template <typename... Args>
details::line_logger emerg(const char* fmt, const Args&... args); details::line_logger emerg(const char* fmt, const Args&... args);
//API to support logger.info() << ".." call style //API to support logger.info() << ".." call style
details::line_logger trace(); details::line_logger trace();
details::line_logger debug(); details::line_logger debug();
details::line_logger info(); details::line_logger info();
details::line_logger notice(); details::line_logger notice();
details::line_logger warn(); details::line_logger warn();
details::line_logger error(); details::line_logger error();
details::line_logger critical(); details::line_logger critical();
details::line_logger alert(); details::line_logger alert();
details::line_logger emerg(); details::line_logger emerg();
// Create log message with the given level, no matter what is the actual logger's level // Create log message with the given level, no matter what is the actual logger's level
template <typename... Args> template <typename... Args>
details::line_logger force_log(level::level_enum lvl, const char* fmt, const Args&... args); details::line_logger force_log(level::level_enum lvl, const char* fmt, const Args&... args);
// Set the format of the log messages from this logger // Set the format of the log messages from this logger
void set_pattern(const std::string&); void set_pattern(const std::string&);
void set_formatter(formatter_ptr); void set_formatter(formatter_ptr);
protected: protected:
virtual void _log_msg(details::log_msg&); virtual void _log_msg(details::log_msg&);
virtual void _set_pattern(const std::string&); virtual void _set_pattern(const std::string&);
virtual void _set_formatter(formatter_ptr); virtual void _set_formatter(formatter_ptr);
virtual void _stop(); virtual void _stop();
details::line_logger _log_if_enabled(level::level_enum lvl); details::line_logger _log_if_enabled(level::level_enum lvl);
template <typename... Args> template <typename... Args>
details::line_logger _log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args); details::line_logger _log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args);
friend details::line_logger; friend details::line_logger;
std::string _name; std::string _name;
std::vector<sink_ptr> _sinks; std::vector<sink_ptr> _sinks;
formatter_ptr _formatter; formatter_ptr _formatter;
std::atomic_int _level; std::atomic_int _level;
}; };
} }
......
...@@ -46,22 +46,22 @@ template<class Mutex> ...@@ -46,22 +46,22 @@ template<class Mutex>
class base_sink:public sink class base_sink:public sink
{ {
public: public:
base_sink():_mutex() {} base_sink():_mutex() {}
virtual ~base_sink() = default; virtual ~base_sink() = default;
base_sink(const base_sink&) = delete; base_sink(const base_sink&) = delete;
base_sink& operator=(const base_sink&) = delete; base_sink& operator=(const base_sink&) = delete;
void log(const details::log_msg& msg) override void log(const details::log_msg& msg) override
{ {
std::lock_guard<Mutex> lock(_mutex); std::lock_guard<Mutex> lock(_mutex);
_sink_it(msg); _sink_it(msg);
} }
protected: protected:
virtual void _sink_it(const details::log_msg& msg) = 0; virtual void _sink_it(const details::log_msg& msg) = 0;
Mutex _mutex; Mutex _mutex;
}; };
} }
} }
...@@ -43,20 +43,20 @@ template<class Mutex> ...@@ -43,20 +43,20 @@ template<class Mutex>
class simple_file_sink : public base_sink<Mutex> class simple_file_sink : public base_sink<Mutex>
{ {
public: public:
explicit simple_file_sink(const std::string &filename, explicit simple_file_sink(const std::string &filename,
bool auto_flush=false): bool auto_flush=false):
_file_helper(auto_flush) _file_helper(auto_flush)
{ {
_file_helper.open(filename); _file_helper.open(filename);
} }
protected: protected:
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
_file_helper.write(msg); _file_helper.write(msg);
} }
private: private:
details::file_helper _file_helper; details::file_helper _file_helper;
}; };
typedef simple_file_sink<std::mutex> simple_file_sink_mt; typedef simple_file_sink<std::mutex> simple_file_sink_mt;
...@@ -69,80 +69,80 @@ template<class Mutex> ...@@ -69,80 +69,80 @@ template<class Mutex>
class rotating_file_sink : public base_sink<Mutex> class rotating_file_sink : public base_sink<Mutex>
{ {
public: public:
rotating_file_sink(const std::string &base_filename, const std::string &extension, rotating_file_sink(const std::string &base_filename, const std::string &extension,
std::size_t max_size, std::size_t max_files, std::size_t max_size, std::size_t max_files,
bool auto_flush=false): bool auto_flush=false):
_base_filename(base_filename), _base_filename(base_filename),
_extension(extension), _extension(extension),
_max_size(max_size), _max_size(max_size),
_max_files(max_files), _max_files(max_files),
_current_size(0), _current_size(0),
_file_helper(auto_flush) _file_helper(auto_flush)
{ {
_file_helper.open(calc_filename(_base_filename, 0, _extension)); _file_helper.open(calc_filename(_base_filename, 0, _extension));
} }
protected: protected:
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
_current_size += msg.formatted.size(); _current_size += msg.formatted.size();
if (_current_size > _max_size) if (_current_size > _max_size)
{ {
_rotate(); _rotate();
_current_size = msg.formatted.size(); _current_size = msg.formatted.size();
} }
_file_helper.write(msg); _file_helper.write(msg);
} }
private: private:
static std::string calc_filename(const std::string& filename, std::size_t index, const std::string& extension) static std::string calc_filename(const std::string& filename, std::size_t index, const std::string& extension)
{ {
details::fmt::MemoryWriter w; details::fmt::MemoryWriter w;
if (index) if (index)
w.write("{}.{}.{}", filename, index, extension); w.write("{}.{}.{}", filename, index, extension);
else else
w.write("{}.{}", filename, extension); w.write("{}.{}", filename, extension);
return w.str(); return w.str();
} }
// Rotate files: // Rotate files:
// log.txt -> log.1.txt // log.txt -> log.1.txt
// log.1.txt -> log2.txt // log.1.txt -> log2.txt
// log.2.txt -> log3.txt // log.2.txt -> log3.txt
// log.3.txt -> delete // log.3.txt -> delete
void _rotate() void _rotate()
{ {
_file_helper.close(); _file_helper.close();
for (auto i = _max_files; i > 0; --i) for (auto i = _max_files; i > 0; --i)
{ {
std::string src = calc_filename(_base_filename, i - 1, _extension); std::string src = calc_filename(_base_filename, i - 1, _extension);
std::string target = calc_filename(_base_filename, i, _extension); std::string target = calc_filename(_base_filename, i, _extension);
if (details::file_helper::file_exists(target)) if (details::file_helper::file_exists(target))
{ {
if (std::remove(target.c_str()) != 0) if (std::remove(target.c_str()) != 0)
{ {
throw spdlog_ex("rotating_file_sink: failed removing " + target); throw spdlog_ex("rotating_file_sink: failed removing " + target);
} }
} }
if (details::file_helper::file_exists(src) && std::rename(src.c_str(), target.c_str())) if (details::file_helper::file_exists(src) && std::rename(src.c_str(), target.c_str()))
{ {
throw spdlog_ex("rotating_file_sink: failed renaming " + src + " to " + target); throw spdlog_ex("rotating_file_sink: failed renaming " + src + " to " + target);
} }
} }
_file_helper.reopen(true); _file_helper.reopen(true);
} }
std::string _base_filename; std::string _base_filename;
std::string _extension; std::string _extension;
std::size_t _max_size; std::size_t _max_size;
std::size_t _max_files; std::size_t _max_files;
std::size_t _current_size; std::size_t _current_size;
details::file_helper _file_helper; details::file_helper _file_helper;
}; };
typedef rotating_file_sink<std::mutex> rotating_file_sink_mt; typedef rotating_file_sink<std::mutex> rotating_file_sink_mt;
...@@ -155,56 +155,56 @@ template<class Mutex> ...@@ -155,56 +155,56 @@ template<class Mutex>
class daily_file_sink:public base_sink<Mutex> class daily_file_sink:public base_sink<Mutex>
{ {
public: public:
explicit daily_file_sink(const std::string& base_filename, explicit daily_file_sink(const std::string& base_filename,
const std::string& extension, const std::string& extension,
bool auto_flush=false): bool auto_flush=false):
_base_filename(base_filename), _base_filename(base_filename),
_extension(extension), _extension(extension),
_midnight_tp (_calc_midnight_tp() ), _midnight_tp (_calc_midnight_tp() ),
_file_helper(auto_flush) _file_helper(auto_flush)
{ {
_file_helper.open(calc_filename(_base_filename, _extension)); _file_helper.open(calc_filename(_base_filename, _extension));
} }
protected: protected:
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
if (std::chrono::system_clock::now() >= _midnight_tp) if (std::chrono::system_clock::now() >= _midnight_tp)
{ {
_file_helper.close(); _file_helper.close();
_file_helper.open(calc_filename(_base_filename, _extension)); _file_helper.open(calc_filename(_base_filename, _extension));
_midnight_tp = _calc_midnight_tp(); _midnight_tp = _calc_midnight_tp();
} }
_file_helper.write(msg); _file_helper.write(msg);
} }
private: private:
// Return next midnight's time_point // Return next midnight's time_point
static std::chrono::system_clock::time_point _calc_midnight_tp() static std::chrono::system_clock::time_point _calc_midnight_tp()
{ {
using namespace std::chrono; using namespace std::chrono;
auto now = system_clock::now(); auto now = system_clock::now();
time_t tnow = std::chrono::system_clock::to_time_t(now); time_t tnow = std::chrono::system_clock::to_time_t(now);
tm date = spdlog::details::os::localtime(tnow); tm date = spdlog::details::os::localtime(tnow);
date.tm_hour = date.tm_min = date.tm_sec = 0; date.tm_hour = date.tm_min = date.tm_sec = 0;
auto midnight = std::chrono::system_clock::from_time_t(std::mktime(&date)); auto midnight = std::chrono::system_clock::from_time_t(std::mktime(&date));
return system_clock::time_point(midnight + hours(24)); return system_clock::time_point(midnight + hours(24));
} }
//Create filename for the form basename.YYYY-MM-DD.extension //Create filename for the form basename.YYYY-MM-DD.extension
static std::string calc_filename(const std::string& basename, const std::string& extension) static std::string calc_filename(const std::string& basename, const std::string& extension)
{ {
std::tm tm = spdlog::details::os::localtime(); std::tm tm = spdlog::details::os::localtime();
details::fmt::MemoryWriter w; details::fmt::MemoryWriter w;
w.write("{}.{:04d}-{:02d}-{:02d}.{}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, extension); w.write("{}.{:04d}-{:02d}-{:02d}.{}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, extension);
return w.str(); return w.str();
} }
std::string _base_filename; std::string _base_filename;
std::string _extension; std::string _extension;
std::chrono::system_clock::time_point _midnight_tp; std::chrono::system_clock::time_point _midnight_tp;
details::file_helper _file_helper; details::file_helper _file_helper;
}; };
......
...@@ -37,8 +37,8 @@ template <class Mutex> ...@@ -37,8 +37,8 @@ template <class Mutex>
class null_sink : public base_sink < Mutex > class null_sink : public base_sink < Mutex >
{ {
protected: protected:
void _sink_it(const details::log_msg&) override void _sink_it(const details::log_msg&) override
{} {}
}; };
typedef null_sink<details::null_mutex> null_sink_st; typedef null_sink<details::null_mutex> null_sink_st;
......
...@@ -39,17 +39,17 @@ template<class Mutex> ...@@ -39,17 +39,17 @@ template<class Mutex>
class ostream_sink: public base_sink<Mutex> class ostream_sink: public base_sink<Mutex>
{ {
public: public:
explicit ostream_sink(std::ostream& os) :_ostream(os) {} explicit ostream_sink(std::ostream& os) :_ostream(os) {}
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;
virtual ~ostream_sink() = default; virtual ~ostream_sink() = default;
protected: protected:
virtual void _sink_it(const details::log_msg& msg) override virtual void _sink_it(const details::log_msg& msg) override
{ {
_ostream.write(msg.formatted.data(), msg.formatted.size()); _ostream.write(msg.formatted.data(), msg.formatted.size());
} }
std::ostream& _ostream; std::ostream& _ostream;
}; };
typedef ostream_sink<std::mutex> ostream_sink_mt; typedef ostream_sink<std::mutex> ostream_sink_mt;
......
...@@ -33,8 +33,8 @@ namespace sinks ...@@ -33,8 +33,8 @@ namespace sinks
class sink class sink
{ {
public: public:
virtual ~sink() {} virtual ~sink() {}
virtual void log(const details::log_msg& msg) = 0; virtual void log(const details::log_msg& msg) = 0;
}; };
} }
} }
......
...@@ -38,7 +38,7 @@ template <class Mutex> ...@@ -38,7 +38,7 @@ template <class Mutex>
class stdout_sink : public ostream_sink<Mutex> class stdout_sink : public ostream_sink<Mutex>
{ {
public: public:
stdout_sink() : ostream_sink<Mutex>(std::cout) {} stdout_sink() : ostream_sink<Mutex>(std::cout) {}
}; };
...@@ -50,7 +50,7 @@ template <class Mutex> ...@@ -50,7 +50,7 @@ template <class Mutex>
class stderr_sink : public ostream_sink<Mutex> class stderr_sink : public ostream_sink<Mutex>
{ {
public: public:
stderr_sink() : ostream_sink<Mutex>(std::cerr) {} stderr_sink() : ostream_sink<Mutex>(std::cerr) {}
}; };
typedef stderr_sink<std::mutex> stderr_sink_mt; typedef stderr_sink<std::mutex> stderr_sink_mt;
......
...@@ -47,50 +47,50 @@ class syslog_sink : public sink ...@@ -47,50 +47,50 @@ class syslog_sink : public sink
{ {
public: public:
// //
syslog_sink(const std::string& ident = "", int syslog_option=0, int syslog_facility=LOG_USER): syslog_sink(const std::string& ident = "", int syslog_option=0, int syslog_facility=LOG_USER):
_ident(ident) _ident(ident)
{ {
_priorities[static_cast<int>(level::trace)] = LOG_DEBUG; _priorities[static_cast<int>(level::trace)] = LOG_DEBUG;
_priorities[static_cast<int>(level::debug)] = LOG_DEBUG; _priorities[static_cast<int>(level::debug)] = LOG_DEBUG;
_priorities[static_cast<int>(level::info)] = LOG_INFO; _priorities[static_cast<int>(level::info)] = LOG_INFO;
_priorities[static_cast<int>(level::notice)] = LOG_NOTICE; _priorities[static_cast<int>(level::notice)] = LOG_NOTICE;
_priorities[static_cast<int>(level::warn)] = LOG_WARNING; _priorities[static_cast<int>(level::warn)] = LOG_WARNING;
_priorities[static_cast<int>(level::err)] = LOG_ERR; _priorities[static_cast<int>(level::err)] = LOG_ERR;
_priorities[static_cast<int>(level::critical)] = LOG_CRIT; _priorities[static_cast<int>(level::critical)] = LOG_CRIT;
_priorities[static_cast<int>(level::alert)] = LOG_ALERT; _priorities[static_cast<int>(level::alert)] = LOG_ALERT;
_priorities[static_cast<int>(level::emerg)] = LOG_EMERG; _priorities[static_cast<int>(level::emerg)] = LOG_EMERG;
_priorities[static_cast<int>(level::off)] = LOG_INFO; _priorities[static_cast<int>(level::off)] = LOG_INFO;
//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);
} }
~syslog_sink() ~syslog_sink()
{ {
::closelog(); ::closelog();
} }
syslog_sink(const syslog_sink&) = delete; syslog_sink(const syslog_sink&) = delete;
syslog_sink& operator=(const syslog_sink&) = delete; syslog_sink& operator=(const syslog_sink&) = delete;
void log(const details::log_msg &msg) override void log(const details::log_msg &msg) override
{ {
::syslog(syslog_prio_from_level(msg), "%s", msg.formatted.str().c_str()); ::syslog(syslog_prio_from_level(msg), "%s", msg.formatted.str().c_str());
} }
private: private:
std::array<int, 10> _priorities; std::array<int, 10> _priorities;
//must store the ident because the man says openlog might use the pointer as is and not a string copy //must store the ident because the man says openlog might use the pointer as is and not a string copy
const std::string _ident; const std::string _ident;
// //
// Simply maps spdlog's log level to syslog priority level. // Simply maps spdlog's log level to syslog priority level.
// //
int syslog_prio_from_level(const details::log_msg &msg) const int syslog_prio_from_level(const details::log_msg &msg) const
{ {
return _priorities[static_cast<int>(msg.level)]; return _priorities[static_cast<int>(msg.level)];
} }
}; };
} }
} }
......
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