1
0
mirror of https://github.com/gabime/spdlog.git synced 2025-04-01 02:42:41 +08:00
This commit is contained in:
gabime 2016-10-12 23:08:44 +03:00
parent 0cfdad4d0b
commit f14d1c002b
11 changed files with 236 additions and 236 deletions

View File

@ -5,7 +5,7 @@
void CrusherLoop() void CrusherLoop()
{ {
size_t counter = 0; size_t counter = 0;
while (true) while (true)
{ {
LOGF(INFO, "Some text to crush you machine. thread:"); LOGF(INFO, "Some text to crush you machine. thread:");
@ -24,12 +24,12 @@ int main(int argc, char** argv)
char c; char c;
std::cin >> c; std::cin >> c;
if (toupper( c ) != 'Y') if (toupper( c ) != 'Y')
return 0; return 0;
auto worker = g3::LogWorker::createLogWorker(); auto worker = g3::LogWorker::createLogWorker();
auto handle= worker->addDefaultLogger(argv[0], "g3log.txt"); auto handle= worker->addDefaultLogger(argv[0], "g3log.txt");
g3::initializeLogging(worker.get()); g3::initializeLogging(worker.get());
CrusherLoop(); CrusherLoop();
return 0; return 0;
} }

View File

@ -22,10 +22,10 @@ int main(int, char*[])
{ {
try try
{ {
// Console logger with color // Console logger with color
auto console = spd::stdout_color_mt("console"); auto console = spd::stdout_color_mt("console");
console->info("Welcome to spdlog!"); console->info("Welcome to spdlog!");
console->error("Some error message with arg{}..", 1); console->error("Some error message with arg{}..", 1);
// Formatting examples // Formatting examples
console->warn("Easy padding in numbers like {:08d}", 12); console->warn("Easy padding in numbers like {:08d}", 12);
@ -58,11 +58,11 @@ int main(int, char*[])
rotating_logger->info("This is another message with custom format"); rotating_logger->info("This is another message with custom format");
// Runtime log levels // Runtime log levels
spd::set_level(spd::level::info); //Set global log level to info spd::set_level(spd::level::info); //Set global log level to info
console->debug("This message shold not be displayed!"); console->debug("This message shold not be displayed!");
console->set_level(spd::level::debug); // Set specific logger's log level console->set_level(spd::level::debug); // Set specific logger's log level
console->debug("This message shold be displayed.."); console->debug("This message shold be displayed..");
// Compile time log levels // Compile time log levels
// define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON // define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON

View File

@ -34,50 +34,50 @@
inline void spdlog::register_logger(std::shared_ptr<logger> logger) inline void spdlog::register_logger(std::shared_ptr<logger> logger)
{ {
return details::registry::instance().register_logger(logger); return details::registry::instance().register_logger(logger);
} }
inline std::shared_ptr<spdlog::logger> spdlog::get(const std::string& name) inline std::shared_ptr<spdlog::logger> spdlog::get(const std::string& name)
{ {
return details::registry::instance().get(name); return details::registry::instance().get(name);
} }
inline void spdlog::drop(const std::string &name) inline void spdlog::drop(const std::string &name)
{ {
details::registry::instance().drop(name); details::registry::instance().drop(name);
} }
// Create multi/single threaded simple file logger // Create multi/single threaded simple file logger
inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_mt(const std::string& logger_name, const filename_t& filename, bool truncate) inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_mt(const std::string& logger_name, const filename_t& filename, bool truncate)
{ {
return create<spdlog::sinks::simple_file_sink_mt>(logger_name, filename, truncate); return create<spdlog::sinks::simple_file_sink_mt>(logger_name, filename, truncate);
} }
inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_st(const std::string& logger_name, const filename_t& filename, bool truncate) inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_st(const std::string& logger_name, const filename_t& filename, bool truncate)
{ {
return create<spdlog::sinks::simple_file_sink_st>(logger_name, filename, truncate); return create<spdlog::sinks::simple_file_sink_st>(logger_name, filename, truncate);
} }
// Create multi/single threaded rotating file logger // Create multi/single threaded rotating file logger
inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_mt(const std::string& logger_name, const 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, SPDLOG_FILENAME_T("txt"), max_file_size, max_files); return create<spdlog::sinks::rotating_file_sink_mt>(logger_name, filename, SPDLOG_FILENAME_T("txt"), 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, SPDLOG_FILENAME_T("txt"), max_file_size, max_files); return create<spdlog::sinks::rotating_file_sink_st>(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files);
} }
// Create file logger which creates new file at midnight): // Create file logger which creates new file at midnight):
inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_mt(const std::string& logger_name, const 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, SPDLOG_FILENAME_T("txt"), hour, minute); return create<spdlog::sinks::daily_file_sink_mt>(logger_name, filename, SPDLOG_FILENAME_T("txt"), 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, SPDLOG_FILENAME_T("txt"), hour, minute); return create<spdlog::sinks::daily_file_sink_st>(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute);
} }
@ -86,22 +86,22 @@ inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_st(const std::string
// //
inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt(const std::string& logger_name)
{ {
return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_mt::instance()); return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_mt::instance());
} }
inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st(const std::string& logger_name)
{ {
return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_st::instance()); return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_st::instance());
} }
inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt(const std::string& logger_name)
{ {
return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_mt::instance()); return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_mt::instance());
} }
inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::string& logger_name)
{ {
return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_st::instance()); return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_st::instance());
} }
// //
@ -110,53 +110,53 @@ inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::strin
#ifdef _WIN32 #ifdef _WIN32
inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string& logger_name)
{ {
auto sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_mt>(); auto sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_mt>();
return spdlog::details::registry::instance().create(logger_name, sink); return spdlog::details::registry::instance().create(logger_name, sink);
} }
inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_st(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_st(const std::string& logger_name)
{ {
auto sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_st>(); auto sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_st>();
return spdlog::details::registry::instance().create(logger_name, sink); return spdlog::details::registry::instance().create(logger_name, sink);
} }
inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string& logger_name)
{ {
auto sink = std::make_shared<spdlog::sinks::wincolor_stderr_sink_mt>(); auto sink = std::make_shared<spdlog::sinks::wincolor_stderr_sink_mt>();
return spdlog::details::registry::instance().create(logger_name, sink); return spdlog::details::registry::instance().create(logger_name, sink);
} }
inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string& logger_name) 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>(); auto sink = std::make_shared<spdlog::sinks::wincolor_stderr_sink_st>();
return spdlog::details::registry::instance().create(logger_name, sink); return spdlog::details::registry::instance().create(logger_name, sink);
} }
#else //ansi terminal colors #else //ansi terminal colors
inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string& logger_name)
{ {
auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stdout_sink_mt::instance()); auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stdout_sink_mt::instance());
return spdlog::details::registry::instance().create(logger_name, sink); return spdlog::details::registry::instance().create(logger_name, sink);
} }
inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_st(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_st(const std::string& logger_name)
{ {
auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stdout_sink_st::instance()); auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stdout_sink_st::instance());
return spdlog::details::registry::instance().create(logger_name, sink); return spdlog::details::registry::instance().create(logger_name, sink);
} }
inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string& logger_name)
{ {
auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stderr_sink_mt::instance()); auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stderr_sink_mt::instance());
return spdlog::details::registry::instance().create(logger_name, sink); return spdlog::details::registry::instance().create(logger_name, sink);
} }
inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string& logger_name)
{ {
auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stderr_sink_st::instance()); auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stderr_sink_st::instance());
return spdlog::details::registry::instance().create(logger_name, sink); return spdlog::details::registry::instance().create(logger_name, sink);
} }
#endif #endif
@ -164,82 +164,82 @@ inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string
// Create syslog logger // Create syslog logger
inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option) inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option)
{ {
return create<spdlog::sinks::syslog_sink>(logger_name, syslog_ident, syslog_option); return create<spdlog::sinks::syslog_sink>(logger_name, syslog_ident, syslog_option);
} }
#endif #endif
#ifdef __ANDROID__ #ifdef __ANDROID__
inline std::shared_ptr<spdlog::logger> spdlog::android_logger(const std::string& logger_name, const std::string& tag) inline std::shared_ptr<spdlog::logger> spdlog::android_logger(const std::string& logger_name, const std::string& tag)
{ {
return create<spdlog::sinks::android_sink>(logger_name, tag); return create<spdlog::sinks::android_sink>(logger_name, tag);
} }
#endif #endif
// Create and register a logger a single sink // Create and register a logger a single sink
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const spdlog::sink_ptr& sink) inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const spdlog::sink_ptr& sink)
{ {
return details::registry::instance().create(logger_name, sink); return details::registry::instance().create(logger_name, sink);
} }
//Create logger with multiple sinks //Create logger with multiple sinks
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks) inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks)
{ {
return details::registry::instance().create(logger_name, sinks); return details::registry::instance().create(logger_name, sinks);
} }
template <typename Sink, typename... Args> template <typename Sink, typename... Args>
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, Args... args) inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, Args... args)
{ {
sink_ptr sink = std::make_shared<Sink>(args...); sink_ptr sink = std::make_shared<Sink>(args...);
return details::registry::instance().create(logger_name, { sink }); return details::registry::instance().create(logger_name, { sink });
} }
template<class It> template<class It>
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end)
{ {
return details::registry::instance().create(logger_name, sinks_begin, sinks_end); return details::registry::instance().create(logger_name, sinks_begin, sinks_end);
} }
inline void spdlog::set_formatter(spdlog::formatter_ptr f) inline void spdlog::set_formatter(spdlog::formatter_ptr f)
{ {
details::registry::instance().formatter(f); details::registry::instance().formatter(f);
} }
inline void spdlog::set_pattern(const std::string& format_string) inline void spdlog::set_pattern(const std::string& format_string)
{ {
return details::registry::instance().set_pattern(format_string); return details::registry::instance().set_pattern(format_string);
} }
inline void spdlog::set_level(level::level_enum log_level) inline void spdlog::set_level(level::level_enum log_level)
{ {
return details::registry::instance().set_level(log_level); return details::registry::instance().set_level(log_level);
} }
inline void spdlog::set_error_handler(log_err_handler handler) inline void spdlog::set_error_handler(log_err_handler handler)
{ {
return details::registry::instance().set_error_handler(handler); return details::registry::instance().set_error_handler(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); details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb);
} }
inline void spdlog::set_sync_mode() inline void spdlog::set_sync_mode()
{ {
details::registry::instance().set_sync_mode(); details::registry::instance().set_sync_mode();
} }
inline void spdlog::apply_all(std::function<void(std::shared_ptr<logger>)> fun) inline void spdlog::apply_all(std::function<void(std::shared_ptr<logger>)> fun)
{ {
details::registry::instance().apply_all(fun); details::registry::instance().apply_all(fun);
} }
inline void spdlog::drop_all() inline void spdlog::drop_all()
{ {
details::registry::instance().drop_all(); details::registry::instance().drop_all();
} }

View File

@ -37,21 +37,21 @@ public:
{ {
_file_helper.flush(); _file_helper.flush();
} }
void set_force_flush(bool force_flush) void set_force_flush(bool force_flush)
{ {
_force_flush = force_flush; _force_flush = force_flush;
} }
protected: protected:
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
_file_helper.write(msg); _file_helper.write(msg);
if(_force_flush) if(_force_flush)
_file_helper.flush(); _file_helper.flush();
} }
private: private:
details::file_helper _file_helper; details::file_helper _file_helper;
bool _force_flush; bool _force_flush;
}; };
typedef simple_file_sink<std::mutex> simple_file_sink_mt; typedef simple_file_sink<std::mutex> simple_file_sink_mt;

View File

@ -14,64 +14,64 @@
namespace spdlog namespace spdlog
{ {
namespace sinks namespace sinks
{ {
template <class Mutex> template <class Mutex>
class stdout_sink: public base_sink<Mutex> class stdout_sink: public base_sink<Mutex>
{ {
using MyType = stdout_sink<Mutex>; using MyType = stdout_sink<Mutex>;
public: public:
stdout_sink() stdout_sink()
{} {}
static std::shared_ptr<MyType> instance() static std::shared_ptr<MyType> instance()
{ {
static std::shared_ptr<MyType> instance = std::make_shared<MyType>(); static std::shared_ptr<MyType> instance = std::make_shared<MyType>();
return instance; return instance;
} }
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), stdout); fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), stdout);
flush(); flush();
} }
void flush() override void flush() override
{ {
fflush(stdout); fflush(stdout);
} }
}; };
typedef stdout_sink<details::null_mutex> stdout_sink_st; typedef stdout_sink<details::null_mutex> stdout_sink_st;
typedef stdout_sink<std::mutex> stdout_sink_mt; typedef stdout_sink<std::mutex> stdout_sink_mt;
template <class Mutex> template <class Mutex>
class stderr_sink: public base_sink<Mutex> class stderr_sink: public base_sink<Mutex>
{ {
using MyType = stderr_sink<Mutex>; using MyType = stderr_sink<Mutex>;
public: public:
stderr_sink() stderr_sink()
{} {}
static std::shared_ptr<MyType> instance() static std::shared_ptr<MyType> instance()
{ {
static std::shared_ptr<MyType> instance = std::make_shared<MyType>(); static std::shared_ptr<MyType> instance = std::make_shared<MyType>();
return instance; return instance;
} }
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), stderr); fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), stderr);
flush(); flush();
} }
void flush() override void flush() override
{ {
fflush(stderr); fflush(stderr);
} }
}; };
typedef stderr_sink<std::mutex> stderr_sink_mt; typedef stderr_sink<std::mutex> stderr_sink_mt;
typedef stderr_sink<details::null_mutex> stderr_sink_st; typedef stderr_sink<details::null_mutex> stderr_sink_st;
} }
} }

View File

@ -16,101 +16,101 @@
namespace spdlog namespace spdlog
{ {
namespace sinks namespace sinks
{ {
/* /*
* Windows color console sink. Uses WriteConsoleA to write to the console with colors * Windows color console sink. Uses WriteConsoleA to write to the console with colors
*/ */
template<class Mutex> template<class Mutex>
class wincolor_sink: public base_sink<Mutex> class wincolor_sink: public base_sink<Mutex>
{ {
public: public:
const WORD BOLD = FOREGROUND_INTENSITY; const WORD BOLD = FOREGROUND_INTENSITY;
const WORD RED = FOREGROUND_RED; const WORD RED = FOREGROUND_RED;
const WORD CYAN = FOREGROUND_GREEN | FOREGROUND_BLUE; const WORD CYAN = FOREGROUND_GREEN | FOREGROUND_BLUE;
const WORD WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; const WORD WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
const WORD YELLOW = FOREGROUND_RED | FOREGROUND_GREEN; 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::trace] = CYAN;
colors_[level::debug] = CYAN; colors_[level::debug] = CYAN;
colors_[level::info] = WHITE | BOLD; colors_[level::info] = WHITE | BOLD;
colors_[level::warn] = YELLOW | BOLD; colors_[level::warn] = YELLOW | BOLD;
colors_[level::err] = RED | BOLD; // red bold colors_[level::err] = RED | BOLD; // red bold
colors_[level::critical] = BACKGROUND_RED | WHITE | BOLD; // white bold on red background colors_[level::critical] = BACKGROUND_RED | WHITE | BOLD; // white bold on red background
colors_[level::off] = 0; colors_[level::off] = 0;
} }
virtual ~wincolor_sink() virtual ~wincolor_sink()
{ {
flush(); flush();
} }
wincolor_sink(const wincolor_sink& other) = delete; wincolor_sink(const wincolor_sink& other) = delete;
wincolor_sink& operator=(const wincolor_sink& other) = delete; wincolor_sink& operator=(const wincolor_sink& other) = delete;
virtual void _sink_it(const details::log_msg& msg) override virtual void _sink_it(const details::log_msg& msg) override
{ {
auto color = colors_[msg.level]; auto color = colors_[msg.level];
auto orig_attribs = set_console_attribs(color); auto orig_attribs = set_console_attribs(color);
WriteConsoleA(out_handle_, msg.formatted.data(), msg.formatted.size(), nullptr, nullptr); WriteConsoleA(out_handle_, msg.formatted.data(), msg.formatted.size(), nullptr, nullptr);
SetConsoleTextAttribute(out_handle_, orig_attribs); //reset to orig colors SetConsoleTextAttribute(out_handle_, orig_attribs); //reset to orig colors
} }
virtual void flush() override virtual void flush() override
{ {
// windows console always flushed? // windows console always flushed?
} }
// change the color for the given level // change the color for the given level
void set_color(level::level_enum level, WORD color) void set_color(level::level_enum level, WORD color)
{ {
std::lock_guard<Mutex> lock(_mutex); std::lock_guard<Mutex> lock(_mutex);
colors_[level] = color; colors_[level] = color;
} }
private: private:
HANDLE out_handle_; HANDLE out_handle_;
std::map<level::level_enum, WORD> colors_; std::map<level::level_enum, WORD> colors_;
// set color and return the orig console attributes (for resetting later) // set color and return the orig console attributes (for resetting later)
WORD set_console_attribs(WORD attribs) WORD set_console_attribs(WORD attribs)
{ {
CONSOLE_SCREEN_BUFFER_INFO orig_buffer_info; CONSOLE_SCREEN_BUFFER_INFO orig_buffer_info;
GetConsoleScreenBufferInfo(out_handle_, &orig_buffer_info); GetConsoleScreenBufferInfo(out_handle_, &orig_buffer_info);
SetConsoleTextAttribute(out_handle_, attribs); SetConsoleTextAttribute(out_handle_, attribs);
return orig_buffer_info.wAttributes; //return orig attribs return orig_buffer_info.wAttributes; //return orig attribs
} }
}; };
// //
// windows color console to stdout // windows color console to stdout
// //
template<class Mutex> template<class Mutex>
class wincolor_stdout_sink: public wincolor_sink<Mutex> class wincolor_stdout_sink: public wincolor_sink<Mutex>
{ {
public: public:
wincolor_stdout_sink():wincolor_sink(GetStdHandle(STD_OUTPUT_HANDLE)) wincolor_stdout_sink():wincolor_sink(GetStdHandle(STD_OUTPUT_HANDLE))
{} {}
}; };
typedef wincolor_stdout_sink<std::mutex> wincolor_stdout_sink_mt; typedef wincolor_stdout_sink<std::mutex> wincolor_stdout_sink_mt;
typedef wincolor_stdout_sink<details::null_mutex> wincolor_stdout_sink_st; typedef wincolor_stdout_sink<details::null_mutex> wincolor_stdout_sink_st;
// //
// windows color console to stderr // windows color console to stderr
// //
template<class Mutex> template<class Mutex>
class wincolor_stderr_sink: public wincolor_sink<Mutex> class wincolor_stderr_sink: public wincolor_sink<Mutex>
{ {
public: public:
wincolor_stderr_sink():wincolor_sink(GetStdHandle(STD_ERROR_HANDLE)) wincolor_stderr_sink():wincolor_sink(GetStdHandle(STD_ERROR_HANDLE))
{} {}
}; };
typedef wincolor_stderr_sink<std::mutex> wincolor_stderr_sink_mt; typedef wincolor_stderr_sink<std::mutex> wincolor_stderr_sink_mt;
typedef wincolor_stderr_sink<details::null_mutex> wincolor_stderr_sink_st; typedef wincolor_stderr_sink<details::null_mutex> wincolor_stderr_sink_st;
} }
} }

View File

@ -28,7 +28,7 @@ TEST_CASE("custom_error_handler", "[errors]]")
prepare_logdir(); prepare_logdir();
std::string filename = "logs/simple_log.txt"; std::string filename = "logs/simple_log.txt";
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true); auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
logger->flush_on(spdlog::level::info); logger->flush_on(spdlog::level::info);
logger->set_error_handler([=](const std::string& msg) logger->set_error_handler([=](const std::string& msg)
{ {
throw custom_ex(); throw custom_ex();

View File

@ -12,7 +12,7 @@ static void write_with_helper(file_helper &helper, size_t howmany)
log_msg msg; log_msg msg;
msg.formatted << std::string(howmany, '1'); msg.formatted << std::string(howmany, '1');
helper.write(msg); helper.write(msg);
helper.flush(); helper.flush();
} }
@ -45,7 +45,7 @@ TEST_CASE("file_helper_exists", "[file_helper::file_exists()]]")
{ {
prepare_logdir(); prepare_logdir();
REQUIRE(!file_helper::file_exists(target_filename)); REQUIRE(!file_helper::file_exists(target_filename));
file_helper helper; file_helper helper;
helper.open(target_filename); helper.open(target_filename);
REQUIRE(file_helper::file_exists(target_filename)); REQUIRE(file_helper::file_exists(target_filename));
} }
@ -65,7 +65,7 @@ TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]]")
{ {
prepare_logdir(); prepare_logdir();
size_t expected_size = 14; size_t expected_size = 14;
file_helper helper; file_helper helper;
helper.open(target_filename); helper.open(target_filename);
write_with_helper(helper, expected_size); write_with_helper(helper, expected_size);
REQUIRE(helper.size() == expected_size); REQUIRE(helper.size() == expected_size);

View File

@ -23,21 +23,21 @@ TEST_CASE("simple_file_logger", "[simple_logger]]")
TEST_CASE("flush_on", "[flush_on]]") TEST_CASE("flush_on", "[flush_on]]")
{ {
prepare_logdir(); prepare_logdir();
std::string filename = "logs/simple_log.txt"; std::string filename = "logs/simple_log.txt";
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename); auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename);
logger->set_pattern("%v"); logger->set_pattern("%v");
logger->set_level(spdlog::level::trace); logger->set_level(spdlog::level::trace);
logger->flush_on(spdlog::level::info); logger->flush_on(spdlog::level::info);
logger->trace("Should not be flushed"); logger->trace("Should not be flushed");
REQUIRE(count_lines(filename) == 0); REQUIRE(count_lines(filename) == 0);
logger->info("Test message {}", 1); logger->info("Test message {}", 1);
logger->info("Test message {}", 2); logger->info("Test message {}", 2);
logger->flush(); logger->flush();
REQUIRE(file_contents(filename) == std::string("Should not be flushed\nTest message 1\nTest message 2\n")); REQUIRE(file_contents(filename) == std::string("Should not be flushed\nTest message 1\nTest message 2\n"));
REQUIRE(count_lines(filename) == 3); REQUIRE(count_lines(filename) == 3);
} }
TEST_CASE("rotating_file_logger1", "[rotating_logger]]") TEST_CASE("rotating_file_logger1", "[rotating_logger]]")
@ -49,7 +49,7 @@ TEST_CASE("rotating_file_logger1", "[rotating_logger]]")
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
logger->info("Test message {}", i); logger->info("Test message {}", i);
logger->flush(); logger->flush();
auto filename = basename + ".txt"; auto filename = basename + ".txt";
REQUIRE(count_lines(filename) == 10); REQUIRE(count_lines(filename) == 10);
} }
@ -111,7 +111,7 @@ TEST_CASE("daily_logger with dateonly calculator", "[daily_logger_dateonly]]")
auto logger = spdlog::create<sink_type>("logger", basename, "txt", 0, 0); auto logger = spdlog::create<sink_type>("logger", basename, "txt", 0, 0);
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
logger->info("Test message {}", i); logger->info("Test message {}", i);
logger->flush(); logger->flush();
auto filename = w.str(); auto filename = w.str();
REQUIRE(count_lines(filename) == 10); REQUIRE(count_lines(filename) == 10);
} }
@ -144,7 +144,7 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger_custom]]")
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
logger->info("Test message {}", i); logger->info("Test message {}", i);
logger->flush(); logger->flush();
auto filename = w.str(); auto filename = w.str();
REQUIRE(count_lines(filename) == 10); REQUIRE(count_lines(filename) == 10);
} }