mirror of
https://github.com/gabime/spdlog.git
synced 2025-04-01 02:42:41 +08:00
clang-format
This commit is contained in:
parent
461b5ef28a
commit
a2653d409f
@ -3,18 +3,18 @@
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
//
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
|
||||
#include <boost/log/core.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/sinks/text_file_backend.hpp>
|
||||
#include <boost/log/utility/setup/file.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <boost/log/sources/record_ostream.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
#include <boost/log/utility/setup/file.hpp>
|
||||
|
||||
namespace logging = boost::log;
|
||||
namespace src = boost::log::sources;
|
||||
@ -23,21 +23,12 @@ namespace keywords = boost::log::keywords;
|
||||
|
||||
void init()
|
||||
{
|
||||
logging::add_file_log
|
||||
(
|
||||
keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/
|
||||
keywords::auto_flush = false,
|
||||
keywords::format = "[%TimeStamp%]: %Message%"
|
||||
);
|
||||
logging::add_file_log(keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/
|
||||
keywords::auto_flush = false, keywords::format = "[%TimeStamp%]: %Message%");
|
||||
|
||||
logging::core::get()->set_filter
|
||||
(
|
||||
logging::trivial::severity >= logging::trivial::info
|
||||
);
|
||||
logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -48,11 +39,9 @@ int main(int argc, char* argv[])
|
||||
|
||||
int howmany = 1000000;
|
||||
|
||||
|
||||
init();
|
||||
logging::add_common_attributes();
|
||||
|
||||
|
||||
using namespace logging::trivial;
|
||||
|
||||
src::severity_logger_mt<severity_level> lg;
|
||||
@ -62,23 +51,21 @@ int main(int argc, char* argv[])
|
||||
|
||||
for (int t = 0; t < thread_count; ++t)
|
||||
{
|
||||
threads.push_back(std::thread([&]()
|
||||
{
|
||||
threads.push_back(std::thread([&]() {
|
||||
while (true)
|
||||
{
|
||||
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";
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
for (auto &t : threads)
|
||||
{
|
||||
t.join();
|
||||
};
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3,13 +3,13 @@
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
//
|
||||
#include <boost/log/core.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/sinks/text_file_backend.hpp>
|
||||
#include <boost/log/utility/setup/file.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <boost/log/sources/record_ostream.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
#include <boost/log/utility/setup/file.hpp>
|
||||
|
||||
namespace logging = boost::log;
|
||||
namespace src = boost::log::sources;
|
||||
@ -18,20 +18,12 @@ namespace keywords = boost::log::keywords;
|
||||
|
||||
void init()
|
||||
{
|
||||
logging::add_file_log
|
||||
(
|
||||
keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/
|
||||
keywords::auto_flush = false,
|
||||
keywords::format = "[%TimeStamp%]: %Message%"
|
||||
);
|
||||
logging::add_file_log(keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/
|
||||
keywords::auto_flush = false, keywords::format = "[%TimeStamp%]: %Message%");
|
||||
|
||||
logging::core::get()->set_filter
|
||||
(
|
||||
logging::trivial::severity >= logging::trivial::info
|
||||
);
|
||||
logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *[])
|
||||
{
|
||||
int howmany = 1000000;
|
||||
|
@ -3,9 +3,9 @@
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
//
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
|
||||
#define _ELPP_THREAD_SAFE
|
||||
#include "easylogging++.h"
|
||||
@ -31,18 +31,17 @@ int main(int argc, char* argv[])
|
||||
|
||||
for (int t = 0; t < thread_count; ++t)
|
||||
{
|
||||
threads.push_back(std::thread([&]()
|
||||
{
|
||||
threads.push_back(std::thread([&]() {
|
||||
while (true)
|
||||
{
|
||||
int counter = ++msg_counter;
|
||||
if (counter > howmany) break;
|
||||
if (counter > howmany)
|
||||
break;
|
||||
LOG(INFO) << "easylog message #" << counter << ": This is some text for your pleasure";
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
for (auto &t : threads)
|
||||
{
|
||||
t.join();
|
||||
|
@ -3,7 +3,6 @@
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
//
|
||||
|
||||
|
||||
#include "easylogging++.h"
|
||||
|
||||
_INITIALIZE_EASYLOGGINGPP
|
||||
|
@ -3,14 +3,14 @@
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
//
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
||||
#include "g2logworker.h"
|
||||
#include "g2log.h"
|
||||
#include "g2logworker.h"
|
||||
|
||||
using namespace std;
|
||||
template <typename T> std::string format(const T &value);
|
||||
@ -28,24 +28,22 @@ int main(int argc, char* argv[])
|
||||
g2LogWorker g2log(argv[0], "logs");
|
||||
g2::initializeLogging(&g2log);
|
||||
|
||||
|
||||
std::atomic<int> msg_counter{0};
|
||||
vector<thread> threads;
|
||||
auto start = clock::now();
|
||||
for (int t = 0; t < thread_count; ++t)
|
||||
{
|
||||
threads.push_back(std::thread([&]()
|
||||
{
|
||||
threads.push_back(std::thread([&]() {
|
||||
while (true)
|
||||
{
|
||||
int counter = ++msg_counter;
|
||||
if (counter > howmany) break;
|
||||
if (counter > howmany)
|
||||
break;
|
||||
LOG(INFO) << "g2log message #" << counter << ": This is some text for your pleasure";
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
for (auto &t : threads)
|
||||
{
|
||||
t.join();
|
||||
|
@ -3,9 +3,9 @@
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
//
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
|
||||
#include "glog/logging.h"
|
||||
|
||||
@ -29,18 +29,17 @@ int main(int argc, char* argv[])
|
||||
|
||||
for (int t = 0; t < thread_count; ++t)
|
||||
{
|
||||
threads.push_back(std::thread([&]()
|
||||
{
|
||||
threads.push_back(std::thread([&]() {
|
||||
while (true)
|
||||
{
|
||||
int counter = ++msg_counter;
|
||||
if (counter > howmany) break;
|
||||
if (counter > howmany)
|
||||
break;
|
||||
LOG(INFO) << "glog message #" << counter << ": This is some text for your pleasure";
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
for (auto &t : threads)
|
||||
{
|
||||
t.join();
|
||||
|
@ -5,12 +5,10 @@
|
||||
|
||||
#include "glog/logging.h"
|
||||
|
||||
|
||||
int main(int, char *argv[])
|
||||
{
|
||||
int howmany = 1000000;
|
||||
|
||||
|
||||
FLAGS_logtostderr = 0;
|
||||
FLAGS_log_dir = "logs";
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
@ -16,7 +16,6 @@ void CrusherLoop()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
std::cout << "WARNING: This test will exaust all your machine memory and will crush it!" << std::endl;
|
||||
@ -33,5 +32,3 @@ int main(int argc, char** argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,31 +1,25 @@
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <numeric>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include "utils.h"
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/logworker.hpp>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace {
|
||||
const uint64_t g_iterations = 1000000;
|
||||
|
||||
|
||||
std::atomic<size_t> g_counter = {0};
|
||||
|
||||
|
||||
void MeasurePeakDuringLogWrites(const size_t id, std::vector<uint64_t> &result)
|
||||
{
|
||||
|
||||
@ -45,8 +39,6 @@ void MeasurePeakDuringLogWrites(const size_t id, std::vector<uint64_t>& result)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PrintResults(const std::map<size_t, std::vector<uint64_t>> &threads_result, size_t total_us)
|
||||
{
|
||||
|
||||
@ -64,11 +56,10 @@ void PrintResults(const std::map<size_t, std::vector<uint64_t>>& threads_result,
|
||||
auto total = accumulate(begin(all_measurements), end(all_measurements), 0, std::plus<uint64_t>());
|
||||
auto avg = double(total) / all_measurements.size();
|
||||
|
||||
std::cout << "[g3log] worst: " << std::setw(10) << std::right << worst << "\tAvg: " << avg << "\tTotal: " << utils::format(total_us) << " us" << std::endl;
|
||||
|
||||
std::cout << "[g3log] worst: " << std::setw(10) << std::right << worst << "\tAvg: " << avg << "\tTotal: " << utils::format(total_us)
|
||||
<< " us" << std::endl;
|
||||
}
|
||||
}// anonymous
|
||||
|
||||
} // namespace
|
||||
|
||||
// The purpose of this test is NOT to see how fast
|
||||
// each thread can possibly write. It is to see what
|
||||
@ -91,7 +82,6 @@ int main(int argc, char** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::thread> threads(number_of_threads);
|
||||
std::map<size_t, std::vector<uint64_t>> threads_result;
|
||||
|
||||
@ -121,9 +111,8 @@ int main(int argc, char** argv)
|
||||
}
|
||||
auto stop_time_application_total = std::chrono::high_resolution_clock::now();
|
||||
|
||||
uint64_t total_time_in_us = std::chrono::duration_cast<std::chrono::microseconds>(stop_time_application_total - start_time_application_total).count();
|
||||
uint64_t total_time_in_us =
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(stop_time_application_total - start_time_application_total).count();
|
||||
PrintResults(threads_result, total_time_in_us);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,30 +1,25 @@
|
||||
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include "utils.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <numeric>
|
||||
#include <functional>
|
||||
#include "utils.h"
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace spd = spdlog;
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace {
|
||||
const uint64_t g_iterations = 1000000;
|
||||
|
||||
|
||||
std::atomic<size_t> g_counter = {0};
|
||||
|
||||
|
||||
void MeasurePeakDuringLogWrites(const size_t id, std::vector<uint64_t> &result)
|
||||
{
|
||||
auto logger = spd::get("file_logger");
|
||||
@ -44,7 +39,6 @@ void MeasurePeakDuringLogWrites(const size_t id, std::vector<uint64_t>& result)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PrintResults(const std::map<size_t, std::vector<uint64_t>> &threads_result, size_t total_us)
|
||||
{
|
||||
|
||||
@ -62,11 +56,10 @@ void PrintResults(const std::map<size_t, std::vector<uint64_t>>& threads_result,
|
||||
auto total = accumulate(begin(all_measurements), end(all_measurements), 0, std::plus<uint64_t>());
|
||||
auto avg = double(total) / all_measurements.size();
|
||||
|
||||
std::cout << "[spdlog] worst: " << std::setw(10) << std::right << worst << "\tAvg: " << avg << "\tTotal: " << utils::format(total_us) << " us" << std::endl;
|
||||
|
||||
std::cout << "[spdlog] worst: " << std::setw(10) << std::right << worst << "\tAvg: " << avg << "\tTotal: " << utils::format(total_us)
|
||||
<< " us" << std::endl;
|
||||
}
|
||||
}// anonymous
|
||||
|
||||
} // namespace
|
||||
|
||||
// The purpose of this test is NOT to see how fast
|
||||
// each thread can possibly write. It is to see what
|
||||
@ -89,7 +82,6 @@ int main(int argc, char** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::thread> threads(number_of_threads);
|
||||
std::map<size_t, std::vector<uint64_t>> threads_result;
|
||||
|
||||
@ -119,10 +111,9 @@ int main(int argc, char** argv)
|
||||
}
|
||||
auto stop_time_application_total = std::chrono::high_resolution_clock::now();
|
||||
|
||||
uint64_t total_time_in_us = std::chrono::duration_cast<std::chrono::microseconds>(stop_time_application_total - start_time_application_total).count();
|
||||
uint64_t total_time_in_us =
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(stop_time_application_total - start_time_application_total).count();
|
||||
|
||||
PrintResults(threads_result, total_time_in_us);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,15 +5,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
namespace utils {
|
||||
|
||||
template<typename T>
|
||||
inline std::string format(const T& value)
|
||||
template <typename T> inline std::string format(const T &value)
|
||||
{
|
||||
static std::locale loc("");
|
||||
std::stringstream ss;
|
||||
@ -22,8 +20,7 @@ inline std::string format(const T& value)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string format(const double & value)
|
||||
template <> inline std::string format(const double &value)
|
||||
{
|
||||
static std::locale loc("");
|
||||
std::stringstream ss;
|
||||
@ -32,4 +29,4 @@ inline std::string format(const double & value)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace utils
|
||||
|
@ -3,13 +3,13 @@
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
//
|
||||
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -29,18 +29,17 @@ int main(int argc, char* argv[])
|
||||
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");
|
||||
|
||||
|
||||
std::atomic<int> msg_counter{0};
|
||||
vector<thread> threads;
|
||||
auto start = clock::now();
|
||||
for (int t = 0; t < thread_count; ++t)
|
||||
{
|
||||
threads.push_back(std::thread([&]()
|
||||
{
|
||||
threads.push_back(std::thread([&]() {
|
||||
while (true)
|
||||
{
|
||||
int counter = ++msg_counter;
|
||||
if (counter > howmany) break;
|
||||
if (counter > howmany)
|
||||
break;
|
||||
logger->info("spdlog message #{}: This is some text for your pleasure", counter);
|
||||
}
|
||||
}));
|
||||
|
@ -3,12 +3,11 @@
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
//
|
||||
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <atomic>
|
||||
#include <cstdlib>
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -32,24 +31,21 @@ int main(int argc, char* argv[])
|
||||
|
||||
for (int t = 0; t < thread_count; ++t)
|
||||
{
|
||||
threads.push_back(std::thread([&]()
|
||||
{
|
||||
threads.push_back(std::thread([&]() {
|
||||
while (true)
|
||||
{
|
||||
int counter = ++msg_counter;
|
||||
if (counter > howmany) break;
|
||||
if (counter > howmany)
|
||||
break;
|
||||
logger->info("spdlog message #{}: This is some text for your pleasure", counter);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
for (auto &t : threads)
|
||||
{
|
||||
t.join();
|
||||
};
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
|
||||
int main(int, char *[])
|
||||
{
|
||||
int howmany = 1000000;
|
||||
|
@ -6,17 +6,16 @@
|
||||
//
|
||||
// bench.cpp : spdlog benchmarks
|
||||
//
|
||||
#include "spdlog/async_logger.h"
|
||||
#include "spdlog/sinks/null_sink.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "utils.h"
|
||||
#include <atomic>
|
||||
#include <cstdlib> // EXIT_FAILURE
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/async_logger.h"
|
||||
#include "spdlog/sinks/null_sink.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
@ -24,8 +23,6 @@ using namespace spdlog;
|
||||
using namespace spdlog::sinks;
|
||||
using namespace utils;
|
||||
|
||||
|
||||
|
||||
size_t bench_as(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -46,7 +43,6 @@ int main(int argc, char* argv[])
|
||||
if (argc > 3)
|
||||
queue_size = atoi(argv[3]);
|
||||
|
||||
|
||||
cout << "\n*******************************************************************************\n";
|
||||
cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " messages " << endl;
|
||||
cout << "*******************************************************************************\n";
|
||||
@ -64,7 +60,6 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
std::cout << endl;
|
||||
std::cout << "Avg rate: " << format(total_rate / iters) << "/sec" << std::endl;
|
||||
|
||||
}
|
||||
catch (std::exception &ex)
|
||||
{
|
||||
@ -75,8 +70,6 @@ int main(int argc, char* argv[])
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// return rate/sec
|
||||
size_t bench_as(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
|
||||
{
|
||||
@ -86,24 +79,22 @@ size_t bench_as(int howmany, std::shared_ptr<spdlog::logger> log, int thread_cou
|
||||
auto start = system_clock::now();
|
||||
for (int t = 0; t < thread_count; ++t)
|
||||
{
|
||||
threads.push_back(std::thread([&]()
|
||||
{
|
||||
threads.push_back(std::thread([&]() {
|
||||
for (;;)
|
||||
{
|
||||
int counter = ++msg_counter;
|
||||
if (counter > howmany) break;
|
||||
if (counter > howmany)
|
||||
break;
|
||||
log->info("Hello logger: msg number {}", counter);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
for (auto &t : threads)
|
||||
{
|
||||
t.join();
|
||||
};
|
||||
|
||||
|
||||
auto delta = system_clock::now() - start;
|
||||
auto delta_d = duration_cast<duration<double>>(delta).count();
|
||||
auto per_sec = size_t(howmany / delta_d);
|
||||
|
@ -5,15 +5,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
namespace utils {
|
||||
|
||||
template<typename T>
|
||||
inline std::string format(const T& value)
|
||||
template <typename T> inline std::string format(const T &value)
|
||||
{
|
||||
static std::locale loc("");
|
||||
std::stringstream ss;
|
||||
@ -22,8 +20,7 @@ inline std::string format(const T& value)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string format(const double & value)
|
||||
template <> inline std::string format(const double &value)
|
||||
{
|
||||
static std::locale loc("");
|
||||
std::stringstream ss;
|
||||
@ -32,4 +29,4 @@ inline std::string format(const double & value)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace utils
|
||||
|
@ -6,18 +6,17 @@
|
||||
//
|
||||
// bench.cpp : spdlog benchmarks
|
||||
//
|
||||
#include "spdlog/async_logger.h"
|
||||
#include "spdlog/sinks/file_sinks.h"
|
||||
#include "spdlog/sinks/null_sink.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "utils.h"
|
||||
#include <atomic>
|
||||
#include <cstdlib> // EXIT_FAILURE
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/async_logger.h"
|
||||
#include "spdlog/sinks/file_sinks.h"
|
||||
#include "spdlog/sinks/null_sink.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
@ -25,7 +24,6 @@ using namespace spdlog;
|
||||
using namespace spdlog::sinks;
|
||||
using namespace utils;
|
||||
|
||||
|
||||
void bench(int howmany, std::shared_ptr<spdlog::logger> log);
|
||||
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);
|
||||
|
||||
@ -48,7 +46,6 @@ int main(int argc, char* argv[])
|
||||
if (argc > 3)
|
||||
queue_size = atoi(argv[3]);
|
||||
|
||||
|
||||
cout << "*******************************************************************************\n";
|
||||
cout << "Single thread, " << format(howmany) << " iterations" << endl;
|
||||
cout << "*******************************************************************************\n";
|
||||
@ -66,7 +63,6 @@ int main(int argc, char* argv[])
|
||||
auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files);
|
||||
bench_mt(howmany, rotating_mt, threads);
|
||||
|
||||
|
||||
auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt.log");
|
||||
bench_mt(howmany, daily_mt, threads);
|
||||
bench(howmany, spdlog::create<null_sink_st>("null_mt"));
|
||||
@ -75,7 +71,6 @@ int main(int argc, char* argv[])
|
||||
cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " iterations " << endl;
|
||||
cout << "*******************************************************************************\n";
|
||||
|
||||
|
||||
spdlog::set_async_mode(queue_size);
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
@ -94,7 +89,6 @@ int main(int argc, char* argv[])
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void bench(int howmany, std::shared_ptr<spdlog::logger> log)
|
||||
{
|
||||
cout << log->name() << "...\t\t" << flush;
|
||||
@ -104,13 +98,11 @@ void bench(int howmany, std::shared_ptr<spdlog::logger> log)
|
||||
log->info("Hello logger: msg number {}", i);
|
||||
}
|
||||
|
||||
|
||||
auto delta = system_clock::now() - start;
|
||||
auto delta_d = duration_cast<duration<double>>(delta).count();
|
||||
cout << format(int(howmany / delta_d)) << "/sec" << endl;
|
||||
}
|
||||
|
||||
|
||||
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
|
||||
{
|
||||
|
||||
@ -120,24 +112,22 @@ void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count
|
||||
auto start = system_clock::now();
|
||||
for (int t = 0; t < thread_count; ++t)
|
||||
{
|
||||
threads.push_back(std::thread([&]()
|
||||
{
|
||||
threads.push_back(std::thread([&]() {
|
||||
for (;;)
|
||||
{
|
||||
int counter = ++msg_counter;
|
||||
if (counter > howmany) break;
|
||||
if (counter > howmany)
|
||||
break;
|
||||
log->info("Hello logger: msg number {}", counter);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
for (auto &t : threads)
|
||||
{
|
||||
t.join();
|
||||
};
|
||||
|
||||
|
||||
auto delta = system_clock::now() - start;
|
||||
auto delta_d = duration_cast<duration<double>>(delta).count();
|
||||
cout << format(int(howmany / delta_d)) << "/sec" << endl;
|
||||
|
@ -31,7 +31,6 @@ int main(int, char*[])
|
||||
console->info("Welcome to spdlog!");
|
||||
console->error("Some error message with arg{}..", 1);
|
||||
|
||||
|
||||
// Formatting examples
|
||||
console->warn("Easy padding in numbers like {:08d}", 12);
|
||||
console->critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
|
||||
@ -41,7 +40,6 @@ int main(int, char*[])
|
||||
|
||||
spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");
|
||||
|
||||
|
||||
// Create basic file logger (not rotated)
|
||||
auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic-log.txt");
|
||||
my_logger->info("Some log message");
|
||||
@ -61,7 +59,6 @@ int main(int, char*[])
|
||||
spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
|
||||
rotating_logger->info("This is another message with custom format");
|
||||
|
||||
|
||||
// Runtime log levels
|
||||
spd::set_level(spd::level::info); // Set global log level to info
|
||||
console->debug("This message should not be displayed!");
|
||||
@ -73,7 +70,6 @@ int main(int, char*[])
|
||||
SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23);
|
||||
SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);
|
||||
|
||||
|
||||
// Asynchronous logging is very fast..
|
||||
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
|
||||
async_example();
|
||||
@ -91,10 +87,7 @@ int main(int, char*[])
|
||||
err_handler_example();
|
||||
|
||||
// Apply a function on all registered loggers
|
||||
spd::apply_all([&](std::shared_ptr<spdlog::logger> l)
|
||||
{
|
||||
l->info("End of example.");
|
||||
});
|
||||
spd::apply_all([&](std::shared_ptr<spdlog::logger> l) { l->info("End of example."); });
|
||||
|
||||
// Release and close all loggers
|
||||
spdlog::drop_all();
|
||||
@ -140,8 +133,7 @@ void android_example()
|
||||
struct my_type
|
||||
{
|
||||
int i;
|
||||
template<typename OStream>
|
||||
friend OStream& operator<<(OStream& os, const my_type &c)
|
||||
template <typename OStream> friend OStream &operator<<(OStream &os, const my_type &c)
|
||||
{
|
||||
return os << "[my_type i=" << c.i << "]";
|
||||
}
|
||||
@ -159,9 +151,6 @@ void user_defined_example()
|
||||
void err_handler_example()
|
||||
{
|
||||
// can be set globaly or per logger(logger->set_error_handler(..))
|
||||
spdlog::set_error_handler([](const std::string& msg)
|
||||
{
|
||||
std::cerr << "my err handler: " << msg << std::endl;
|
||||
});
|
||||
spdlog::set_error_handler([](const std::string &msg) { std::cerr << "my err handler: " << msg << std::endl; });
|
||||
spd::get("console")->info("some invalid message to trigger an error {}{}{}{}", 3);
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
../example.cpp
|
156
example/jni/example.cpp
Normal file
156
example/jni/example.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
//
|
||||
// Copyright(c) 2015 Gabi Melman.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
//
|
||||
//
|
||||
// spdlog usage example
|
||||
//
|
||||
//
|
||||
|
||||
#define SPDLOG_TRACE_ON
|
||||
#define SPDLOG_DEBUG_ON
|
||||
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
void async_example();
|
||||
void syslog_example();
|
||||
void android_example();
|
||||
void user_defined_example();
|
||||
void err_handler_example();
|
||||
|
||||
namespace spd = spdlog;
|
||||
int main(int, char *[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// Console logger with color
|
||||
auto console = spd::stdout_color_mt("console");
|
||||
console->info("Welcome to spdlog!");
|
||||
console->error("Some error message with arg{}..", 1);
|
||||
|
||||
// Formatting examples
|
||||
console->warn("Easy padding in numbers like {:08d}", 12);
|
||||
console->critical("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("Positional args are {1} {0}..", "too", "supported");
|
||||
console->info("{:<30}", "left aligned");
|
||||
|
||||
spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");
|
||||
|
||||
// Create basic file logger (not rotated)
|
||||
auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic-log.txt");
|
||||
my_logger->info("Some log message");
|
||||
|
||||
// Create a file rotating logger with 5mb size max and 3 rotated files
|
||||
auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3);
|
||||
for (int i = 0; i < 10; ++i)
|
||||
rotating_logger->info("{} * {} equals {:>10}", i, i, i * i);
|
||||
|
||||
// Create a daily logger - a new file is created every day on 2:30am
|
||||
auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
|
||||
// trigger flush if the log severity is error or higher
|
||||
daily_logger->flush_on(spd::level::err);
|
||||
daily_logger->info(123.44);
|
||||
|
||||
// Customize msg format for all messages
|
||||
spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
|
||||
rotating_logger->info("This is another message with custom format");
|
||||
|
||||
// Runtime log levels
|
||||
spd::set_level(spd::level::info); // Set global log level to info
|
||||
console->debug("This message should not be displayed!");
|
||||
console->set_level(spd::level::debug); // Set specific logger's log level
|
||||
console->debug("This message should be displayed..");
|
||||
|
||||
// Compile time log levels
|
||||
// define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON
|
||||
SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23);
|
||||
SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);
|
||||
|
||||
// Asynchronous logging is very fast..
|
||||
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
|
||||
async_example();
|
||||
|
||||
// syslog example. linux/osx only
|
||||
syslog_example();
|
||||
|
||||
// android example. compile with NDK
|
||||
android_example();
|
||||
|
||||
// Log user-defined types example
|
||||
user_defined_example();
|
||||
|
||||
// Change default log error handler
|
||||
err_handler_example();
|
||||
|
||||
// Apply a function on all registered loggers
|
||||
spd::apply_all([&](std::shared_ptr<spdlog::logger> l) { l->info("End of example."); });
|
||||
|
||||
// Release and close all loggers
|
||||
spdlog::drop_all();
|
||||
}
|
||||
// Exceptions will only be thrown upon failed logger or sink construction (not during logging)
|
||||
catch (const spd::spdlog_ex &ex)
|
||||
{
|
||||
std::cout << "Log init failed: " << ex.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void async_example()
|
||||
{
|
||||
size_t q_size = 4096; // 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");
|
||||
for (int i = 0; i < 100; ++i)
|
||||
async_file->info("Async message #{}", i);
|
||||
}
|
||||
|
||||
// syslog example (linux/osx/freebsd)
|
||||
void syslog_example()
|
||||
{
|
||||
#ifdef SPDLOG_ENABLE_SYSLOG
|
||||
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.");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Android example
|
||||
void android_example()
|
||||
{
|
||||
#if defined(__ANDROID__)
|
||||
std::string tag = "spdlog-android";
|
||||
auto android_logger = spd::android_logger("android", tag);
|
||||
android_logger->critical("Use \"adb shell logcat\" to view this message.");
|
||||
#endif
|
||||
}
|
||||
|
||||
// user defined types logging by implementing operator<<
|
||||
struct my_type
|
||||
{
|
||||
int i;
|
||||
template <typename OStream> friend OStream &operator<<(OStream &os, const my_type &c)
|
||||
{
|
||||
return os << "[my_type i=" << c.i << "]";
|
||||
}
|
||||
};
|
||||
|
||||
#include "spdlog/fmt/ostr.h" // must be included
|
||||
void user_defined_example()
|
||||
{
|
||||
spd::get("console")->info("user defined type: {}", my_type{14});
|
||||
}
|
||||
|
||||
//
|
||||
// custom error handler
|
||||
//
|
||||
void err_handler_example()
|
||||
{
|
||||
// can be set globaly or per logger(logger->set_error_handler(..))
|
||||
spdlog::set_error_handler([](const std::string &msg) { std::cerr << "my err handler: " << msg << std::endl; });
|
||||
spd::get("console")->info("some invalid message to trigger an error {}{}{}{}", 3);
|
||||
}
|
@ -44,4 +44,3 @@ int main(int, char*[])
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,15 +5,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
namespace utils {
|
||||
|
||||
template<typename T>
|
||||
inline std::string format(const T& value)
|
||||
template <typename T> inline std::string format(const T &value)
|
||||
{
|
||||
static std::locale loc("");
|
||||
std::stringstream ss;
|
||||
@ -22,8 +20,7 @@ inline std::string format(const T& value)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string format(const double & value)
|
||||
template <> inline std::string format(const double &value)
|
||||
{
|
||||
static std::locale loc("");
|
||||
std::stringstream ss;
|
||||
@ -32,4 +29,4 @@ inline std::string format(const double & value)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace utils
|
||||
|
@ -20,14 +20,12 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace spdlog {
|
||||
|
||||
namespace details
|
||||
{
|
||||
namespace details {
|
||||
class async_log_helper;
|
||||
}
|
||||
|
||||
@ -35,26 +33,19 @@ class async_logger SPDLOG_FINAL : public logger
|
||||
{
|
||||
public:
|
||||
template <class It>
|
||||
async_logger(const std::string& logger_name,
|
||||
const It& begin,
|
||||
const It& end,
|
||||
size_t queue_size,
|
||||
async_logger(const std::string &logger_name, const It &begin, const It &end, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
|
||||
const std::function<void()> &worker_warmup_cb = nullptr,
|
||||
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
|
||||
const std::function<void()> &worker_teardown_cb = nullptr);
|
||||
|
||||
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,
|
||||
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
|
||||
const std::function<void()> &worker_warmup_cb = nullptr,
|
||||
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
|
||||
const std::function<void()> &worker_teardown_cb = nullptr);
|
||||
|
||||
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,
|
||||
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
|
||||
const std::function<void()> &worker_warmup_cb = nullptr,
|
||||
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
|
||||
@ -76,6 +67,6 @@ protected:
|
||||
private:
|
||||
std::unique_ptr<details::async_log_helper> _async_log_helper;
|
||||
};
|
||||
}
|
||||
} // namespace spdlog
|
||||
|
||||
#include "details/async_logger_impl.h"
|
||||
|
@ -13,11 +13,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "../common.h"
|
||||
#include "../sinks/sink.h"
|
||||
#include "../details/mpmc_bounded_q.h"
|
||||
#include "../details/log_msg.h"
|
||||
#include "../details/mpmc_bounded_q.h"
|
||||
#include "../details/os.h"
|
||||
#include "../formatter.h"
|
||||
#include "../sinks/sink.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
@ -28,10 +28,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
namespace spdlog { namespace details {
|
||||
|
||||
class async_log_helper
|
||||
{
|
||||
@ -57,22 +54,23 @@ class async_log_helper
|
||||
async_msg() = default;
|
||||
~async_msg() = default;
|
||||
|
||||
explicit async_msg(async_msg_type m_type) :
|
||||
level(level::info),
|
||||
thread_id(0),
|
||||
msg_type(m_type),
|
||||
msg_id(0)
|
||||
{}
|
||||
explicit async_msg(async_msg_type m_type)
|
||||
: level(level::info)
|
||||
, thread_id(0)
|
||||
, msg_type(m_type)
|
||||
, msg_id(0)
|
||||
{
|
||||
}
|
||||
|
||||
async_msg(async_msg&& other) SPDLOG_NOEXCEPT :
|
||||
logger_name(std::move(other.logger_name)),
|
||||
async_msg(async_msg &&other) SPDLOG_NOEXCEPT : logger_name(std::move(other.logger_name)),
|
||||
level(std::move(other.level)),
|
||||
time(std::move(other.time)),
|
||||
thread_id(other.thread_id),
|
||||
txt(std::move(other.txt)),
|
||||
msg_type(std::move(other.msg_type)),
|
||||
msg_id(other.msg_id)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
async_msg &operator=(async_msg &&other) SPDLOG_NOEXCEPT
|
||||
{
|
||||
@ -91,13 +89,13 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT :
|
||||
async_msg &operator=(const async_msg &other) = delete;
|
||||
|
||||
// construct from log_msg
|
||||
explicit async_msg(const details::log_msg& m):
|
||||
level(m.level),
|
||||
time(m.time),
|
||||
thread_id(m.thread_id),
|
||||
txt(m.raw.data(), m.raw.size()),
|
||||
msg_type(async_msg_type::log),
|
||||
msg_id(m.msg_id)
|
||||
explicit async_msg(const details::log_msg &m)
|
||||
: level(m.level)
|
||||
, time(m.time)
|
||||
, thread_id(m.thread_id)
|
||||
, txt(m.raw.data(), m.raw.size())
|
||||
, msg_type(async_msg_type::log)
|
||||
, msg_id(m.msg_id)
|
||||
{
|
||||
#ifndef SPDLOG_NO_NAME
|
||||
logger_name = *m.logger_name;
|
||||
@ -122,12 +120,8 @@ public:
|
||||
|
||||
using clock = std::chrono::steady_clock;
|
||||
|
||||
async_log_helper(formatter_ptr formatter,
|
||||
std::vector<sink_ptr> sinks,
|
||||
size_t queue_size,
|
||||
const log_err_handler err_handler,
|
||||
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
|
||||
std::function<void()> worker_warmup_cb = nullptr,
|
||||
async_log_helper(formatter_ptr formatter, std::vector<sink_ptr> sinks, size_t queue_size, const log_err_handler err_handler,
|
||||
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, std::function<void()> worker_warmup_cb = nullptr,
|
||||
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
|
||||
std::function<void()> worker_teardown_cb = nullptr);
|
||||
|
||||
@ -189,33 +183,25 @@ private:
|
||||
|
||||
// wait until the queue is empty
|
||||
void wait_empty_q();
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::details
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// async_sink class implementation
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline spdlog::details::async_log_helper::async_log_helper(
|
||||
formatter_ptr formatter,
|
||||
std::vector<sink_ptr> sinks,
|
||||
size_t queue_size,
|
||||
log_err_handler err_handler,
|
||||
const async_overflow_policy overflow_policy,
|
||||
std::function<void()> worker_warmup_cb,
|
||||
const std::chrono::milliseconds& flush_interval_ms,
|
||||
std::function<void()> worker_teardown_cb):
|
||||
_formatter(std::move(formatter)),
|
||||
_sinks(std::move(sinks)),
|
||||
_q(queue_size),
|
||||
_err_handler(std::move(err_handler)),
|
||||
_flush_requested(false),
|
||||
_terminate_requested(false),
|
||||
_overflow_policy(overflow_policy),
|
||||
_worker_warmup_cb(std::move(worker_warmup_cb)),
|
||||
_flush_interval_ms(flush_interval_ms),
|
||||
_worker_teardown_cb(std::move(worker_teardown_cb))
|
||||
inline spdlog::details::async_log_helper::async_log_helper(formatter_ptr formatter, std::vector<sink_ptr> sinks, size_t queue_size,
|
||||
log_err_handler err_handler, const async_overflow_policy overflow_policy, std::function<void()> worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, std::function<void()> worker_teardown_cb)
|
||||
: _formatter(std::move(formatter))
|
||||
, _sinks(std::move(sinks))
|
||||
, _q(queue_size)
|
||||
, _err_handler(std::move(err_handler))
|
||||
, _flush_requested(false)
|
||||
, _terminate_requested(false)
|
||||
, _overflow_policy(overflow_policy)
|
||||
, _worker_warmup_cb(std::move(worker_warmup_cb))
|
||||
, _flush_interval_ms(flush_interval_ms)
|
||||
, _worker_teardown_cb(std::move(worker_teardown_cb))
|
||||
{
|
||||
_worker_thread = std::thread(&async_log_helper::worker_loop, this);
|
||||
}
|
||||
@ -234,7 +220,6 @@ inline spdlog::details::async_log_helper::~async_log_helper()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Try to push and block until succeeded (if the policy is not to discard when the queue is full)
|
||||
inline void spdlog::details::async_log_helper::log(const details::log_msg &msg)
|
||||
{
|
||||
@ -251,8 +236,7 @@ inline void spdlog::details::async_log_helper::push_msg(details::async_log_helpe
|
||||
{
|
||||
now = details::os::now();
|
||||
sleep_or_yield(now, last_op_time);
|
||||
}
|
||||
while (!_q.enqueue(std::move(new_msg)));
|
||||
} while (!_q.enqueue(std::move(new_msg)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,7 +250,8 @@ inline void spdlog::details::async_log_helper::flush(bool wait_for_q)
|
||||
|
||||
inline void spdlog::details::async_log_helper::worker_loop()
|
||||
{
|
||||
if (_worker_warmup_cb) _worker_warmup_cb();
|
||||
if (_worker_warmup_cb)
|
||||
_worker_warmup_cb();
|
||||
auto last_pop = details::os::now();
|
||||
auto last_flush = last_pop;
|
||||
auto active = true;
|
||||
@ -285,9 +270,8 @@ inline void spdlog::details::async_log_helper::worker_loop()
|
||||
_err_handler("Unknown exeption in async logger worker loop.");
|
||||
}
|
||||
}
|
||||
if (_worker_teardown_cb) _worker_teardown_cb();
|
||||
|
||||
|
||||
if (_worker_teardown_cb)
|
||||
_worker_teardown_cb();
|
||||
}
|
||||
|
||||
// process next message in the queue
|
||||
@ -336,7 +320,8 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
|
||||
// flush all sinks if _flush_interval_ms has expired
|
||||
inline void spdlog::details::async_log_helper::handle_flush_interval(log_clock::time_point &now, log_clock::time_point &last_flush)
|
||||
{
|
||||
auto should_flush = _flush_requested || (_flush_interval_ms != std::chrono::milliseconds::zero() && now - last_flush >= _flush_interval_ms);
|
||||
auto should_flush =
|
||||
_flush_requested || (_flush_interval_ms != std::chrono::milliseconds::zero() && now - last_flush >= _flush_interval_ms);
|
||||
if (should_flush)
|
||||
{
|
||||
for (auto &s : _sinks)
|
||||
@ -352,10 +337,11 @@ inline void spdlog::details::async_log_helper::set_formatter(formatter_ptr msg_f
|
||||
}
|
||||
|
||||
// spin, yield or sleep. use the time passed since last message as a hint
|
||||
inline void spdlog::details::async_log_helper::sleep_or_yield(const spdlog::log_clock::time_point& now, const spdlog::log_clock::time_point& last_op_time)
|
||||
inline void spdlog::details::async_log_helper::sleep_or_yield(
|
||||
const spdlog::log_clock::time_point &now, const spdlog::log_clock::time_point &last_op_time)
|
||||
{
|
||||
using std::chrono::milliseconds;
|
||||
using std::chrono::microseconds;
|
||||
using std::chrono::milliseconds;
|
||||
|
||||
auto time_since_op = now - last_op_time;
|
||||
|
||||
|
@ -8,49 +8,39 @@
|
||||
// Async Logger implementation
|
||||
// Use an async_sink (queue per logger) to perform the logging in a worker thread
|
||||
|
||||
#include "../details/async_log_helper.h"
|
||||
#include "../async_logger.h"
|
||||
#include "../details/async_log_helper.h"
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
template <class It>
|
||||
inline spdlog::async_logger::async_logger(const std::string& logger_name,
|
||||
const It& begin,
|
||||
const It& end,
|
||||
size_t queue_size,
|
||||
const async_overflow_policy overflow_policy,
|
||||
const std::function<void()>& worker_warmup_cb,
|
||||
const std::chrono::milliseconds& flush_interval_ms,
|
||||
const std::function<void()>& worker_teardown_cb) :
|
||||
logger(logger_name, begin, end),
|
||||
_async_log_helper(new details::async_log_helper(_formatter, _sinks, queue_size, _err_handler, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb))
|
||||
inline spdlog::async_logger::async_logger(const std::string &logger_name, const It &begin, const It &end, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
|
||||
: logger(logger_name, begin, end)
|
||||
, _async_log_helper(new details::async_log_helper(
|
||||
_formatter, _sinks, queue_size, _err_handler, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb))
|
||||
{
|
||||
}
|
||||
|
||||
inline spdlog::async_logger::async_logger(const std::string& logger_name,
|
||||
sinks_init_list sinks_list,
|
||||
size_t queue_size,
|
||||
const async_overflow_policy overflow_policy,
|
||||
const std::function<void()>& worker_warmup_cb,
|
||||
const std::chrono::milliseconds& flush_interval_ms,
|
||||
const std::function<void()>& worker_teardown_cb) :
|
||||
async_logger(logger_name, sinks_list.begin(), sinks_list.end(), queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb) {}
|
||||
|
||||
inline spdlog::async_logger::async_logger(const std::string& logger_name,
|
||||
sink_ptr single_sink,
|
||||
size_t queue_size,
|
||||
const async_overflow_policy overflow_policy,
|
||||
const std::function<void()>& worker_warmup_cb,
|
||||
const std::chrono::milliseconds& flush_interval_ms,
|
||||
const std::function<void()>& worker_teardown_cb) :
|
||||
async_logger(logger_name,
|
||||
inline spdlog::async_logger::async_logger(const std::string &logger_name, sinks_init_list sinks_list, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
|
||||
: async_logger(logger_name, sinks_list.begin(), sinks_list.end(), queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms,
|
||||
worker_teardown_cb)
|
||||
{
|
||||
std::move(single_sink)
|
||||
}, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb) {}
|
||||
}
|
||||
|
||||
inline spdlog::async_logger::async_logger(const std::string &logger_name, sink_ptr single_sink, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
|
||||
: async_logger(
|
||||
logger_name, {std::move(single_sink)}, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb)
|
||||
{
|
||||
}
|
||||
|
||||
inline void spdlog::async_logger::flush()
|
||||
{
|
||||
@ -62,14 +52,12 @@ inline void spdlog::async_logger::set_error_handler(spdlog::log_err_handler err_
|
||||
{
|
||||
_err_handler = err_handler;
|
||||
_async_log_helper->set_error_handler(err_handler);
|
||||
|
||||
}
|
||||
inline spdlog::log_err_handler spdlog::async_logger::error_handler()
|
||||
{
|
||||
return _err_handler;
|
||||
}
|
||||
|
||||
|
||||
inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_formatter)
|
||||
{
|
||||
_formatter = msg_formatter;
|
||||
@ -82,7 +70,6 @@ inline void spdlog::async_logger::_set_pattern(const std::string& pattern, patte
|
||||
_async_log_helper->set_formatter(_formatter);
|
||||
}
|
||||
|
||||
|
||||
inline void spdlog::async_logger::_sink_it(details::log_msg &msg)
|
||||
{
|
||||
try
|
||||
@ -103,5 +90,4 @@ inline void spdlog::async_logger::_sink_it(details::log_msg& msg)
|
||||
_err_handler("Unknown exception in logger " + _name);
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,20 +9,17 @@
|
||||
// When failing to open a file, retry several times(5) with small delay between the tries(10 ms)
|
||||
// Throw spdlog_ex exception on errors
|
||||
|
||||
#include "../details/os.h"
|
||||
#include "../details/log_msg.h"
|
||||
#include "../details/os.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
#include <cerrno>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
namespace spdlog { namespace details {
|
||||
|
||||
class file_helper
|
||||
{
|
||||
@ -41,7 +38,6 @@ public:
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void open(const filename_t &fname, bool truncate = false)
|
||||
{
|
||||
close();
|
||||
@ -63,7 +59,6 @@ public:
|
||||
if (_filename.empty())
|
||||
throw spdlog_ex("Failed re opening file - was not opened before");
|
||||
open(_filename, truncate);
|
||||
|
||||
}
|
||||
|
||||
void flush()
|
||||
@ -141,5 +136,4 @@ private:
|
||||
FILE *_fd{nullptr};
|
||||
filename_t _filename;
|
||||
};
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::details
|
||||
|
@ -11,16 +11,13 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
namespace spdlog { namespace details {
|
||||
struct log_msg
|
||||
{
|
||||
log_msg() = default;
|
||||
log_msg(const std::string *loggers_name, level::level_enum lvl) :
|
||||
logger_name(loggers_name),
|
||||
level(lvl)
|
||||
log_msg(const std::string *loggers_name, level::level_enum lvl)
|
||||
: logger_name(loggers_name)
|
||||
, level(lvl)
|
||||
{
|
||||
#ifndef SPDLOG_NO_DATETIME
|
||||
time = os::now();
|
||||
@ -35,7 +32,6 @@ struct log_msg
|
||||
log_msg &operator=(log_msg &&other) = delete;
|
||||
log_msg(log_msg &&other) = delete;
|
||||
|
||||
|
||||
const std::string *logger_name{nullptr};
|
||||
level::level_enum level;
|
||||
log_clock::time_point time;
|
||||
@ -44,5 +40,4 @@ struct log_msg
|
||||
fmt::MemoryWriter formatted;
|
||||
size_t msg_id{0};
|
||||
};
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::details
|
||||
|
@ -14,39 +14,32 @@
|
||||
// create logger with given name, sinks and the default pattern formatter
|
||||
// all other ctors will call this one
|
||||
template <class It>
|
||||
inline spdlog::logger::logger(std::string logger_name, const It& begin, const It& end):
|
||||
_name(std::move(logger_name)),
|
||||
_sinks(begin, end),
|
||||
_formatter(std::make_shared<pattern_formatter>("%+")),
|
||||
_level(level::info),
|
||||
_flush_level(level::off),
|
||||
_last_err_time(0),
|
||||
_msg_counter(1) // message counter will start from 1. 0-message id will be reserved for controll messages
|
||||
inline spdlog::logger::logger(std::string logger_name, const It &begin, const It &end)
|
||||
: _name(std::move(logger_name))
|
||||
, _sinks(begin, end)
|
||||
, _formatter(std::make_shared<pattern_formatter>("%+"))
|
||||
, _level(level::info)
|
||||
, _flush_level(level::off)
|
||||
, _last_err_time(0)
|
||||
, _msg_counter(1) // message counter will start from 1. 0-message id will be reserved for controll messages
|
||||
{
|
||||
_err_handler = [this](const std::string &msg)
|
||||
{
|
||||
this->_default_err_handler(msg);
|
||||
};
|
||||
_err_handler = [this](const std::string &msg) { this->_default_err_handler(msg); };
|
||||
}
|
||||
|
||||
// ctor with sinks as init list
|
||||
inline spdlog::logger::logger(const std::string& logger_name, sinks_init_list sinks_list):
|
||||
logger(logger_name, sinks_list.begin(), sinks_list.end())
|
||||
{}
|
||||
|
||||
inline spdlog::logger::logger(const std::string &logger_name, sinks_init_list sinks_list)
|
||||
: logger(logger_name, sinks_list.begin(), sinks_list.end())
|
||||
{
|
||||
}
|
||||
|
||||
// ctor with single sink
|
||||
inline spdlog::logger::logger(const std::string& logger_name, spdlog::sink_ptr single_sink):
|
||||
logger(logger_name,
|
||||
inline spdlog::logger::logger(const std::string &logger_name, spdlog::sink_ptr single_sink)
|
||||
: logger(logger_name, {std::move(single_sink)})
|
||||
{
|
||||
std::move(single_sink)
|
||||
})
|
||||
{}
|
||||
|
||||
}
|
||||
|
||||
inline spdlog::logger::~logger() = default;
|
||||
|
||||
|
||||
inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter)
|
||||
{
|
||||
_set_formatter(std::move(msg_formatter));
|
||||
@ -57,10 +50,10 @@ inline void spdlog::logger::set_pattern(const std::string& pattern, pattern_time
|
||||
_set_pattern(pattern, pattern_time);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Args&... args)
|
||||
template <typename... Args> inline void spdlog::logger::log(level::level_enum lvl, const char *fmt, const Args &... args)
|
||||
{
|
||||
if (!should_log(lvl)) return;
|
||||
if (!should_log(lvl))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
@ -84,10 +77,10 @@ inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Ar
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void spdlog::logger::log(level::level_enum lvl, const char* msg)
|
||||
template <typename... Args> inline void spdlog::logger::log(level::level_enum lvl, const char *msg)
|
||||
{
|
||||
if (!should_log(lvl)) return;
|
||||
if (!should_log(lvl))
|
||||
return;
|
||||
try
|
||||
{
|
||||
details::log_msg log_msg(&_name, lvl);
|
||||
@ -105,10 +98,10 @@ inline void spdlog::logger::log(level::level_enum lvl, const char* msg)
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void spdlog::logger::log(level::level_enum lvl, const T& msg)
|
||||
template <typename T> inline void spdlog::logger::log(level::level_enum lvl, const T &msg)
|
||||
{
|
||||
if (!should_log(lvl)) return;
|
||||
if (!should_log(lvl))
|
||||
return;
|
||||
try
|
||||
{
|
||||
details::log_msg log_msg(&_name, lvl);
|
||||
@ -126,98 +119,78 @@ inline void spdlog::logger::log(level::level_enum lvl, const T& msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Arg1, typename... Args>
|
||||
inline void spdlog::logger::trace(const char* fmt, const Arg1 &arg1, const Args&... args)
|
||||
template <typename Arg1, typename... Args> inline void spdlog::logger::trace(const char *fmt, const Arg1 &arg1, const Args &... args)
|
||||
{
|
||||
log(level::trace, fmt, arg1, args...);
|
||||
}
|
||||
|
||||
template <typename Arg1, typename... Args>
|
||||
inline void spdlog::logger::debug(const char* fmt, const Arg1 &arg1, const Args&... args)
|
||||
template <typename Arg1, typename... Args> inline void spdlog::logger::debug(const char *fmt, const Arg1 &arg1, const Args &... args)
|
||||
{
|
||||
log(level::debug, fmt, arg1, args...);
|
||||
}
|
||||
|
||||
template <typename Arg1, typename... Args>
|
||||
inline void spdlog::logger::info(const char* fmt, const Arg1 &arg1, const Args&... args)
|
||||
template <typename Arg1, typename... Args> inline void spdlog::logger::info(const char *fmt, const Arg1 &arg1, const Args &... args)
|
||||
{
|
||||
log(level::info, fmt, arg1, args...);
|
||||
}
|
||||
|
||||
template <typename Arg1, typename... Args>
|
||||
inline void spdlog::logger::warn(const char* fmt, const Arg1 &arg1, const Args&... args)
|
||||
template <typename Arg1, typename... Args> inline void spdlog::logger::warn(const char *fmt, const Arg1 &arg1, const Args &... args)
|
||||
{
|
||||
log(level::warn, fmt, arg1, args...);
|
||||
}
|
||||
|
||||
template <typename Arg1, typename... Args>
|
||||
inline void spdlog::logger::error(const char* fmt, const Arg1 &arg1, const Args&... args)
|
||||
template <typename Arg1, typename... Args> inline void spdlog::logger::error(const char *fmt, const Arg1 &arg1, const Args &... args)
|
||||
{
|
||||
log(level::err, fmt, arg1, args...);
|
||||
}
|
||||
|
||||
template <typename Arg1, typename... Args>
|
||||
inline void spdlog::logger::critical(const char* fmt, const Arg1 &arg1, const Args&... args)
|
||||
template <typename Arg1, typename... Args> inline void spdlog::logger::critical(const char *fmt, const Arg1 &arg1, const Args &... args)
|
||||
{
|
||||
log(level::critical, fmt, arg1, args...);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void spdlog::logger::trace(const T& msg)
|
||||
template <typename T> inline void spdlog::logger::trace(const T &msg)
|
||||
{
|
||||
log(level::trace, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void spdlog::logger::debug(const T& msg)
|
||||
template <typename T> inline void spdlog::logger::debug(const T &msg)
|
||||
{
|
||||
log(level::debug, msg);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void spdlog::logger::info(const T& msg)
|
||||
template <typename T> inline void spdlog::logger::info(const T &msg)
|
||||
{
|
||||
log(level::info, msg);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void spdlog::logger::warn(const T& msg)
|
||||
template <typename T> inline void spdlog::logger::warn(const T &msg)
|
||||
{
|
||||
log(level::warn, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void spdlog::logger::error(const T& msg)
|
||||
template <typename T> inline void spdlog::logger::error(const T &msg)
|
||||
{
|
||||
log(level::err, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void spdlog::logger::critical(const T& msg)
|
||||
template <typename T> inline void spdlog::logger::critical(const T &msg)
|
||||
{
|
||||
log(level::critical, msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
|
||||
template <typename... Args>
|
||||
inline void spdlog::logger::log(level::level_enum lvl, const wchar_t* msg)
|
||||
template <typename... Args> inline void spdlog::logger::log(level::level_enum lvl, const wchar_t *msg)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
|
||||
|
||||
log(lvl, conv.to_bytes(msg));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void spdlog::logger::log(level::level_enum lvl, const wchar_t* fmt, const Args&... args)
|
||||
template <typename... Args> inline void spdlog::logger::log(level::level_enum lvl, const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
fmt::WMemoryWriter wWriter;
|
||||
|
||||
@ -225,47 +198,38 @@ inline void spdlog::logger::log(level::level_enum lvl, const wchar_t* fmt, const
|
||||
log(lvl, wWriter.c_str());
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void spdlog::logger::trace(const wchar_t* fmt, const Args&... args)
|
||||
template <typename... Args> inline void spdlog::logger::trace(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::trace, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void spdlog::logger::debug(const wchar_t* fmt, const Args&... args)
|
||||
template <typename... Args> inline void spdlog::logger::debug(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::debug, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void spdlog::logger::info(const wchar_t* fmt, const Args&... args)
|
||||
template <typename... Args> inline void spdlog::logger::info(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::info, fmt, args...);
|
||||
}
|
||||
|
||||
|
||||
template <typename... Args>
|
||||
inline void spdlog::logger::warn(const wchar_t* fmt, const Args&... args)
|
||||
template <typename... Args> inline void spdlog::logger::warn(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::warn, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void spdlog::logger::error(const wchar_t* fmt, const Args&... args)
|
||||
template <typename... Args> inline void spdlog::logger::error(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::err, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void spdlog::logger::critical(const wchar_t* fmt, const Args&... args)
|
||||
template <typename... Args> inline void spdlog::logger::critical(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::critical, fmt, args...);
|
||||
}
|
||||
|
||||
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
|
||||
|
||||
|
||||
//
|
||||
// name and level
|
||||
//
|
||||
@ -370,4 +334,3 @@ inline const std::vector<spdlog::sink_ptr>& spdlog::logger::sinks() const
|
||||
{
|
||||
return _sinks;
|
||||
}
|
||||
|
||||
|
@ -48,21 +48,17 @@ Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
#include <atomic>
|
||||
#include <utility>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
namespace spdlog { namespace details {
|
||||
|
||||
template <typename T>
|
||||
class mpmc_bounded_queue
|
||||
template <typename T> class mpmc_bounded_queue
|
||||
{
|
||||
public:
|
||||
using item_type = T;
|
||||
|
||||
explicit mpmc_bounded_queue(size_t buffer_size)
|
||||
:max_size_(buffer_size),
|
||||
buffer_(new cell_t[buffer_size]),
|
||||
buffer_mask_(buffer_size - 1)
|
||||
: max_size_(buffer_size)
|
||||
, buffer_(new cell_t[buffer_size])
|
||||
, buffer_mask_(buffer_size - 1)
|
||||
{
|
||||
// queue size must be power of two
|
||||
if (!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0)))
|
||||
@ -117,8 +113,7 @@ public:
|
||||
for (;;)
|
||||
{
|
||||
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 = static_cast<intptr_t>(seq) - static_cast<intptr_t>(pos + 1);
|
||||
if (dif == 0)
|
||||
{
|
||||
@ -144,8 +139,7 @@ public:
|
||||
front = enqueue_pos_.load(std::memory_order_acquire);
|
||||
back = dequeue_pos_.load(std::memory_order_acquire);
|
||||
front1 = enqueue_pos_.load(std::memory_order_relaxed);
|
||||
}
|
||||
while (front != front1);
|
||||
} while (front != front1);
|
||||
return back == front;
|
||||
}
|
||||
|
||||
@ -171,5 +165,4 @@ private:
|
||||
cacheline_pad_t pad3_;
|
||||
};
|
||||
|
||||
} // ns details
|
||||
} // ns spdlog
|
||||
}} // namespace spdlog::details
|
||||
|
@ -8,10 +8,7 @@
|
||||
#include <atomic>
|
||||
// null, no cost dummy "mutex" and dummy "atomic" int
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
namespace spdlog { namespace details {
|
||||
struct null_mutex
|
||||
{
|
||||
void lock() {}
|
||||
@ -27,8 +24,10 @@ struct null_atomic_int
|
||||
int value;
|
||||
null_atomic_int() = default;
|
||||
|
||||
explicit null_atomic_int(int val) : value(val)
|
||||
{}
|
||||
explicit null_atomic_int(int val)
|
||||
: value(val)
|
||||
{
|
||||
}
|
||||
|
||||
int load(std::memory_order) const
|
||||
{
|
||||
@ -41,5 +40,4 @@ struct null_atomic_int
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::details
|
||||
|
@ -6,17 +6,17 @@
|
||||
|
||||
#include "../common.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <thread>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@ -27,9 +27,9 @@
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <process.h> // _get_pid support
|
||||
#include <io.h> // _get_osfhandle and _isatty support
|
||||
#include <process.h> // _get_pid support
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <share.h>
|
||||
@ -37,8 +37,8 @@
|
||||
|
||||
#else // unix
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/syscall.h> //Use gettid() syscall under linux to get thread id
|
||||
@ -53,13 +53,7 @@
|
||||
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
|
||||
#endif
|
||||
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
namespace os
|
||||
{
|
||||
namespace spdlog { namespace details { namespace os {
|
||||
|
||||
inline spdlog::log_clock::time_point now()
|
||||
{
|
||||
@ -68,14 +62,11 @@ inline spdlog::log_clock::time_point now()
|
||||
timespec ts;
|
||||
::clock_gettime(CLOCK_REALTIME_COARSE, &ts);
|
||||
return std::chrono::time_point<log_clock, typename log_clock::duration>(
|
||||
std::chrono::duration_cast<typename log_clock::duration>(
|
||||
std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec)));
|
||||
|
||||
std::chrono::duration_cast<typename log_clock::duration>(std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec)));
|
||||
|
||||
#else
|
||||
return log_clock::now();
|
||||
#endif
|
||||
|
||||
}
|
||||
inline std::tm localtime(const std::time_t &time_tt)
|
||||
{
|
||||
@ -116,13 +107,8 @@ inline std::tm gmtime()
|
||||
}
|
||||
inline bool operator==(const std::tm &tm1, const std::tm &tm2)
|
||||
{
|
||||
return (tm1.tm_sec == tm2.tm_sec &&
|
||||
tm1.tm_min == tm2.tm_min &&
|
||||
tm1.tm_hour == tm2.tm_hour &&
|
||||
tm1.tm_mday == tm2.tm_mday &&
|
||||
tm1.tm_mon == tm2.tm_mon &&
|
||||
tm1.tm_year == tm2.tm_year &&
|
||||
tm1.tm_isdst == tm2.tm_isdst);
|
||||
return (tm1.tm_sec == tm2.tm_sec && tm1.tm_min == tm2.tm_min && tm1.tm_hour == tm2.tm_hour && tm1.tm_mday == tm2.tm_mday &&
|
||||
tm1.tm_mon == tm2.tm_mon && tm1.tm_year == tm2.tm_year && tm1.tm_isdst == tm2.tm_isdst);
|
||||
}
|
||||
|
||||
inline bool operator!=(const std::tm &tm1, const std::tm &tm2)
|
||||
@ -141,8 +127,6 @@ inline bool operator!=(const std::tm& tm1, const std::tm& tm2)
|
||||
|
||||
SPDLOG_CONSTEXPR static const char *default_eol = SPDLOG_EOL;
|
||||
|
||||
|
||||
|
||||
// folder separator
|
||||
#ifdef _WIN32
|
||||
SPDLOG_CONSTEXPR static const char folder_sep = '\\';
|
||||
@ -150,7 +134,6 @@ SPDLOG_CONSTEXPR static const char folder_sep = '\\';
|
||||
SPDLOG_CONSTEXPR static const char folder_sep = '/';
|
||||
#endif
|
||||
|
||||
|
||||
inline void prevent_child_fd(FILE *f)
|
||||
{
|
||||
|
||||
@ -167,7 +150,6 @@ inline void prevent_child_fd(FILE *f)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// fopen_s on non windows for writing
|
||||
inline bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode)
|
||||
{
|
||||
@ -188,7 +170,6 @@ inline bool fopen_s(FILE** fp, const filename_t& filename, const filename_t& mod
|
||||
return *fp == nullptr;
|
||||
}
|
||||
|
||||
|
||||
inline int remove(const filename_t &filename)
|
||||
{
|
||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
|
||||
@ -207,7 +188,6 @@ inline int rename(const filename_t& filename1, const filename_t& filename2)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Return if file exists
|
||||
inline bool file_exists(const filename_t &filename)
|
||||
{
|
||||
@ -224,9 +204,6 @@ inline bool file_exists(const filename_t& filename)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Return file size according to open FILE* object
|
||||
inline size_t filesize(FILE *f)
|
||||
{
|
||||
@ -261,9 +238,6 @@ inline size_t filesize(FILE *f)
|
||||
throw spdlog_ex("Failed getting file size from fd", errno);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Return utc offset in minutes or throw spdlog_ex on failure
|
||||
inline int utc_minutes_offset(const std::tm &tm = details::os::localtime())
|
||||
{
|
||||
@ -298,16 +272,15 @@ inline int utc_minutes_offset(const std::tm& tm = details::os::localtime())
|
||||
|
||||
long int days = (
|
||||
// difference in day of year
|
||||
localtm.tm_yday - gmtm.tm_yday
|
||||
localtm.tm_yday -
|
||||
gmtm.tm_yday
|
||||
|
||||
// + intervening leap days
|
||||
+ ((local_year >> 2) - (gmt_year >> 2))
|
||||
- (local_year / 100 - gmt_year / 100)
|
||||
+ ((local_year / 100 >> 2) - (gmt_year / 100 >> 2))
|
||||
+ ((local_year >> 2) - (gmt_year >> 2)) - (local_year / 100 - gmt_year / 100) +
|
||||
((local_year / 100 >> 2) - (gmt_year / 100 >> 2))
|
||||
|
||||
// + difference in years * 365 */
|
||||
+ (long int)(local_year - gmt_year) * 365
|
||||
);
|
||||
+ (long int)(local_year - gmt_year) * 365);
|
||||
|
||||
long int hours = (24 * days) + (localtm.tm_hour - gmtm.tm_hour);
|
||||
long int mins = (60 * hours) + (localtm.tm_min - gmtm.tm_min);
|
||||
@ -353,17 +326,15 @@ inline size_t _thread_id()
|
||||
// Return current thread id as size_t (from thread local storage)
|
||||
inline size_t thread_id()
|
||||
{
|
||||
#if defined(SPDLOG_DISABLE_TID_CACHING) || (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__cplusplus_winrt ) || (defined(__clang__) && !__has_feature(cxx_thread_local))
|
||||
#if defined(SPDLOG_DISABLE_TID_CACHING) || (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__cplusplus_winrt) || \
|
||||
(defined(__clang__) && !__has_feature(cxx_thread_local))
|
||||
return _thread_id();
|
||||
#else // cache thread id in tls
|
||||
static thread_local const size_t tid = _thread_id();
|
||||
return tid;
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// This is avoid msvc issue in sleep_for that happens if the clock changes.
|
||||
// See https://github.com/gabime/spdlog/issues/609
|
||||
inline void sleep_for_millis(int milliseconds)
|
||||
@ -439,10 +410,8 @@ inline int pid()
|
||||
#else
|
||||
return static_cast<int>(::getpid());
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Determine if the terminal supports colors
|
||||
// Source: https://github.com/agauniyal/rang/
|
||||
inline bool is_color_terminal()
|
||||
@ -450,11 +419,8 @@ inline bool is_color_terminal()
|
||||
#ifdef _WIN32
|
||||
return true;
|
||||
#else
|
||||
static constexpr const char* Terms[] =
|
||||
{
|
||||
"ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm",
|
||||
"linux", "msys", "putty", "rxvt", "screen", "vt100", "xterm"
|
||||
};
|
||||
static constexpr const char *Terms[] = {
|
||||
"ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", "linux", "msys", "putty", "rxvt", "screen", "vt100", "xterm"};
|
||||
|
||||
const char *env_p = std::getenv("TERM");
|
||||
if (env_p == nullptr)
|
||||
@ -462,16 +428,12 @@ inline bool is_color_terminal()
|
||||
return false;
|
||||
}
|
||||
|
||||
static const bool result = std::any_of(
|
||||
std::begin(Terms), std::end(Terms), [&](const char* term)
|
||||
{
|
||||
return std::strstr(env_p, term) != nullptr;
|
||||
});
|
||||
static const bool result =
|
||||
std::any_of(std::begin(Terms), std::end(Terms), [&](const char *term) { return std::strstr(env_p, term) != nullptr; });
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Detrmine if the terminal attached
|
||||
// Source: https://github.com/agauniyal/rang/
|
||||
inline bool in_terminal(FILE *file)
|
||||
@ -483,6 +445,4 @@ inline bool in_terminal(FILE* file)
|
||||
return isatty(fileno(file)) != 0;
|
||||
#endif
|
||||
}
|
||||
} //os
|
||||
} //details
|
||||
} //spdlog
|
||||
}}} // namespace spdlog::details::os
|
||||
|
@ -5,11 +5,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../formatter.h"
|
||||
#include "../details/log_msg.h"
|
||||
#include "../details/os.h"
|
||||
#include "../fmt/fmt.h"
|
||||
#include "../formatter.h"
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
@ -18,12 +19,8 @@
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
namespace spdlog { namespace details {
|
||||
class flag_formatter
|
||||
{
|
||||
public:
|
||||
@ -105,7 +102,8 @@ class b_formatter : public flag_formatter
|
||||
};
|
||||
|
||||
// Full month name
|
||||
static const std::string full_months[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
|
||||
static const std::string full_months[]{
|
||||
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
|
||||
class B_formatter : public flag_formatter
|
||||
{
|
||||
void format(details::log_msg &msg, const std::tm &tm_time) override
|
||||
@ -334,6 +332,7 @@ public:
|
||||
msg.formatted << sign;
|
||||
pad_n_join(msg.formatted, h, m, ':');
|
||||
}
|
||||
|
||||
private:
|
||||
log_clock::time_point _last_update{std::chrono::seconds(0)};
|
||||
int _offset_minutes{0};
|
||||
@ -389,17 +388,19 @@ class v_formatter SPDLOG_FINAL : public flag_formatter
|
||||
class ch_formatter SPDLOG_FINAL : public flag_formatter
|
||||
{
|
||||
public:
|
||||
explicit ch_formatter(char ch): _ch(ch)
|
||||
{}
|
||||
explicit ch_formatter(char ch)
|
||||
: _ch(ch)
|
||||
{
|
||||
}
|
||||
void format(details::log_msg &msg, const std::tm &) override
|
||||
{
|
||||
msg.formatted << _ch;
|
||||
}
|
||||
|
||||
private:
|
||||
char _ch;
|
||||
};
|
||||
|
||||
|
||||
// aggregate user chars to display as is
|
||||
class aggregate_formatter SPDLOG_FINAL : public flag_formatter
|
||||
{
|
||||
@ -414,6 +415,7 @@ public:
|
||||
{
|
||||
msg.formatted << _str;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _str;
|
||||
};
|
||||
@ -441,7 +443,6 @@ class full_formatter SPDLOG_FINAL : public flag_formatter
|
||||
level::to_str(msg.level),
|
||||
msg.raw.str());*/
|
||||
|
||||
|
||||
// Faster (albeit uglier) way to format the line (5.6 million lines/sec under 10 threads)
|
||||
msg.formatted << '[' << static_cast<unsigned int>(tm_time.tm_year + 1900) << '-'
|
||||
<< fmt::pad(static_cast<unsigned int>(tm_time.tm_mon + 1), 2, '0') << '-'
|
||||
@ -465,16 +466,13 @@ class full_formatter SPDLOG_FINAL : public flag_formatter
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::details
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// pattern_formatter inline impl
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline spdlog::pattern_formatter::pattern_formatter(const std::string& pattern, pattern_time_type pattern_time, std::string eol) :
|
||||
_eol(std::move(eol)),
|
||||
_pattern_time(pattern_time)
|
||||
inline spdlog::pattern_formatter::pattern_formatter(const std::string &pattern, pattern_time_type pattern_time, std::string eol)
|
||||
: _eol(std::move(eol))
|
||||
, _pattern_time(pattern_time)
|
||||
{
|
||||
compile_pattern(pattern);
|
||||
}
|
||||
@ -505,7 +503,6 @@ inline void spdlog::pattern_formatter::compile_pattern(const std::string& patter
|
||||
{
|
||||
_formatters.push_back(std::move(user_chars));
|
||||
}
|
||||
|
||||
}
|
||||
inline void spdlog::pattern_formatter::handle_flag(char flag)
|
||||
{
|
||||
@ -634,7 +631,6 @@ inline void spdlog::pattern_formatter::handle_flag(char flag)
|
||||
_formatters.emplace_back(new details::pid_formatter());
|
||||
break;
|
||||
|
||||
|
||||
case ('i'):
|
||||
_formatters.emplace_back(new details::i_formatter());
|
||||
break;
|
||||
|
@ -10,10 +10,10 @@
|
||||
// If user requests a non existing logger, nullptr will be returned
|
||||
// This class is thread safe
|
||||
|
||||
#include "../details/null_mutex.h"
|
||||
#include "../logger.h"
|
||||
#include "../async_logger.h"
|
||||
#include "../common.h"
|
||||
#include "../details/null_mutex.h"
|
||||
#include "../logger.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
@ -22,12 +22,8 @@
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
template <class Mutex>
|
||||
class registry_t
|
||||
namespace spdlog { namespace details {
|
||||
template <class Mutex> class registry_t
|
||||
{
|
||||
public:
|
||||
registry_t<Mutex>(const registry_t<Mutex> &) = delete;
|
||||
@ -48,14 +44,14 @@ public:
|
||||
return found == _loggers.end() ? nullptr : found->second;
|
||||
}
|
||||
|
||||
template<class It>
|
||||
std::shared_ptr<logger> create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end)
|
||||
template <class It> std::shared_ptr<logger> create(const std::string &logger_name, const It &sinks_begin, const It &sinks_end)
|
||||
{
|
||||
std::lock_guard<Mutex> lock(_mutex);
|
||||
throw_if_exists(logger_name);
|
||||
std::shared_ptr<logger> new_logger;
|
||||
if (_async_mode)
|
||||
new_logger = std::make_shared<async_logger>(logger_name, sinks_begin, sinks_end, _async_q_size, _overflow_policy, _worker_warmup_cb, _flush_interval_ms, _worker_teardown_cb);
|
||||
new_logger = std::make_shared<async_logger>(logger_name, sinks_begin, sinks_end, _async_q_size, _overflow_policy,
|
||||
_worker_warmup_cb, _flush_interval_ms, _worker_teardown_cb);
|
||||
else
|
||||
new_logger = std::make_shared<logger>(logger_name, sinks_begin, sinks_end);
|
||||
|
||||
@ -68,18 +64,21 @@ public:
|
||||
new_logger->set_level(_level);
|
||||
new_logger->flush_on(_flush_level);
|
||||
|
||||
|
||||
// Add to registry
|
||||
_loggers[logger_name] = new_logger;
|
||||
return new_logger;
|
||||
}
|
||||
|
||||
template <class It>
|
||||
std::shared_ptr<async_logger> create_async(const std::string& logger_name, size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb, const It& sinks_begin, const It& sinks_end)
|
||||
std::shared_ptr<async_logger> create_async(const std::string &logger_name, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb, const It &sinks_begin,
|
||||
const It &sinks_end)
|
||||
{
|
||||
std::lock_guard<Mutex> lock(_mutex);
|
||||
throw_if_exists(logger_name);
|
||||
auto new_logger = std::make_shared<async_logger>(logger_name, sinks_begin, sinks_end, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb);
|
||||
auto new_logger = std::make_shared<async_logger>(
|
||||
logger_name, sinks_begin, sinks_end, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb);
|
||||
|
||||
if (_formatter)
|
||||
new_logger->set_formatter(_formatter);
|
||||
@ -124,12 +123,17 @@ public:
|
||||
return create(logger_name, {sink});
|
||||
}
|
||||
|
||||
std::shared_ptr<async_logger> create_async(const std::string& logger_name, size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb, sinks_init_list sinks)
|
||||
std::shared_ptr<async_logger> create_async(const std::string &logger_name, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb, sinks_init_list sinks)
|
||||
{
|
||||
return create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks.begin(), sinks.end());
|
||||
return create_async(
|
||||
logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks.begin(), sinks.end());
|
||||
}
|
||||
|
||||
std::shared_ptr<async_logger> create_async(const std::string& logger_name, size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb, sink_ptr sink)
|
||||
std::shared_ptr<async_logger> create_async(const std::string &logger_name, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb, sink_ptr sink)
|
||||
{
|
||||
return create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, {sink});
|
||||
}
|
||||
@ -173,7 +177,8 @@ public:
|
||||
_err_handler = handler;
|
||||
}
|
||||
|
||||
void set_async_mode(size_t q_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb)
|
||||
void set_async_mode(size_t q_size, const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
|
||||
{
|
||||
std::lock_guard<Mutex> lock(_mutex);
|
||||
_async_mode = true;
|
||||
@ -225,5 +230,4 @@ using registry = registry_t<spdlog::details::null_mutex>;
|
||||
using registry = registry_t<std::mutex>;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::details
|
||||
|
@ -8,10 +8,10 @@
|
||||
//
|
||||
// Global registry functions
|
||||
//
|
||||
#include "../spdlog.h"
|
||||
#include "../details/registry.h"
|
||||
#include "../sinks/file_sinks.h"
|
||||
#include "../sinks/stdout_sinks.h"
|
||||
#include "../spdlog.h"
|
||||
#ifdef SPDLOG_ENABLE_SYSLOG
|
||||
#include "../sinks/syslog_sink.h"
|
||||
#endif
|
||||
@ -22,7 +22,6 @@
|
||||
#include "../sinks/ansicolor_sink.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include "../sinks/android_sink.h"
|
||||
#endif
|
||||
@ -59,28 +58,31 @@ inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_st(const std::string
|
||||
}
|
||||
|
||||
// Create multi/single threaded rotating file logger
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_mt(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files)
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_mt(
|
||||
const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files)
|
||||
{
|
||||
return create<spdlog::sinks::rotating_file_sink_mt>(logger_name, filename, max_file_size, max_files);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_st(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files)
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_st(
|
||||
const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files)
|
||||
{
|
||||
return create<spdlog::sinks::rotating_file_sink_st>(logger_name, filename, max_file_size, max_files);
|
||||
}
|
||||
|
||||
// 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 filename_t& filename, int hour, int minute)
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_mt(
|
||||
const std::string &logger_name, const filename_t &filename, int hour, int minute)
|
||||
{
|
||||
return create<spdlog::sinks::daily_file_sink_mt>(logger_name, filename, hour, minute);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_st(const std::string& logger_name, const filename_t& filename, int hour, int minute)
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_st(
|
||||
const std::string &logger_name, const filename_t &filename, int hour, int minute)
|
||||
{
|
||||
return create<spdlog::sinks::daily_file_sink_st>(logger_name, filename, hour, minute);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// stdout/stderr loggers
|
||||
//
|
||||
@ -127,7 +129,6 @@ inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string
|
||||
return spdlog::details::registry::instance().create(logger_name, sink);
|
||||
}
|
||||
|
||||
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string &logger_name)
|
||||
{
|
||||
auto sink = std::make_shared<spdlog::sinks::wincolor_stderr_sink_st>();
|
||||
@ -163,7 +164,8 @@ inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string
|
||||
|
||||
#ifdef SPDLOG_ENABLE_SYSLOG
|
||||
// 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, int syslog_facility)
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(
|
||||
const std::string &logger_name, const std::string &syslog_ident, int syslog_option, int syslog_facility)
|
||||
{
|
||||
return create<spdlog::sinks::syslog_sink>(logger_name, syslog_ident, syslog_option, syslog_facility);
|
||||
}
|
||||
@ -202,21 +204,30 @@ inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_
|
||||
}
|
||||
|
||||
// Create and register an async logger with a single sink
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::create_async(const std::string& logger_name, const sink_ptr& sink, size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb)
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::create_async(const std::string &logger_name, const sink_ptr &sink, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
|
||||
{
|
||||
return details::registry::instance().create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sink);
|
||||
return details::registry::instance().create_async(
|
||||
logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sink);
|
||||
}
|
||||
|
||||
// Create and register an async logger with multiple sinks
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::create_async(const std::string& logger_name, sinks_init_list sinks, size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb )
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::create_async(const std::string &logger_name, sinks_init_list sinks, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
|
||||
{
|
||||
return details::registry::instance().create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks);
|
||||
return details::registry::instance().create_async(
|
||||
logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks);
|
||||
}
|
||||
|
||||
template <class It>
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::create_async(const std::string& logger_name, const It& sinks_begin, const It& sinks_end, size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb)
|
||||
inline std::shared_ptr<spdlog::logger> spdlog::create_async(const std::string &logger_name, const It &sinks_begin, const It &sinks_end,
|
||||
size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()> &worker_warmup_cb,
|
||||
const std::chrono::milliseconds &flush_interval_ms, const std::function<void()> &worker_teardown_cb)
|
||||
{
|
||||
return details::registry::instance().create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks_begin, sinks_end);
|
||||
return details::registry::instance().create_async(
|
||||
logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks_begin, sinks_end);
|
||||
}
|
||||
|
||||
inline void spdlog::set_formatter(spdlog::formatter_ptr f)
|
||||
@ -244,7 +255,9 @@ inline void spdlog::set_error_handler(log_err_handler handler)
|
||||
return details::registry::instance().set_error_handler(std::move(handler));
|
||||
}
|
||||
|
||||
inline void spdlog::set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb)
|
||||
inline void spdlog::set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy,
|
||||
const std::function<void()> &worker_warmup_cb, const std::chrono::milliseconds &flush_interval_ms,
|
||||
const std::function<void()> &worker_teardown_cb)
|
||||
{
|
||||
details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -13,14 +13,11 @@
|
||||
#include "format.h"
|
||||
#include <ostream>
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
namespace fmt {
|
||||
|
||||
namespace internal
|
||||
{
|
||||
namespace internal {
|
||||
|
||||
template <class Char>
|
||||
class FormatBuf : public std::basic_streambuf<Char>
|
||||
template <class Char> class FormatBuf : public std::basic_streambuf<Char>
|
||||
{
|
||||
private:
|
||||
typedef typename std::basic_streambuf<Char>::int_type int_type;
|
||||
@ -29,7 +26,10 @@ private:
|
||||
Buffer<Char> &buffer_;
|
||||
|
||||
public:
|
||||
FormatBuf(Buffer<Char> &buffer) : buffer_(buffer) {}
|
||||
FormatBuf(Buffer<Char> &buffer)
|
||||
: buffer_(buffer)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
// The put-area is actually always empty. This makes the implementation
|
||||
@ -60,14 +60,12 @@ struct DummyStream : std::ostream
|
||||
DummyStream(); // Suppress a bogus warning in MSVC.
|
||||
|
||||
// Hide all operator<< overloads from std::ostream.
|
||||
template <typename T>
|
||||
typename EnableIf<sizeof(T) == 0>::type operator<<(const T &);
|
||||
template <typename T> typename EnableIf<sizeof(T) == 0>::type operator<<(const T &);
|
||||
};
|
||||
|
||||
No &operator<<(std::ostream &, int);
|
||||
|
||||
template <typename T>
|
||||
struct ConvertToIntImpl<T, true>
|
||||
template <typename T> struct ConvertToIntImpl<T, true>
|
||||
{
|
||||
// Convert to int only if T doesn't have an overloaded operator<<.
|
||||
enum
|
||||
@ -82,8 +80,7 @@ FMT_API void write(std::ostream &os, Writer &w);
|
||||
|
||||
// Formats a value.
|
||||
template <typename Char, typename ArgFormatter_, typename T>
|
||||
void format_arg(BasicFormatter<Char, ArgFormatter_> &f,
|
||||
const Char *&format_str, const T &value)
|
||||
void format_arg(BasicFormatter<Char, ArgFormatter_> &f, const Char *&format_str, const T &value)
|
||||
{
|
||||
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
|
||||
|
||||
|
@ -55,7 +55,8 @@
|
||||
// equals to EINTR.
|
||||
#ifndef _WIN32
|
||||
#define FMT_RETRY_VAL(result, expression, error_result) \
|
||||
do { \
|
||||
do \
|
||||
{ \
|
||||
result = (expression); \
|
||||
} while (result == error_result && errno == EINTR)
|
||||
#else
|
||||
@ -64,8 +65,7 @@
|
||||
|
||||
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
namespace fmt {
|
||||
|
||||
// An error code.
|
||||
class ErrorCode
|
||||
@ -74,8 +74,7 @@ private:
|
||||
int value_;
|
||||
|
||||
public:
|
||||
explicit ErrorCode(int value = 0) FMT_NOEXCEPT :
|
||||
value_(value) {}
|
||||
explicit ErrorCode(int value = 0) FMT_NOEXCEPT : value_(value) {}
|
||||
|
||||
int get() const FMT_NOEXCEPT
|
||||
{
|
||||
@ -91,12 +90,14 @@ private:
|
||||
|
||||
friend class File;
|
||||
|
||||
explicit BufferedFile(FILE *f) : file_(f) {}
|
||||
explicit BufferedFile(FILE *f)
|
||||
: file_(f)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
// Constructs a BufferedFile object which doesn't represent any file.
|
||||
BufferedFile() FMT_NOEXCEPT :
|
||||
file_(FMT_NULL) {}
|
||||
BufferedFile() FMT_NOEXCEPT : file_(FMT_NULL) {}
|
||||
|
||||
// Destroys the object closing the file it represents if any.
|
||||
FMT_API ~BufferedFile() FMT_NOEXCEPT;
|
||||
@ -115,12 +116,10 @@ private:
|
||||
|
||||
public:
|
||||
// A "move constructor" for moving from a temporary.
|
||||
BufferedFile(Proxy p) FMT_NOEXCEPT :
|
||||
file_(p.file) {}
|
||||
BufferedFile(Proxy p) FMT_NOEXCEPT : file_(p.file) {}
|
||||
|
||||
// A "move constructor" for moving from an lvalue.
|
||||
BufferedFile(BufferedFile &f) FMT_NOEXCEPT :
|
||||
file_(f.file_)
|
||||
BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_)
|
||||
{
|
||||
f.file_ = FMT_NULL;
|
||||
}
|
||||
@ -156,8 +155,7 @@ private:
|
||||
FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile);
|
||||
|
||||
public:
|
||||
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT :
|
||||
file_(other.file_)
|
||||
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_)
|
||||
{
|
||||
other.file_ = FMT_NULL;
|
||||
}
|
||||
@ -206,7 +204,10 @@ private:
|
||||
int fd_; // File descriptor.
|
||||
|
||||
// Constructs a File object with a given descriptor.
|
||||
explicit File(int fd) : fd_(fd) {}
|
||||
explicit File(int fd)
|
||||
: fd_(fd)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
// Possible values for the oflag argument to the constructor.
|
||||
@ -218,8 +219,7 @@ public:
|
||||
};
|
||||
|
||||
// Constructs a File object which doesn't represent any file.
|
||||
File() FMT_NOEXCEPT :
|
||||
fd_(-1) {}
|
||||
File() FMT_NOEXCEPT : fd_(-1) {}
|
||||
|
||||
// Opens a file and constructs a File object representing this file.
|
||||
FMT_API File(CStringRef path, int oflag);
|
||||
@ -238,12 +238,10 @@ private:
|
||||
|
||||
public:
|
||||
// A "move constructor" for moving from a temporary.
|
||||
File(Proxy p) FMT_NOEXCEPT :
|
||||
fd_(p.fd) {}
|
||||
File(Proxy p) FMT_NOEXCEPT : fd_(p.fd) {}
|
||||
|
||||
// A "move constructor" for moving from an lvalue.
|
||||
File(File &other) FMT_NOEXCEPT :
|
||||
fd_(other.fd_)
|
||||
File(File &other) FMT_NOEXCEPT : fd_(other.fd_)
|
||||
{
|
||||
other.fd_ = -1;
|
||||
}
|
||||
@ -279,8 +277,7 @@ private:
|
||||
FMT_DISALLOW_COPY_AND_ASSIGN(File);
|
||||
|
||||
public:
|
||||
File(File &&other) FMT_NOEXCEPT :
|
||||
fd_(other.fd_)
|
||||
File(File &&other) FMT_NOEXCEPT : fd_(other.fd_)
|
||||
{
|
||||
other.fd_ = -1;
|
||||
}
|
||||
@ -340,8 +337,7 @@ File(File &&other) FMT_NOEXCEPT :
|
||||
// Returns the memory page size.
|
||||
long getpagesize();
|
||||
|
||||
#if (defined(LC_NUMERIC_MASK) || defined(_MSC_VER)) && \
|
||||
!defined(__ANDROID__) && !defined(__CYGWIN__)
|
||||
#if (defined(LC_NUMERIC_MASK) || defined(_MSC_VER)) && !defined(__ANDROID__) && !defined(__CYGWIN__)
|
||||
#define FMT_LOCALE
|
||||
#endif
|
||||
|
||||
@ -353,7 +349,10 @@ private:
|
||||
#ifdef _MSC_VER
|
||||
typedef _locale_t locale_t;
|
||||
|
||||
enum { LC_NUMERIC_MASK = LC_NUMERIC };
|
||||
enum
|
||||
{
|
||||
LC_NUMERIC_MASK = LC_NUMERIC
|
||||
};
|
||||
|
||||
static locale_t newlocale(int category_mask, const char *locale, locale_t)
|
||||
{
|
||||
@ -378,7 +377,8 @@ private:
|
||||
public:
|
||||
typedef locale_t Type;
|
||||
|
||||
Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", FMT_NULL))
|
||||
Locale()
|
||||
: locale_(newlocale(LC_NUMERIC_MASK, "C", FMT_NULL))
|
||||
{
|
||||
if (!locale_)
|
||||
FMT_THROW(fmt::SystemError(errno, "cannot create locale"));
|
||||
@ -407,8 +407,7 @@ public:
|
||||
} // namespace fmt
|
||||
|
||||
#if !FMT_USE_RVALUE_REFERENCES
|
||||
namespace std
|
||||
{
|
||||
namespace std {
|
||||
// For compatibility with C++98.
|
||||
inline fmt::BufferedFile &move(fmt::BufferedFile &f)
|
||||
{
|
||||
@ -418,7 +417,7 @@ inline fmt::File &move(fmt::File &f)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
}
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
#endif // FMT_POSIX_H_
|
||||
|
@ -15,18 +15,14 @@
|
||||
|
||||
#include "ostream.h"
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
namespace fmt {
|
||||
namespace internal {
|
||||
|
||||
// Checks if a value fits in int - used to avoid warnings about comparing
|
||||
// signed and unsigned integers.
|
||||
template <bool IsSigned>
|
||||
struct IntChecker
|
||||
template <bool IsSigned> struct IntChecker
|
||||
{
|
||||
template <typename T>
|
||||
static bool fits_in_int(T value)
|
||||
template <typename T> static bool fits_in_int(T value)
|
||||
{
|
||||
unsigned max = std::numeric_limits<int>::max();
|
||||
return value <= max;
|
||||
@ -37,14 +33,11 @@ struct IntChecker
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct IntChecker<true>
|
||||
template <> struct IntChecker<true>
|
||||
{
|
||||
template <typename T>
|
||||
static bool fits_in_int(T value)
|
||||
template <typename T> static bool fits_in_int(T value)
|
||||
{
|
||||
return value >= std::numeric_limits<int>::min() &&
|
||||
value <= std::numeric_limits<int>::max();
|
||||
return value >= std::numeric_limits<int>::min() && value <= std::numeric_limits<int>::max();
|
||||
}
|
||||
static bool fits_in_int(int)
|
||||
{
|
||||
@ -60,8 +53,7 @@ public:
|
||||
FMT_THROW(FormatError("precision is not integer"));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int visit_any_int(T value)
|
||||
template <typename T> int visit_any_int(T value)
|
||||
{
|
||||
if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
||||
FMT_THROW(FormatError("number is too big"));
|
||||
@ -73,8 +65,7 @@ public:
|
||||
class IsZeroInt : public ArgVisitor<IsZeroInt, bool>
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
bool visit_any_int(T value)
|
||||
template <typename T> bool visit_any_int(T value)
|
||||
{
|
||||
return value == 0;
|
||||
}
|
||||
@ -99,14 +90,12 @@ public:
|
||||
return 'p';
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
char visit_any_int(T)
|
||||
template <typename T> char visit_any_int(T)
|
||||
{
|
||||
return 'd';
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
char visit_any_double(T)
|
||||
template <typename T> char visit_any_double(T)
|
||||
{
|
||||
return 'g';
|
||||
}
|
||||
@ -117,24 +106,27 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct is_same
|
||||
template <typename T, typename U> struct is_same
|
||||
{
|
||||
enum { value = 0 };
|
||||
enum
|
||||
{
|
||||
value = 0
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_same<T, T>
|
||||
template <typename T> struct is_same<T, T>
|
||||
{
|
||||
enum { value = 1 };
|
||||
enum
|
||||
{
|
||||
value = 1
|
||||
};
|
||||
};
|
||||
|
||||
// An argument visitor that converts an integer argument to T for printf,
|
||||
// if T is an integral type. If T is void, the argument is converted to
|
||||
// corresponding signed or unsigned type depending on the type specifier:
|
||||
// 'd' and 'i' - signed, other - unsigned)
|
||||
template <typename T = void>
|
||||
class ArgConverter : public ArgVisitor<ArgConverter<T>, void>
|
||||
template <typename T = void> class ArgConverter : public ArgVisitor<ArgConverter<T>, void>
|
||||
{
|
||||
private:
|
||||
internal::Arg &arg_;
|
||||
@ -144,7 +136,10 @@ private:
|
||||
|
||||
public:
|
||||
ArgConverter(internal::Arg &arg, wchar_t type)
|
||||
: arg_(arg), type_(type) {}
|
||||
: arg_(arg)
|
||||
, type_(type)
|
||||
{
|
||||
}
|
||||
|
||||
void visit_bool(bool value)
|
||||
{
|
||||
@ -158,8 +153,7 @@ public:
|
||||
visit_any_int(value);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void visit_any_int(U value)
|
||||
template <typename U> void visit_any_int(U value)
|
||||
{
|
||||
bool is_signed = type_ == 'd' || type_ == 'i';
|
||||
if (type_ == 's')
|
||||
@ -168,8 +162,7 @@ public:
|
||||
}
|
||||
|
||||
using internal::Arg;
|
||||
typedef typename internal::Conditional<
|
||||
is_same<T, void>::value, U, T>::type TargetType;
|
||||
typedef typename internal::Conditional<is_same<T, void>::value, U, T>::type TargetType;
|
||||
if (const_check(sizeof(TargetType) <= sizeof(int)))
|
||||
{
|
||||
// Extra casts are used to silence warnings.
|
||||
@ -198,8 +191,7 @@ public:
|
||||
else
|
||||
{
|
||||
arg_.type = Arg::ULONG_LONG;
|
||||
arg_.ulong_long_value =
|
||||
static_cast<typename internal::MakeUnsigned<U>::Type>(value);
|
||||
arg_.ulong_long_value = static_cast<typename internal::MakeUnsigned<U>::Type>(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,10 +206,12 @@ private:
|
||||
FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);
|
||||
|
||||
public:
|
||||
explicit CharConverter(internal::Arg &arg) : arg_(arg) {}
|
||||
explicit CharConverter(internal::Arg &arg)
|
||||
: arg_(arg)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void visit_any_int(T value)
|
||||
template <typename T> void visit_any_int(T value)
|
||||
{
|
||||
arg_.type = internal::Arg::CHAR;
|
||||
arg_.int_value = static_cast<char>(value);
|
||||
@ -234,15 +228,17 @@ private:
|
||||
FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
|
||||
|
||||
public:
|
||||
explicit WidthHandler(FormatSpec &spec) : spec_(spec) {}
|
||||
explicit WidthHandler(FormatSpec &spec)
|
||||
: spec_(spec)
|
||||
{
|
||||
}
|
||||
|
||||
void report_unhandled_arg()
|
||||
{
|
||||
FMT_THROW(FormatError("width is not integer"));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned visit_any_int(T value)
|
||||
template <typename T> unsigned visit_any_int(T value)
|
||||
{
|
||||
typedef typename internal::IntTraits<T>::MainType UnsignedType;
|
||||
UnsignedType width = static_cast<UnsignedType>(value);
|
||||
@ -276,9 +272,7 @@ public:
|
||||
superclass will be called.
|
||||
\endrst
|
||||
*/
|
||||
template <typename Impl, typename Char, typename Spec>
|
||||
class BasicPrintfArgFormatter :
|
||||
public internal::ArgFormatterBase<Impl, Char, Spec>
|
||||
template <typename Impl, typename Char, typename Spec> class BasicPrintfArgFormatter : public internal::ArgFormatterBase<Impl, Char, Spec>
|
||||
{
|
||||
private:
|
||||
void write_null_pointer()
|
||||
@ -298,7 +292,9 @@ public:
|
||||
\endrst
|
||||
*/
|
||||
BasicPrintfArgFormatter(BasicWriter<Char> &w, Spec &s)
|
||||
: internal::ArgFormatterBase<Impl, Char, Spec>(w, s) {}
|
||||
: internal::ArgFormatterBase<Impl, Char, Spec>(w, s)
|
||||
{
|
||||
}
|
||||
|
||||
/** Formats an argument of type ``bool``. */
|
||||
void visit_bool(bool value)
|
||||
@ -371,19 +367,18 @@ public:
|
||||
};
|
||||
|
||||
/** The default printf argument formatter. */
|
||||
template <typename Char>
|
||||
class PrintfArgFormatter :
|
||||
public BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char, FormatSpec>
|
||||
template <typename Char> class PrintfArgFormatter : public BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char, FormatSpec>
|
||||
{
|
||||
public:
|
||||
/** Constructs an argument formatter object. */
|
||||
PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
|
||||
: BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char, FormatSpec>(w, s) {}
|
||||
: BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char, FormatSpec>(w, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** This template formats data and writes the output to a writer. */
|
||||
template <typename Char, typename ArgFormatter = PrintfArgFormatter<Char> >
|
||||
class PrintfFormatter : private internal::FormatterBase
|
||||
template <typename Char, typename ArgFormatter = PrintfArgFormatter<Char>> class PrintfFormatter : private internal::FormatterBase
|
||||
{
|
||||
private:
|
||||
BasicWriter<Char> &writer_;
|
||||
@ -392,9 +387,7 @@ private:
|
||||
|
||||
// Returns the argument with specified index or, if arg_index is equal
|
||||
// to the maximum unsigned value, the next argument.
|
||||
internal::Arg get_arg(
|
||||
const Char *s,
|
||||
unsigned arg_index = (std::numeric_limits<unsigned>::max)());
|
||||
internal::Arg get_arg(const Char *s, unsigned arg_index = (std::numeric_limits<unsigned>::max)());
|
||||
|
||||
// Parses argument index, flags and width and returns the argument index.
|
||||
unsigned parse_header(const Char *&s, FormatSpec &spec);
|
||||
@ -408,14 +401,16 @@ public:
|
||||
\endrst
|
||||
*/
|
||||
explicit PrintfFormatter(const ArgList &al, BasicWriter<Char> &w)
|
||||
: FormatterBase(al), writer_(w) {}
|
||||
: FormatterBase(al)
|
||||
, writer_(w)
|
||||
{
|
||||
}
|
||||
|
||||
/** Formats stored arguments and writes the output to the writer. */
|
||||
void format(BasicCStringRef<Char> format_str);
|
||||
};
|
||||
|
||||
template <typename Char, typename AF>
|
||||
void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s)
|
||||
template <typename Char, typename AF> void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
@ -443,22 +438,17 @@ void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s)
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Char, typename AF>
|
||||
internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s,
|
||||
unsigned arg_index)
|
||||
template <typename Char, typename AF> internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s, unsigned arg_index)
|
||||
{
|
||||
(void)s;
|
||||
const char *error = FMT_NULL;
|
||||
internal::Arg arg = arg_index == std::numeric_limits<unsigned>::max() ?
|
||||
next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
|
||||
internal::Arg arg = arg_index == std::numeric_limits<unsigned>::max() ? next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
|
||||
if (error)
|
||||
FMT_THROW(FormatError(!*s ? "invalid format string" : error));
|
||||
return arg;
|
||||
}
|
||||
|
||||
template <typename Char, typename AF>
|
||||
unsigned PrintfFormatter<Char, AF>::parse_header(
|
||||
const Char *&s, FormatSpec &spec)
|
||||
template <typename Char, typename AF> unsigned PrintfFormatter<Char, AF>::parse_header(const Char *&s, FormatSpec &spec)
|
||||
{
|
||||
unsigned arg_index = std::numeric_limits<unsigned>::max();
|
||||
Char c = *s;
|
||||
@ -499,15 +489,15 @@ unsigned PrintfFormatter<Char, AF>::parse_header(
|
||||
return arg_index;
|
||||
}
|
||||
|
||||
template <typename Char, typename AF>
|
||||
void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
|
||||
template <typename Char, typename AF> void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
|
||||
{
|
||||
const Char *start = format_str.c_str();
|
||||
const Char *s = start;
|
||||
while (*s)
|
||||
{
|
||||
Char c = *s++;
|
||||
if (c != '%') continue;
|
||||
if (c != '%')
|
||||
continue;
|
||||
if (*s == c)
|
||||
{
|
||||
write(writer_, start, s);
|
||||
|
@ -19,11 +19,8 @@
|
||||
#pragma warning(disable : 4996) // "deprecated" functions
|
||||
#endif
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
template <typename ArgFormatter>
|
||||
void format_arg(BasicFormatter<char, ArgFormatter> &f,
|
||||
const char *&format_str, const std::tm &tm)
|
||||
namespace fmt {
|
||||
template <typename ArgFormatter> void format_arg(BasicFormatter<char, ArgFormatter> &f, const char *&format_str, const std::tm &tm)
|
||||
{
|
||||
if (*format_str == ':')
|
||||
++format_str;
|
||||
@ -60,8 +57,7 @@ void format_arg(BasicFormatter<char, ArgFormatter> &f,
|
||||
format_str = end + 1;
|
||||
}
|
||||
|
||||
namespace internal
|
||||
{
|
||||
namespace internal {
|
||||
inline Null<> localtime_r(...)
|
||||
{
|
||||
return Null<>();
|
||||
@ -78,7 +74,7 @@ inline Null<> gmtime_s(...)
|
||||
{
|
||||
return Null<>();
|
||||
}
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
// Thread-safe replacement for std::localtime
|
||||
inline std::tm localtime(std::time_t time)
|
||||
@ -88,7 +84,10 @@ inline std::tm localtime(std::time_t time)
|
||||
std::time_t time_;
|
||||
std::tm tm_;
|
||||
|
||||
LocalTime(std::time_t t): time_(t) {}
|
||||
LocalTime(std::time_t t)
|
||||
: time_(t)
|
||||
{
|
||||
}
|
||||
|
||||
bool run()
|
||||
{
|
||||
@ -116,7 +115,8 @@ inline std::tm localtime(std::time_t time)
|
||||
{
|
||||
using namespace fmt::internal;
|
||||
std::tm *tm = std::localtime(&time_);
|
||||
if (tm) tm_ = *tm;
|
||||
if (tm)
|
||||
tm_ = *tm;
|
||||
return tm != FMT_NULL;
|
||||
}
|
||||
};
|
||||
@ -136,7 +136,10 @@ inline std::tm gmtime(std::time_t time)
|
||||
std::time_t time_;
|
||||
std::tm tm_;
|
||||
|
||||
GMTime(std::time_t t): time_(t) {}
|
||||
GMTime(std::time_t t)
|
||||
: time_(t)
|
||||
{
|
||||
}
|
||||
|
||||
bool run()
|
||||
{
|
||||
@ -163,7 +166,8 @@ inline std::tm gmtime(std::time_t time)
|
||||
bool fallback(internal::Null<>)
|
||||
{
|
||||
std::tm *tm = std::gmtime(&time_);
|
||||
if (tm != FMT_NULL) tm_ = *tm;
|
||||
if (tm != FMT_NULL)
|
||||
tm_ = *tm;
|
||||
return tm != FMT_NULL;
|
||||
}
|
||||
};
|
||||
|
@ -31,4 +31,3 @@
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -8,10 +8,8 @@
|
||||
// include external or bundled copy of fmtlib's ostream support
|
||||
//
|
||||
#if !defined(SPDLOG_FMT_EXTERNAL)
|
||||
#include "fmt.h"
|
||||
#include "bundled/ostream.h"
|
||||
#include "fmt.h"
|
||||
#else
|
||||
#include <fmt/ostream.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -7,14 +7,12 @@
|
||||
|
||||
#include "details/log_msg.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
class flag_formatter;
|
||||
}
|
||||
|
||||
@ -28,7 +26,8 @@ public:
|
||||
class pattern_formatter SPDLOG_FINAL : public formatter
|
||||
{
|
||||
public:
|
||||
explicit pattern_formatter(const std::string& pattern, pattern_time_type pattern_time = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol);
|
||||
explicit pattern_formatter(const std::string &pattern, pattern_time_type pattern_time = pattern_time_type::local,
|
||||
std::string eol = spdlog::details::os::default_eol);
|
||||
pattern_formatter(const pattern_formatter &) = delete;
|
||||
pattern_formatter &operator=(const pattern_formatter &) = delete;
|
||||
void format(details::log_msg &msg) override;
|
||||
@ -42,6 +41,6 @@ private:
|
||||
void handle_flag(char flag);
|
||||
void compile_pattern(const std::string &pattern);
|
||||
};
|
||||
}
|
||||
} // namespace spdlog
|
||||
|
||||
#include "details/pattern_formatter_impl.h"
|
||||
|
@ -12,15 +12,14 @@
|
||||
// 2. Format the message using the formatter function
|
||||
// 3. Pass the formatted message to its sinks to performa the actual logging
|
||||
|
||||
#include "sinks/base_sink.h"
|
||||
#include "common.h"
|
||||
#include "sinks/base_sink.h"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace spdlog {
|
||||
|
||||
class logger
|
||||
{
|
||||
@ -28,8 +27,7 @@ public:
|
||||
logger(const std::string &name, sink_ptr single_sink);
|
||||
logger(const std::string &name, sinks_init_list sinks);
|
||||
|
||||
template <class It>
|
||||
logger(std::string name, const It& begin, const It& end);
|
||||
template <class It> logger(std::string name, const It &begin, const It &end);
|
||||
|
||||
virtual ~logger();
|
||||
|
||||
@ -105,6 +103,6 @@ protected:
|
||||
std::atomic<time_t> _last_err_time;
|
||||
std::atomic<size_t> _msg_counter;
|
||||
};
|
||||
}
|
||||
} // namespace spdlog
|
||||
|
||||
#include "details/logger_impl.h"
|
||||
|
@ -7,23 +7,20 @@
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
#include "sink.h"
|
||||
#include "../details/os.h"
|
||||
#include "sink.h"
|
||||
|
||||
#include <android/log.h>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <android/log.h>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
#if !defined(SPDLOG_ANDROID_RETRIES)
|
||||
#define SPDLOG_ANDROID_RETRIES 2
|
||||
#endif
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
namespace spdlog { namespace sinks {
|
||||
|
||||
/*
|
||||
* Android sink (logging using __android_log_write)
|
||||
@ -32,7 +29,11 @@ namespace sinks
|
||||
class android_sink : public sink
|
||||
{
|
||||
public:
|
||||
explicit android_sink(const std::string& tag = "spdlog", bool use_raw_msg = false): _tag(tag), _use_raw_msg(use_raw_msg) {}
|
||||
explicit android_sink(const std::string &tag = "spdlog", bool use_raw_msg = false)
|
||||
: _tag(tag)
|
||||
, _use_raw_msg(use_raw_msg)
|
||||
{
|
||||
}
|
||||
|
||||
void log(const details::log_msg &msg) override
|
||||
{
|
||||
@ -55,9 +56,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void flush() override
|
||||
{
|
||||
}
|
||||
void flush() override {}
|
||||
|
||||
private:
|
||||
static android_LogPriority convert_to_android(spdlog::level::level_enum level)
|
||||
@ -85,7 +84,6 @@ private:
|
||||
bool _use_raw_msg;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
||||
#endif
|
||||
|
@ -5,28 +5,25 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base_sink.h"
|
||||
#include "../common.h"
|
||||
#include "../details/os.h"
|
||||
#include "base_sink.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
namespace spdlog { namespace sinks {
|
||||
|
||||
/**
|
||||
* This sink prefixes the output with an ANSI escape sequence color code depending on the severity
|
||||
* of the message.
|
||||
* If no color terminal detected, omit the escape codes.
|
||||
*/
|
||||
template <class Mutex>
|
||||
class ansicolor_sink : public base_sink<Mutex>
|
||||
template <class Mutex> class ansicolor_sink : public base_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
explicit ansicolor_sink(FILE* file) : target_file_(file)
|
||||
explicit ansicolor_sink(FILE *file)
|
||||
: target_file_(file)
|
||||
{
|
||||
should_do_colors_ = details::os::in_terminal(file) && details::os::is_color_terminal();
|
||||
colors_[level::trace] = cyan;
|
||||
@ -109,29 +106,28 @@ protected:
|
||||
std::unordered_map<level::level_enum, std::string, level::level_hasher> colors_;
|
||||
};
|
||||
|
||||
|
||||
template<class Mutex>
|
||||
class ansicolor_stdout_sink: public ansicolor_sink<Mutex>
|
||||
template <class Mutex> class ansicolor_stdout_sink : public ansicolor_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
ansicolor_stdout_sink(): ansicolor_sink<Mutex>(stdout)
|
||||
{}
|
||||
ansicolor_stdout_sink()
|
||||
: ansicolor_sink<Mutex>(stdout)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using ansicolor_stdout_sink_mt = ansicolor_stdout_sink<std::mutex>;
|
||||
using ansicolor_stdout_sink_st = ansicolor_stdout_sink<details::null_mutex>;
|
||||
|
||||
template<class Mutex>
|
||||
class ansicolor_stderr_sink: public ansicolor_sink<Mutex>
|
||||
template <class Mutex> class ansicolor_stderr_sink : public ansicolor_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
ansicolor_stderr_sink(): ansicolor_sink<Mutex>(stderr)
|
||||
{}
|
||||
ansicolor_stderr_sink()
|
||||
: ansicolor_sink<Mutex>(stderr)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using ansicolor_stderr_sink_mt = ansicolor_stderr_sink<std::mutex>;
|
||||
using ansicolor_stderr_sink_st = ansicolor_stderr_sink<details::null_mutex>;
|
||||
|
||||
} // namespace sinks
|
||||
} // namespace spdlog
|
||||
|
||||
}} // namespace spdlog::sinks
|
||||
|
@ -10,19 +10,15 @@
|
||||
// all locking is taken care of here so no locking needed by the implementers..
|
||||
//
|
||||
|
||||
#include "sink.h"
|
||||
#include "../formatter.h"
|
||||
#include "../common.h"
|
||||
#include "../details/log_msg.h"
|
||||
#include "../formatter.h"
|
||||
#include "sink.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
template<class Mutex>
|
||||
class base_sink : public sink
|
||||
namespace spdlog { namespace sinks {
|
||||
template <class Mutex> class base_sink : public sink
|
||||
{
|
||||
public:
|
||||
base_sink() = default;
|
||||
@ -47,5 +43,4 @@ protected:
|
||||
virtual void _flush() = 0;
|
||||
Mutex _mutex;
|
||||
};
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
@ -11,21 +11,20 @@
|
||||
#include "sink.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
// Distribution sink (mux). Stores a vector of sinks which get called when log is called
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
template<class Mutex>
|
||||
class dist_sink : public base_sink<Mutex>
|
||||
namespace spdlog { namespace sinks {
|
||||
template <class Mutex> class dist_sink : public base_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
explicit dist_sink() :_sinks() {}
|
||||
explicit dist_sink()
|
||||
: _sinks()
|
||||
{
|
||||
}
|
||||
dist_sink(const dist_sink &) = delete;
|
||||
dist_sink &operator=(const dist_sink &) = delete;
|
||||
|
||||
@ -66,5 +65,4 @@ public:
|
||||
using dist_sink_mt = dist_sink<std::mutex>;
|
||||
using dist_sink_st = dist_sink<details::null_mutex>;
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
@ -5,31 +5,28 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base_sink.h"
|
||||
#include "../details/null_mutex.h"
|
||||
#include "../details/file_helper.h"
|
||||
#include "../details/null_mutex.h"
|
||||
#include "../fmt/fmt.h"
|
||||
#include "base_sink.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <cerrno>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
namespace spdlog { namespace sinks {
|
||||
/*
|
||||
* Trivial file sink with single file as target
|
||||
*/
|
||||
template <class Mutex>
|
||||
class simple_file_sink SPDLOG_FINAL : public base_sink<Mutex>
|
||||
template <class Mutex> class simple_file_sink SPDLOG_FINAL : public base_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
explicit simple_file_sink(const filename_t &filename, bool truncate = false):_force_flush(false)
|
||||
explicit simple_file_sink(const filename_t &filename, bool truncate = false)
|
||||
: _force_flush(false)
|
||||
{
|
||||
_file_helper.open(filename, truncate);
|
||||
}
|
||||
@ -63,15 +60,13 @@ using simple_file_sink_st = simple_file_sink<details::null_mutex>;
|
||||
/*
|
||||
* Rotating file sink based on size
|
||||
*/
|
||||
template <class Mutex>
|
||||
class rotating_file_sink SPDLOG_FINAL : public base_sink<Mutex>
|
||||
template <class Mutex> class rotating_file_sink SPDLOG_FINAL : public base_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
rotating_file_sink(filename_t base_filename,
|
||||
std::size_t max_size, std::size_t max_files) :
|
||||
_base_filename(std::move(base_filename)),
|
||||
_max_size(max_size),
|
||||
_max_files(max_files)
|
||||
rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files)
|
||||
: _base_filename(std::move(base_filename))
|
||||
, _max_size(max_size)
|
||||
, _max_files(max_files)
|
||||
{
|
||||
_file_helper.open(calc_filename(_base_filename, 0));
|
||||
_current_size = _file_helper.size(); // expensive. called only once
|
||||
@ -164,7 +159,8 @@ struct default_daily_file_name_calculator
|
||||
filename_t basename, ext;
|
||||
std::tie(basename, ext) = details::file_helper::split_by_extenstion(filename);
|
||||
std::conditional<std::is_same<filename_t::value_type, char>::value, fmt::MemoryWriter, fmt::WMemoryWriter>::type w;
|
||||
w.write(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}_{:02d}-{:02d}{}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, ext);
|
||||
w.write(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}_{:02d}-{:02d}{}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, ext);
|
||||
return w.str();
|
||||
}
|
||||
};
|
||||
@ -189,18 +185,14 @@ struct dateonly_daily_file_name_calculator
|
||||
/*
|
||||
* Rotating file sink based on date. rotates at midnight
|
||||
*/
|
||||
template<class Mutex, class FileNameCalc = default_daily_file_name_calculator>
|
||||
class daily_file_sink SPDLOG_FINAL :public base_sink < Mutex >
|
||||
template <class Mutex, class FileNameCalc = default_daily_file_name_calculator> class daily_file_sink SPDLOG_FINAL : public base_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
// create daily file sink which rotates on given time
|
||||
daily_file_sink(
|
||||
filename_t base_filename,
|
||||
int rotation_hour,
|
||||
int rotation_minute) :
|
||||
_base_filename(std::move(base_filename)),
|
||||
_rotation_h(rotation_hour),
|
||||
_rotation_m(rotation_minute)
|
||||
daily_file_sink(filename_t base_filename, int rotation_hour, int rotation_minute)
|
||||
: _base_filename(std::move(base_filename))
|
||||
, _rotation_h(rotation_hour)
|
||||
, _rotation_m(rotation_minute)
|
||||
{
|
||||
if (rotation_hour < 0 || rotation_hour > 23 || rotation_minute < 0 || rotation_minute > 59)
|
||||
throw spdlog_ex("daily_file_sink: Invalid rotation time in ctor");
|
||||
@ -208,7 +200,6 @@ public:
|
||||
_file_helper.open(FileNameCalc::calc_filename(_base_filename));
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
void _sink_it(const details::log_msg &msg) override
|
||||
{
|
||||
@ -252,5 +243,4 @@ private:
|
||||
using daily_file_sink_mt = daily_file_sink<std::mutex>;
|
||||
using daily_file_sink_st = daily_file_sink<details::null_mutex>;
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
@ -7,28 +7,22 @@
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include "base_sink.h"
|
||||
#include "../details/null_mutex.h"
|
||||
#include "base_sink.h"
|
||||
|
||||
#include <winbase.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
namespace spdlog { namespace sinks {
|
||||
/*
|
||||
* MSVC sink (logging using OutputDebugStringA)
|
||||
*/
|
||||
template<class Mutex>
|
||||
class msvc_sink : public base_sink<Mutex>
|
||||
template <class Mutex> class msvc_sink : public base_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
explicit msvc_sink()
|
||||
{
|
||||
}
|
||||
explicit msvc_sink() {}
|
||||
|
||||
protected:
|
||||
void _sink_it(const details::log_msg &msg) override
|
||||
@ -36,14 +30,12 @@ protected:
|
||||
OutputDebugStringA(msg.formatted.c_str());
|
||||
}
|
||||
|
||||
void _flush() override
|
||||
{}
|
||||
void _flush() override {}
|
||||
};
|
||||
|
||||
using msvc_sink_mt = msvc_sink<std::mutex>;
|
||||
using msvc_sink_st = msvc_sink<details::null_mutex>;
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
||||
#endif
|
||||
|
@ -5,31 +5,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base_sink.h"
|
||||
#include "../details/null_mutex.h"
|
||||
#include "base_sink.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
namespace spdlog { namespace sinks {
|
||||
|
||||
template <class Mutex>
|
||||
class null_sink : public base_sink<Mutex>
|
||||
template <class Mutex> class null_sink : public base_sink<Mutex>
|
||||
{
|
||||
protected:
|
||||
void _sink_it(const details::log_msg&) override
|
||||
{}
|
||||
|
||||
void _flush() override
|
||||
{}
|
||||
void _sink_it(const details::log_msg &) override {}
|
||||
|
||||
void _flush() override {}
|
||||
};
|
||||
|
||||
using null_sink_mt = null_sink<details::null_mutex>;
|
||||
using null_sink_st = null_sink<details::null_mutex>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace spdlog::sinks
|
||||
|
@ -8,18 +8,18 @@
|
||||
#include "../details/null_mutex.h"
|
||||
#include "base_sink.h"
|
||||
|
||||
#include <ostream>
|
||||
#include <mutex>
|
||||
#include <ostream>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
template<class Mutex>
|
||||
class ostream_sink : public base_sink<Mutex>
|
||||
namespace spdlog { namespace sinks {
|
||||
template <class Mutex> class ostream_sink : public base_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
explicit ostream_sink(std::ostream& os, bool force_flush=false) :_ostream(os), _force_flush(force_flush) {}
|
||||
explicit ostream_sink(std::ostream &os, bool force_flush = false)
|
||||
: _ostream(os)
|
||||
, _force_flush(force_flush)
|
||||
{
|
||||
}
|
||||
ostream_sink(const ostream_sink &) = delete;
|
||||
ostream_sink &operator=(const ostream_sink &) = delete;
|
||||
|
||||
@ -43,5 +43,4 @@ protected:
|
||||
using ostream_sink_mt = ostream_sink<std::mutex>;
|
||||
using ostream_sink_st = ostream_sink<details::null_mutex>;
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
@ -7,10 +7,7 @@
|
||||
|
||||
#include "../details/log_msg.h"
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
namespace spdlog { namespace sinks {
|
||||
class sink
|
||||
{
|
||||
public:
|
||||
@ -42,5 +39,4 @@ inline level::level_enum sink::level() const
|
||||
return static_cast<spdlog::level::level_enum>(_level.load(std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
@ -12,13 +12,9 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
namespace spdlog { namespace sinks {
|
||||
|
||||
template <class Mutex>
|
||||
class stdout_sink SPDLOG_FINAL : public base_sink<Mutex>
|
||||
template <class Mutex> class stdout_sink SPDLOG_FINAL : public base_sink<Mutex>
|
||||
{
|
||||
using MyType = stdout_sink<Mutex>;
|
||||
|
||||
@ -47,8 +43,7 @@ protected:
|
||||
using stdout_sink_mt = stdout_sink<std::mutex>;
|
||||
using stdout_sink_st = stdout_sink<details::null_mutex>;
|
||||
|
||||
template <class Mutex>
|
||||
class stderr_sink SPDLOG_FINAL : public base_sink<Mutex>
|
||||
template <class Mutex> class stderr_sink SPDLOG_FINAL : public base_sink<Mutex>
|
||||
{
|
||||
using MyType = stderr_sink<Mutex>;
|
||||
|
||||
@ -77,5 +72,4 @@ protected:
|
||||
using stderr_sink_mt = stderr_sink<std::mutex>;
|
||||
using stderr_sink_st = stderr_sink<details::null_mutex>;
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
@ -9,18 +9,14 @@
|
||||
|
||||
#ifdef SPDLOG_ENABLE_SYSLOG
|
||||
|
||||
#include "sink.h"
|
||||
#include "../details/log_msg.h"
|
||||
#include "sink.h"
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <syslog.h>
|
||||
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
namespace spdlog { namespace sinks {
|
||||
/**
|
||||
* Sink that write to syslog using the `syscall()` library call.
|
||||
*
|
||||
@ -30,8 +26,8 @@ class syslog_sink : public sink
|
||||
{
|
||||
public:
|
||||
//
|
||||
syslog_sink(const std::string& ident = "", int syslog_option=0, int syslog_facility=LOG_USER):
|
||||
_ident(ident)
|
||||
syslog_sink(const std::string &ident = "", int syslog_option = 0, int syslog_facility = LOG_USER)
|
||||
: _ident(ident)
|
||||
{
|
||||
_priorities[static_cast<size_t>(level::trace)] = LOG_DEBUG;
|
||||
_priorities[static_cast<size_t>(level::debug)] = LOG_DEBUG;
|
||||
@ -58,10 +54,7 @@ public:
|
||||
::syslog(syslog_prio_from_level(msg), "%s", msg.raw.str().c_str());
|
||||
}
|
||||
|
||||
void flush() override
|
||||
{
|
||||
}
|
||||
|
||||
void flush() override {}
|
||||
|
||||
private:
|
||||
std::array<int, 7> _priorities;
|
||||
@ -76,7 +69,6 @@ private:
|
||||
return _priorities[static_cast<size_t>(msg.level)];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
||||
#endif
|
||||
|
@ -5,24 +5,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base_sink.h"
|
||||
#include "../details/null_mutex.h"
|
||||
#include "../common.h"
|
||||
#include "../details/null_mutex.h"
|
||||
#include "base_sink.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <wincon.h>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
namespace spdlog { namespace sinks {
|
||||
/*
|
||||
* Windows color console sink. Uses WriteConsoleA to write to the console with colors
|
||||
*/
|
||||
template <class Mutex>
|
||||
class wincolor_sink : public base_sink<Mutex>
|
||||
template <class Mutex> class wincolor_sink : public base_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
const WORD BOLD = FOREGROUND_INTENSITY;
|
||||
@ -31,7 +27,8 @@ public:
|
||||
const WORD WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
|
||||
const WORD YELLOW = FOREGROUND_RED | FOREGROUND_GREEN;
|
||||
|
||||
wincolor_sink(HANDLE std_handle): out_handle_(std_handle)
|
||||
wincolor_sink(HANDLE std_handle)
|
||||
: out_handle_(std_handle)
|
||||
{
|
||||
colors_[level::trace] = CYAN;
|
||||
colors_[level::debug] = CYAN;
|
||||
@ -92,12 +89,13 @@ private:
|
||||
//
|
||||
// windows color console to stdout
|
||||
//
|
||||
template <class Mutex>
|
||||
class wincolor_stdout_sink : public wincolor_sink<Mutex>
|
||||
template <class Mutex> class wincolor_stdout_sink : public wincolor_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
wincolor_stdout_sink() : wincolor_sink<Mutex>(GetStdHandle(STD_OUTPUT_HANDLE))
|
||||
{}
|
||||
wincolor_stdout_sink()
|
||||
: wincolor_sink<Mutex>(GetStdHandle(STD_OUTPUT_HANDLE))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using wincolor_stdout_sink_mt = wincolor_stdout_sink<std::mutex>;
|
||||
@ -106,16 +104,16 @@ using wincolor_stdout_sink_st = wincolor_stdout_sink<details::null_mutex>;
|
||||
//
|
||||
// windows color console to stderr
|
||||
//
|
||||
template <class Mutex>
|
||||
class wincolor_stderr_sink : public wincolor_sink<Mutex>
|
||||
template <class Mutex> class wincolor_stderr_sink : public wincolor_sink<Mutex>
|
||||
{
|
||||
public:
|
||||
wincolor_stderr_sink() : wincolor_sink<Mutex>(GetStdHandle(STD_ERROR_HANDLE))
|
||||
{}
|
||||
wincolor_stderr_sink()
|
||||
: wincolor_sink<Mutex>(GetStdHandle(STD_ERROR_HANDLE))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using wincolor_stderr_sink_mt = wincolor_stderr_sink<std::mutex>;
|
||||
using wincolor_stderr_sink_st = wincolor_stderr_sink<details::null_mutex>;
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
@ -9,21 +9,16 @@
|
||||
|
||||
#include "msvc_sink.h"
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace sinks
|
||||
{
|
||||
namespace spdlog { namespace sinks {
|
||||
|
||||
/*
|
||||
* Windows debug sink (logging using OutputDebugStringA, synonym for msvc_sink)
|
||||
*/
|
||||
template <class Mutex>
|
||||
using windebug_sink = msvc_sink<Mutex>;
|
||||
template <class Mutex> using windebug_sink = msvc_sink<Mutex>;
|
||||
|
||||
using windebug_sink_mt = msvc_sink_mt;
|
||||
using windebug_sink_st = msvc_sink_st;
|
||||
|
||||
}
|
||||
}
|
||||
}} // namespace spdlog::sinks
|
||||
|
||||
#endif
|
||||
|
@ -7,17 +7,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "common.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace spdlog
|
||||
{
|
||||
namespace spdlog {
|
||||
|
||||
//
|
||||
// Return an existing logger or nullptr if a logger with such name doesn't exist.
|
||||
@ -25,7 +23,6 @@ namespace spdlog
|
||||
//
|
||||
std::shared_ptr<logger> get(const std::string &name);
|
||||
|
||||
|
||||
//
|
||||
// Set global formatting
|
||||
// example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v");
|
||||
@ -64,12 +61,14 @@ void set_error_handler(log_err_handler handler);
|
||||
// worker_teardown_cb (optional):
|
||||
// callback function that will be called in worker thread upon exit
|
||||
//
|
||||
void set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function<void()>& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::function<void()>& worker_teardown_cb = nullptr);
|
||||
void set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
|
||||
const std::function<void()> &worker_warmup_cb = nullptr,
|
||||
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
|
||||
const std::function<void()> &worker_teardown_cb = nullptr);
|
||||
|
||||
// Turn off async mode
|
||||
void set_sync_mode();
|
||||
|
||||
|
||||
//
|
||||
// Create and register multi/single threaded basic file logger.
|
||||
// Basic logger simply writes to given file without any limitations or rotations.
|
||||
@ -80,8 +79,10 @@ std::shared_ptr<logger> basic_logger_st(const std::string& logger_name, const fi
|
||||
//
|
||||
// Create and register multi/single threaded rotating file logger
|
||||
//
|
||||
std::shared_ptr<logger> rotating_logger_mt(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files);
|
||||
std::shared_ptr<logger> rotating_logger_st(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files);
|
||||
std::shared_ptr<logger> rotating_logger_mt(
|
||||
const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files);
|
||||
std::shared_ptr<logger> rotating_logger_st(
|
||||
const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files);
|
||||
|
||||
//
|
||||
// Create file logger which creates new file on the given time (default in midnight):
|
||||
@ -104,12 +105,12 @@ std::shared_ptr<logger> stdout_color_st(const std::string& logger_name);
|
||||
std::shared_ptr<logger> stderr_color_mt(const std::string &logger_name);
|
||||
std::shared_ptr<logger> stderr_color_st(const std::string &logger_name);
|
||||
|
||||
|
||||
//
|
||||
// Create and register a syslog logger
|
||||
//
|
||||
#ifdef SPDLOG_ENABLE_SYSLOG
|
||||
std::shared_ptr<logger> syslog_logger(const std::string& logger_name, const std::string& ident = "", int syslog_option = 0, int syslog_facilty = (1<<3));
|
||||
std::shared_ptr<logger> syslog_logger(
|
||||
const std::string &logger_name, const std::string &ident = "", int syslog_option = 0, int syslog_facilty = (1 << 3));
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
@ -121,23 +122,32 @@ std::shared_ptr<logger> create(const std::string& logger_name, const sink_ptr& s
|
||||
|
||||
// Create and register a logger with multiple sinks
|
||||
std::shared_ptr<logger> create(const std::string &logger_name, sinks_init_list sinks);
|
||||
template<class It>
|
||||
std::shared_ptr<logger> create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end);
|
||||
|
||||
template <class It> std::shared_ptr<logger> create(const std::string &logger_name, const It &sinks_begin, const It &sinks_end);
|
||||
|
||||
// Create and register a logger with templated sink type
|
||||
// Example:
|
||||
// spdlog::create<daily_file_sink_st>("mylog", "dailylog_filename");
|
||||
template <typename Sink, typename... Args>
|
||||
std::shared_ptr<spdlog::logger> create(const std::string& logger_name, Args... args);
|
||||
template <typename Sink, typename... Args> std::shared_ptr<spdlog::logger> create(const std::string &logger_name, Args... args);
|
||||
|
||||
// Create and register an async logger with a single sink
|
||||
std::shared_ptr<logger> create_async(const std::string& logger_name, const sink_ptr& sink, size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function<void()>& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::function<void()>& worker_teardown_cb = nullptr);
|
||||
std::shared_ptr<logger> create_async(const std::string &logger_name, const sink_ptr &sink, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
|
||||
const std::function<void()> &worker_warmup_cb = nullptr,
|
||||
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
|
||||
const std::function<void()> &worker_teardown_cb = nullptr);
|
||||
|
||||
// Create and register an async logger with multiple sinks
|
||||
std::shared_ptr<logger> create_async(const std::string& logger_name, sinks_init_list sinks, size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function<void()>& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::function<void()>& worker_teardown_cb = nullptr);
|
||||
std::shared_ptr<logger> create_async(const std::string &logger_name, sinks_init_list sinks, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
|
||||
const std::function<void()> &worker_warmup_cb = nullptr,
|
||||
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
|
||||
const std::function<void()> &worker_teardown_cb = nullptr);
|
||||
template <class It>
|
||||
std::shared_ptr<logger> create_async(const std::string& logger_name, const It& sinks_begin, const It& sinks_end, size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function<void()>& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::function<void()>& worker_teardown_cb = nullptr);
|
||||
std::shared_ptr<logger> create_async(const std::string &logger_name, const It &sinks_begin, const It &sinks_end, size_t queue_size,
|
||||
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
|
||||
const std::function<void()> &worker_warmup_cb = nullptr,
|
||||
const std::chrono::milliseconds &flush_interval_ms = std::chrono::milliseconds::zero(),
|
||||
const std::function<void()> &worker_teardown_cb = nullptr);
|
||||
|
||||
// Register the given logger with the given name
|
||||
void register_logger(std::shared_ptr<logger> logger);
|
||||
@ -153,7 +163,6 @@ void drop(const std::string &name);
|
||||
// Drop all references from the registry
|
||||
void drop_all();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Trace & Debug can be switched on/off at compile time for zero cost debug statements.
|
||||
@ -185,6 +194,6 @@ void drop_all();
|
||||
#define SPDLOG_DEBUG(logger, ...) (void)0
|
||||
#endif
|
||||
|
||||
}
|
||||
} // namespace spdlog
|
||||
|
||||
#include "details/spdlog_impl.h"
|
||||
|
@ -11,7 +11,6 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Under Linux, the much faster CLOCK_REALTIME_COARSE clock can be used.
|
||||
// This clock is less accurate - can be off by dozens of millis - depending on the kernel HZ.
|
||||
@ -20,7 +19,6 @@
|
||||
// #define SPDLOG_CLOCK_COARSE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment if date/time logging is not needed and never appear in the log pattern.
|
||||
// This will prevent spdlog from querying the clock on each log call.
|
||||
@ -31,7 +29,6 @@
|
||||
// #define SPDLOG_NO_DATETIME
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment if thread id logging is not needed (i.e. no %t in the log pattern).
|
||||
// This will prevent spdlog from querying the thread id on each log call.
|
||||
@ -41,7 +38,6 @@
|
||||
// #define SPDLOG_NO_THREAD_ID
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to prevent spdlog from caching thread ids in thread local storage.
|
||||
// By default spdlog saves thread ids in tls to gain a few micros for each call.
|
||||
@ -51,7 +47,6 @@
|
||||
// #define SPDLOG_DISABLE_TID_CACHING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment if logger name logging is not needed.
|
||||
// This will prevent spdlog from copying the logger name on each log call.
|
||||
@ -66,7 +61,6 @@
|
||||
// #define SPDLOG_TRACE_ON
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to avoid locking in the registry operations (spdlog::get(), spdlog::drop() spdlog::register()).
|
||||
// Use only if your code never modifies concurrently the registry.
|
||||
@ -75,7 +69,6 @@
|
||||
// #define SPDLOG_NO_REGISTRY_MUTEX
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to avoid spdlog's usage of atomic log levels
|
||||
// Use only if your code never modifies a logger's log levels concurrently by different threads.
|
||||
@ -83,21 +76,18 @@
|
||||
// #define SPDLOG_NO_ATOMIC_LEVELS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to enable usage of wchar_t for file names on Windows.
|
||||
//
|
||||
// #define SPDLOG_WCHAR_FILENAMES
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to override default eol ("\n" or "\r\n" under Linux/Windows)
|
||||
//
|
||||
// #define SPDLOG_EOL ";-)\n"
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to use your own copy of the fmt library instead of spdlog's copy.
|
||||
// In this case spdlog will try to include <fmt/format.h> so set your -I flag accordingly.
|
||||
@ -105,7 +95,6 @@
|
||||
// #define SPDLOG_FMT_EXTERNAL
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to use printf-style messages in your logs instead of the usual
|
||||
// format-style used by default.
|
||||
@ -113,28 +102,24 @@
|
||||
// #define SPDLOG_FMT_PRINTF
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to enable syslog (disabled by default)
|
||||
//
|
||||
// #define SPDLOG_ENABLE_SYSLOG
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to enable wchar_t support (convert to utf8)
|
||||
//
|
||||
// #define SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to prevent child processes from inheriting log file descriptors
|
||||
//
|
||||
// #define SPDLOG_PREVENT_CHILD_FD
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment if your compiler doesn't support the "final" keyword.
|
||||
// The final keyword allows more optimizations in release
|
||||
@ -144,7 +129,6 @@
|
||||
// #define SPDLOG_NO_FINAL
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to enable message counting feature.
|
||||
// Use the %i in the logger pattern to display log message sequence id.
|
||||
@ -152,7 +136,6 @@
|
||||
// #define SPDLOG_ENABLE_MESSAGE_COUNTER
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to customize level names (e.g. "MT TRACE")
|
||||
//
|
||||
|
@ -5,9 +5,6 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
|
||||
|
||||
class failing_sink : public spdlog::sinks::sink
|
||||
{
|
||||
void log(const spdlog::details::log_msg &msg) override
|
||||
@ -15,8 +12,7 @@ class failing_sink: public spdlog::sinks::sink
|
||||
throw std::runtime_error("some error happened during log");
|
||||
}
|
||||
|
||||
void flush() override
|
||||
{}
|
||||
void flush() override {}
|
||||
};
|
||||
|
||||
TEST_CASE("default_error_handler", "[errors]]")
|
||||
@ -39,21 +35,16 @@ TEST_CASE("default_error_handler", "[errors]]")
|
||||
REQUIRE(count_lines(filename) == 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct custom_ex
|
||||
{};
|
||||
{
|
||||
};
|
||||
TEST_CASE("custom_error_handler", "[errors]]")
|
||||
{
|
||||
prepare_logdir();
|
||||
std::string filename = "logs/simple_log.txt";
|
||||
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
|
||||
logger->flush_on(spdlog::level::info);
|
||||
logger->set_error_handler([=](const std::string& msg)
|
||||
{
|
||||
throw custom_ex();
|
||||
});
|
||||
logger->set_error_handler([=](const std::string &msg) { throw custom_ex(); });
|
||||
logger->info("Good message #1");
|
||||
#if !defined(SPDLOG_FMT_PRINTF)
|
||||
REQUIRE_THROWS_AS(logger->info("Bad format msg {} {}", "xxx"), custom_ex);
|
||||
@ -68,10 +59,7 @@ TEST_CASE("default_error_handler2", "[errors]]")
|
||||
{
|
||||
|
||||
auto logger = spdlog::create<failing_sink>("failed_logger");
|
||||
logger->set_error_handler([=](const std::string& msg)
|
||||
{
|
||||
throw custom_ex();
|
||||
});
|
||||
logger->set_error_handler([=](const std::string &msg) { throw custom_ex(); });
|
||||
REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
|
||||
}
|
||||
|
||||
@ -83,10 +71,10 @@ TEST_CASE("async_error_handler", "[errors]]")
|
||||
std::string filename = "logs/simple_async_log.txt";
|
||||
{
|
||||
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
|
||||
logger->set_error_handler([=](const std::string& msg)
|
||||
{
|
||||
logger->set_error_handler([=](const std::string &msg) {
|
||||
std::ofstream ofs("logs/custom_err.txt");
|
||||
if (!ofs) throw std::runtime_error("Failed open logs/custom_err.txt");
|
||||
if (!ofs)
|
||||
throw std::runtime_error("Failed open logs/custom_err.txt");
|
||||
ofs << err_msg;
|
||||
});
|
||||
logger->info("Good message #1");
|
||||
@ -111,10 +99,10 @@ TEST_CASE("async_error_handler2", "[errors]]")
|
||||
spdlog::set_async_mode(128);
|
||||
{
|
||||
auto logger = spdlog::create<failing_sink>("failed_logger");
|
||||
logger->set_error_handler([=](const std::string& msg)
|
||||
{
|
||||
logger->set_error_handler([=](const std::string &msg) {
|
||||
std::ofstream ofs("logs/custom_err2.txt");
|
||||
if (!ofs) throw std::runtime_error("Failed open logs/custom_err2.txt");
|
||||
if (!ofs)
|
||||
throw std::runtime_error("Failed open logs/custom_err2.txt");
|
||||
ofs << err_msg;
|
||||
});
|
||||
logger->info("Hello failure");
|
||||
|
@ -3,8 +3,8 @@
|
||||
*/
|
||||
#include "includes.h"
|
||||
|
||||
using spdlog::details::log_msg;
|
||||
using spdlog::details::file_helper;
|
||||
using spdlog::details::log_msg;
|
||||
|
||||
static const std::string target_filename = "logs/file_helper_test.txt";
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
*/
|
||||
#include "includes.h"
|
||||
|
||||
|
||||
TEST_CASE("simple_file_logger", "[simple_logger]]")
|
||||
{
|
||||
prepare_logdir();
|
||||
@ -24,7 +23,6 @@ TEST_CASE("simple_file_logger", "[simple_logger]]")
|
||||
REQUIRE(count_lines(filename) == 2);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("flush_on", "[flush_on]]")
|
||||
{
|
||||
prepare_logdir();
|
||||
@ -69,7 +67,6 @@ TEST_CASE("rotating_file_logger1", "[rotating_logger]]")
|
||||
REQUIRE(count_lines(filename) == 10);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("rotating_file_logger2", "[rotating_logger]]")
|
||||
{
|
||||
prepare_logdir();
|
||||
@ -96,7 +93,6 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]]")
|
||||
REQUIRE(get_filesize(filename1) <= 1024);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("daily_logger", "[daily_logger]]")
|
||||
{
|
||||
prepare_logdir();
|
||||
@ -121,12 +117,9 @@ TEST_CASE("daily_logger", "[daily_logger]]")
|
||||
REQUIRE(count_lines(filename) == 10);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("daily_logger with dateonly calculator", "[daily_logger_dateonly]]")
|
||||
{
|
||||
using sink_type = spdlog::sinks::daily_file_sink<
|
||||
std::mutex,
|
||||
spdlog::sinks::dateonly_daily_file_name_calculator>;
|
||||
using sink_type = spdlog::sinks::daily_file_sink<std::mutex, spdlog::sinks::dateonly_daily_file_name_calculator>;
|
||||
|
||||
prepare_logdir();
|
||||
// calculate filename (time based)
|
||||
@ -162,9 +155,7 @@ struct custom_daily_file_name_calculator
|
||||
|
||||
TEST_CASE("daily_logger with custom calculator", "[daily_logger_custom]]")
|
||||
{
|
||||
using sink_type = spdlog::sinks::daily_file_sink<
|
||||
std::mutex,
|
||||
custom_daily_file_name_calculator>;
|
||||
using sink_type = spdlog::sinks::daily_file_sink<std::mutex, custom_daily_file_name_calculator>;
|
||||
|
||||
prepare_logdir();
|
||||
// calculate filename (time based)
|
||||
@ -188,7 +179,6 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger_custom]]")
|
||||
REQUIRE(count_lines(filename) == 10);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* File name calculations
|
||||
*/
|
||||
@ -211,10 +201,6 @@ TEST_CASE("rotating_file_sink::calc_filename3", "[rotating_file_sink]]")
|
||||
REQUIRE(filename == "rotated.txt");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// regex supported only from gcc 4.9 and above
|
||||
#if defined(_MSC_VER) || !(__GNUC__ <= 4 && __GNUC_MINOR__ < 9)
|
||||
#include <regex>
|
||||
|
@ -1,18 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
#include "catch.hpp"
|
||||
#include "utils.h"
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#define SPDLOG_TRACE_ON
|
||||
#define SPDLOG_DEBUG_ON
|
||||
|
||||
#include "../include/spdlog/spdlog.h"
|
||||
#include "../include/spdlog/sinks/null_sink.h"
|
||||
#include "../include/spdlog/sinks/ostream_sink.h"
|
||||
|
||||
#include "../include/spdlog/spdlog.h"
|
||||
|
@ -12,8 +12,8 @@ TEST_CASE("register_drop", "[registry]")
|
||||
REQUIRE_THROWS_AS(spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name), spdlog::spdlog_ex);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("explicit register" "[registry]")
|
||||
TEST_CASE("explicit register"
|
||||
"[registry]")
|
||||
{
|
||||
spdlog::drop_all();
|
||||
auto logger = std::make_shared<spdlog::logger>(tested_logger_name, std::make_shared<spdlog::sinks::null_sink_st>());
|
||||
@ -23,7 +23,8 @@ TEST_CASE("explicit register" "[registry]")
|
||||
REQUIRE_THROWS_AS(spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name), spdlog::spdlog_ex);
|
||||
}
|
||||
|
||||
TEST_CASE("apply_all" "[registry]")
|
||||
TEST_CASE("apply_all"
|
||||
"[registry]")
|
||||
{
|
||||
spdlog::drop_all();
|
||||
auto logger = std::make_shared<spdlog::logger>(tested_logger_name, std::make_shared<spdlog::sinks::null_sink_st>());
|
||||
@ -32,26 +33,20 @@ TEST_CASE("apply_all" "[registry]")
|
||||
spdlog::register_logger(logger2);
|
||||
|
||||
int counter = 0;
|
||||
spdlog::apply_all([&counter](std::shared_ptr<spdlog::logger> l)
|
||||
{
|
||||
counter++;
|
||||
});
|
||||
spdlog::apply_all([&counter](std::shared_ptr<spdlog::logger> l) { counter++; });
|
||||
REQUIRE(counter == 2);
|
||||
|
||||
counter = 0;
|
||||
spdlog::drop(tested_logger_name2);
|
||||
spdlog::apply_all([&counter](std::shared_ptr<spdlog::logger> l)
|
||||
{
|
||||
spdlog::apply_all([&counter](std::shared_ptr<spdlog::logger> l) {
|
||||
REQUIRE(l->name() == tested_logger_name);
|
||||
counter++;
|
||||
}
|
||||
);
|
||||
});
|
||||
REQUIRE(counter == 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("drop" "[registry]")
|
||||
TEST_CASE("drop"
|
||||
"[registry]")
|
||||
{
|
||||
spdlog::drop_all();
|
||||
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
||||
@ -59,7 +54,8 @@ TEST_CASE("drop" "[registry]")
|
||||
REQUIRE_FALSE(spdlog::get(tested_logger_name));
|
||||
}
|
||||
|
||||
TEST_CASE("drop_all" "[registry]")
|
||||
TEST_CASE("drop_all"
|
||||
"[registry]")
|
||||
{
|
||||
spdlog::drop_all();
|
||||
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
||||
@ -69,8 +65,8 @@ TEST_CASE("drop_all" "[registry]")
|
||||
REQUIRE_FALSE(spdlog::get(tested_logger_name));
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("drop non existing" "[registry]")
|
||||
TEST_CASE("drop non existing"
|
||||
"[registry]")
|
||||
{
|
||||
spdlog::drop_all();
|
||||
spdlog::create<spdlog::sinks::null_sink_mt>(tested_logger_name);
|
||||
@ -79,6 +75,3 @@ TEST_CASE("drop non existing" "[registry]")
|
||||
REQUIRE(spdlog::get(tested_logger_name));
|
||||
spdlog::drop_all();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -22,7 +22,6 @@ TEST_CASE("debug and trace w/o format string", "[macros]]")
|
||||
REQUIRE(count_lines(filename) == 2);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("debug and trace with format strings", "[macros]]")
|
||||
{
|
||||
prepare_logdir();
|
||||
@ -47,4 +46,3 @@ TEST_CASE("debug and trace with format strings", "[macros]]")
|
||||
REQUIRE(ends_with(file_contents(filename), "Test message 222\n"));
|
||||
REQUIRE(count_lines(filename) == 2);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,8 @@ static std::string log_to_str(const std::string& msg, const std::shared_ptr<spdl
|
||||
auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss);
|
||||
spdlog::logger oss_logger("pattern_tester", oss_sink);
|
||||
oss_logger.set_level(spdlog::level::info);
|
||||
if (formatter) oss_logger.set_formatter(formatter);
|
||||
if (formatter)
|
||||
oss_logger.set_formatter(formatter);
|
||||
oss_logger.info(msg);
|
||||
return oss.str();
|
||||
}
|
||||
@ -56,6 +57,7 @@ TEST_CASE("date MM/DD/YY ", "[pattern_formatter]")
|
||||
auto formatter = std::make_shared<spdlog::pattern_formatter>("%D %v", spdlog::pattern_time_type::local, "\n");
|
||||
auto now_tm = spdlog::details::os::localtime();
|
||||
std::stringstream oss;
|
||||
oss << std::setfill('0') << std::setw(2) << now_tm.tm_mon + 1 << "/" << std::setw(2) << now_tm.tm_mday << "/" << std::setw(2) << (now_tm.tm_year + 1900) % 1000 << " Some message\n";
|
||||
oss << std::setfill('0') << std::setw(2) << now_tm.tm_mon + 1 << "/" << std::setw(2) << now_tm.tm_mday << "/" << std::setw(2)
|
||||
<< (now_tm.tm_year + 1900) % 1000 << " Some message\n";
|
||||
REQUIRE(log_to_str("Some message", formatter) == oss.str());
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "includes.h"
|
||||
|
||||
|
||||
void prepare_logdir()
|
||||
{
|
||||
spdlog::drop_all();
|
||||
@ -14,15 +13,12 @@ void prepare_logdir()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
std::string file_contents(const std::string &filename)
|
||||
{
|
||||
std::ifstream ifs(filename);
|
||||
if (!ifs)
|
||||
throw std::runtime_error("Failed open file ");
|
||||
return std::string((std::istreambuf_iterator<char>(ifs)),
|
||||
(std::istreambuf_iterator<char>()));
|
||||
|
||||
return std::string((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
||||
}
|
||||
|
||||
std::size_t count_lines(const std::string &filename)
|
||||
@ -47,10 +43,10 @@ std::size_t get_filesize(const std::string& filename)
|
||||
return static_cast<std::size_t>(ifs.tellg());
|
||||
}
|
||||
|
||||
|
||||
// source: https://stackoverflow.com/a/2072890/192001
|
||||
bool ends_with(std::string const &value, std::string const &ending)
|
||||
{
|
||||
if (ending.size() > value.size()) return false;
|
||||
if (ending.size() > value.size())
|
||||
return false;
|
||||
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
std::size_t count_lines(const std::string &filename);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user