From c47ae3b15dedc35cc62cc34ec1e411b040373776 Mon Sep 17 00:00:00 2001 From: seker <04070628@163.com> Date: Thu, 11 Nov 2021 00:08:24 +0800 Subject: [PATCH] add file event handlers --- example/example.cpp | 17 ++++++++++++++++- include/spdlog/common.h | 8 ++++++++ include/spdlog/details/file_helper-inl.h | 18 ++++++++++++++++++ include/spdlog/details/file_helper.h | 4 +++- include/spdlog/sinks/basic_file_sink-inl.h | 3 ++- include/spdlog/sinks/basic_file_sink.h | 10 +++++----- include/spdlog/sinks/daily_file_sink.h | 19 ++++++++++--------- include/spdlog/sinks/hourly_file_sink.h | 11 ++++++----- include/spdlog/sinks/rotating_file_sink-inl.h | 3 ++- include/spdlog/sinks/rotating_file_sink.h | 10 +++++----- 10 files changed, 75 insertions(+), 28 deletions(-) diff --git a/example/example.cpp b/example/example.cpp index 3fbde21a..56e28825 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -120,7 +120,22 @@ void basic_example() void rotating_example() { // Create a file rotating logger with 5mb size max and 3 rotated files. - auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3); + spdlog::file_event_handlers_t file_event_handlers; + file_event_handlers.after_open = [](spdlog::filename_t filename, std::FILE* fstream) + { + fputs("OPEN!\r\n", fstream); + spdlog::info("basic_example() : file_event_handlers.after_open : {}", filename.c_str()); + }; + file_event_handlers.before_close = [](spdlog::filename_t filename, std::FILE* fstream) + { + fputs("CLOSE!\r\n", fstream); + spdlog::info("basic_example() : file_event_handlers.before_close : {}", filename.c_str()); + }; + file_event_handlers.after_close = [](spdlog::filename_t filename) + { + spdlog::info("basic_example() : file_event_handlers.after_close : {}", filename.c_str()); + }; + auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3, false, file_event_handlers); } #include "spdlog/sinks/daily_file_sink.h" diff --git a/include/spdlog/common.h b/include/spdlog/common.h index ed0ab46c..ddaa34ce 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef SPDLOG_COMPILED_LIB # undef SPDLOG_HEADER_ONLY @@ -255,6 +256,13 @@ struct source_loc const char *funcname{nullptr}; }; +typedef struct +{ + std::function after_open; + std::function before_close; + std::function after_close; +} file_event_handlers_t; + namespace details { // make_unique support for pre c++14 diff --git a/include/spdlog/details/file_helper-inl.h b/include/spdlog/details/file_helper-inl.h index ac7021a9..df6cd4c1 100644 --- a/include/spdlog/details/file_helper-inl.h +++ b/include/spdlog/details/file_helper-inl.h @@ -20,6 +20,10 @@ namespace spdlog { namespace details { +SPDLOG_INLINE file_helper::file_helper(const file_event_handlers_t& event_handlers) + : event_handlers_(event_handlers) +{} + SPDLOG_INLINE file_helper::~file_helper() { close(); @@ -52,6 +56,10 @@ SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate) } if (!os::fopen_s(&fd_, fname, mode)) { + if (event_handlers_.after_open) + { + event_handlers_.after_open(filename_, fd_); + } return; } @@ -79,8 +87,18 @@ SPDLOG_INLINE void file_helper::close() { if (fd_ != nullptr) { + if (event_handlers_.before_close) + { + event_handlers_.before_close(filename_, fd_); + } + std::fclose(fd_); fd_ = nullptr; + + if (event_handlers_.after_close) + { + event_handlers_.after_close(filename_); + } } } diff --git a/include/spdlog/details/file_helper.h b/include/spdlog/details/file_helper.h index cfccaed2..60c47788 100644 --- a/include/spdlog/details/file_helper.h +++ b/include/spdlog/details/file_helper.h @@ -16,7 +16,8 @@ namespace details { class SPDLOG_API file_helper { public: - explicit file_helper() = default; + file_helper() = default; + explicit file_helper(const file_event_handlers_t& event_handlers); file_helper(const file_helper &) = delete; file_helper &operator=(const file_helper &) = delete; @@ -50,6 +51,7 @@ private: const unsigned int open_interval_ = 10; std::FILE *fd_{nullptr}; filename_t filename_; + file_event_handlers_t event_handlers_{nullptr, nullptr, nullptr}; }; } // namespace details } // namespace spdlog diff --git a/include/spdlog/sinks/basic_file_sink-inl.h b/include/spdlog/sinks/basic_file_sink-inl.h index e903dd93..463e075f 100644 --- a/include/spdlog/sinks/basic_file_sink-inl.h +++ b/include/spdlog/sinks/basic_file_sink-inl.h @@ -14,7 +14,8 @@ namespace spdlog { namespace sinks { template -SPDLOG_INLINE basic_file_sink::basic_file_sink(const filename_t &filename, bool truncate) +SPDLOG_INLINE basic_file_sink::basic_file_sink(const filename_t &filename, bool truncate, const file_event_handlers_t& event_handlers) + : file_helper_{event_handlers} { file_helper_.open(filename, truncate); } diff --git a/include/spdlog/sinks/basic_file_sink.h b/include/spdlog/sinks/basic_file_sink.h index 047bc8ce..51e26e38 100644 --- a/include/spdlog/sinks/basic_file_sink.h +++ b/include/spdlog/sinks/basic_file_sink.h @@ -20,7 +20,7 @@ template class basic_file_sink final : public base_sink { public: - explicit basic_file_sink(const filename_t &filename, bool truncate = false); + explicit basic_file_sink(const filename_t &filename, bool truncate = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}); const filename_t &filename() const; protected: @@ -40,15 +40,15 @@ using basic_file_sink_st = basic_file_sink; // factory functions // template -inline std::shared_ptr basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false) +inline std::shared_ptr basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) { - return Factory::template create(logger_name, filename, truncate); + return Factory::template create(logger_name, filename, truncate, event_handlers); } template -inline std::shared_ptr basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false) +inline std::shared_ptr basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) { - return Factory::template create(logger_name, filename, truncate); + return Factory::template create(logger_name, filename, truncate, event_handlers); } } // namespace spdlog diff --git a/include/spdlog/sinks/daily_file_sink.h b/include/spdlog/sinks/daily_file_sink.h index d6a09f6b..fc552398 100644 --- a/include/spdlog/sinks/daily_file_sink.h +++ b/include/spdlog/sinks/daily_file_sink.h @@ -68,10 +68,11 @@ class daily_file_sink final : public base_sink { public: // create daily file sink which rotates on given time - daily_file_sink(filename_t base_filename, int rotation_hour, int rotation_minute, bool truncate = false, uint16_t max_files = 0) + daily_file_sink(filename_t base_filename, int rotation_hour, int rotation_minute, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) : base_filename_(std::move(base_filename)) , rotation_h_(rotation_hour) , rotation_m_(rotation_minute) + , file_helper_{event_handlers} , truncate_(truncate) , max_files_(max_files) , filenames_q_() @@ -214,29 +215,29 @@ using daily_file_format_sink_st = daily_file_sink inline std::shared_ptr daily_logger_mt( - const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0) + const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) { - return Factory::template create(logger_name, filename, hour, minute, truncate, max_files); + return Factory::template create(logger_name, filename, hour, minute, truncate, max_files, event_handlers); } template inline std::shared_ptr daily_logger_format_mt( - const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0) + const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) { - return Factory::template create(logger_name, filename, hour, minute, truncate, max_files); + return Factory::template create(logger_name, filename, hour, minute, truncate, max_files, event_handlers); } template inline std::shared_ptr daily_logger_st( - const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0) + const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) { - return Factory::template create(logger_name, filename, hour, minute, truncate, max_files); + return Factory::template create(logger_name, filename, hour, minute, truncate, max_files, event_handlers); } template inline std::shared_ptr daily_logger_format_st( - const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0) + const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) { - return Factory::template create(logger_name, filename, hour, minute, truncate, max_files); + return Factory::template create(logger_name, filename, hour, minute, truncate, max_files, event_handlers); } } // namespace spdlog diff --git a/include/spdlog/sinks/hourly_file_sink.h b/include/spdlog/sinks/hourly_file_sink.h index 815781d9..653faceb 100644 --- a/include/spdlog/sinks/hourly_file_sink.h +++ b/include/spdlog/sinks/hourly_file_sink.h @@ -46,8 +46,9 @@ class hourly_file_sink final : public base_sink { public: // create hourly file sink which rotates on given time - hourly_file_sink(filename_t base_filename, bool truncate = false, uint16_t max_files = 0) + hourly_file_sink(filename_t base_filename, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) : base_filename_(std::move(base_filename)) + , file_helper_{event_handlers} , truncate_(truncate) , max_files_(max_files) , filenames_q_() @@ -180,15 +181,15 @@ using hourly_file_sink_st = hourly_file_sink; // template inline std::shared_ptr hourly_logger_mt( - const std::string &logger_name, const filename_t &filename, bool truncate = false, uint16_t max_files = 0) + const std::string &logger_name, const filename_t &filename, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) { - return Factory::template create(logger_name, filename, truncate, max_files); + return Factory::template create(logger_name, filename, truncate, max_files, event_handlers); } template inline std::shared_ptr hourly_logger_st( - const std::string &logger_name, const filename_t &filename, bool truncate = false, uint16_t max_files = 0) + const std::string &logger_name, const filename_t &filename, bool truncate = false, uint16_t max_files = 0, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) { - return Factory::template create(logger_name, filename, truncate, max_files); + return Factory::template create(logger_name, filename, truncate, max_files, event_handlers); } } // namespace spdlog diff --git a/include/spdlog/sinks/rotating_file_sink-inl.h b/include/spdlog/sinks/rotating_file_sink-inl.h index f31f5319..2e3087af 100644 --- a/include/spdlog/sinks/rotating_file_sink-inl.h +++ b/include/spdlog/sinks/rotating_file_sink-inl.h @@ -25,10 +25,11 @@ namespace sinks { template SPDLOG_INLINE rotating_file_sink::rotating_file_sink( - filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open) + filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open, const file_event_handlers_t& event_handlers) : base_filename_(std::move(base_filename)) , max_size_(max_size) , max_files_(max_files) + , file_helper_{event_handlers} { file_helper_.open(calc_filename(base_filename_, 0)); current_size_ = file_helper_.size(); // expensive. called only once diff --git a/include/spdlog/sinks/rotating_file_sink.h b/include/spdlog/sinks/rotating_file_sink.h index 842527ef..8455227f 100644 --- a/include/spdlog/sinks/rotating_file_sink.h +++ b/include/spdlog/sinks/rotating_file_sink.h @@ -22,7 +22,7 @@ template class rotating_file_sink final : public base_sink { public: - rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false); + rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}); static filename_t calc_filename(const filename_t &filename, std::size_t index); filename_t filename(); @@ -60,16 +60,16 @@ using rotating_file_sink_st = rotating_file_sink; template inline std::shared_ptr rotating_logger_mt( - const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false) + const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) { - return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open); + return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers); } template inline std::shared_ptr rotating_logger_st( - const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false) + const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false, const file_event_handlers_t& event_handlers = {nullptr, nullptr, nullptr}) { - return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open); + return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers); } } // namespace spdlog