diff options
author | Gabi Melman <gmelman1@gmail.com> | 2018-05-30 13:30:13 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-30 13:30:13 +0300 |
commit | 4640c5cb50f03a39cdc70d13a7cd7ebd86fbf4b0 (patch) | |
tree | 4ed7a4d34dffd951d892195155420e4363b566dc | |
parent | 67a6eaf23ed38cf37ee872dbf513443ca28869dd (diff) | |
parent | 98b9cd38ec5d2d57f4109e3c703cc78e7c3fee2d (diff) |
Merge pull request #713 from Puasonych/master
Update step logger
-rw-r--r-- | include/spdlog/contrib/sinks/step_file_sink.h | 94 |
1 files changed, 63 insertions, 31 deletions
diff --git a/include/spdlog/contrib/sinks/step_file_sink.h b/include/spdlog/contrib/sinks/step_file_sink.h index 395a534d..87f45f45 100644 --- a/include/spdlog/contrib/sinks/step_file_sink.h +++ b/include/spdlog/contrib/sinks/step_file_sink.h @@ -18,22 +18,22 @@ // Create a file logger which creates new files with a specified time step and fixed file size: // // std::shared_ptr<logger> step_logger_mt(const std::string &logger_name, const filename_t &filename, unsigned seconds = 60, const -// filename_t &tmp_ext = ".tmp", unsigned max_file_size = std::numeric_limits<unsigned>::max()); std::shared_ptr<logger> +// filename_t &tmp_ext = ".tmp", unsigned max_file_size = std::numeric_limits<unsigned>::max(), bool delete_empty_files = true, const filename_t &file_header = ""); std::shared_ptr<logger> // step_logger_st(const std::string &logger_name, const filename_t &filename, unsigned seconds = 60, const filename_t &tmp_ext = ".tmp", // unsigned max_file_size = std::numeric_limits<unsigned>::max()); // Example for spdlog_impl.h // Create a file logger that creates new files with a specified increment // inline std::shared_ptr<spdlog::logger> spdlog::step_logger_mt( -// const std::string &logger_name, const filename_t &filename_fmt, unsigned seconds, const filename_t &tmp_ext, unsigned max_file_size) +// const std::string &logger_name, const filename_t &filename_fmt, unsigned seconds, const filename_t &tmp_ext, unsigned max_file_size, bool delete_empty_files, const filename_t &file_header) // { -// return create<spdlog::sinks::step_file_sink_mt>(logger_name, filename_fmt, seconds, tmp_ext, max_file_size); +// return create<spdlog::sinks::step_file_sink_mt>(logger_name, filename_fmt, seconds, tmp_ext, max_file_size, delete_empty_files, file_header); // } // inline std::shared_ptr<spdlog::logger> spdlog::step_logger_st( -// const std::string &logger_name, const filename_t &filename_fmt, unsigned seconds, const filename_t &tmp_ext, unsigned max_file_size) +// const std::string &logger_name, const filename_t &filename_fmt, unsigned seconds, const filename_t &tmp_ext, unsigned max_file_size, bool delete_empty_files, const filename_t &file_header) // { -// return create<spdlog::sinks::step_file_sink_st>(logger_name, filename_fmt, seconds, tmp_ext, max_file_size); +// return create<spdlog::sinks::step_file_sink_st>(logger_name, filename_fmt, seconds, tmp_ext, max_file_size, delete_empty_files, file_header); // } namespace spdlog { @@ -58,36 +58,32 @@ struct default_step_file_name_calculator }; /* - * The default action when recording starts - */ -struct default_action_when_recording_starts -{ - // Write the start message to the beginning of the file and return its size - static size_t beginning_of_file() - { - return 0; - } -}; - -/* * Rotating file sink based on size and a specified time step */ -template<class Mutex, class FileNameCalc = default_step_file_name_calculator, - class RecordingStartActions = default_action_when_recording_starts> +template<class Mutex, class FileNameCalc = default_step_file_name_calculator> class step_file_sink SPDLOG_FINAL : public base_sink<Mutex> { public: - step_file_sink(filename_t base_filename, unsigned step_seconds, filename_t tmp_ext, unsigned max_size) + step_file_sink(filename_t base_filename, unsigned step_seconds, filename_t tmp_ext, unsigned max_size, bool delete_empty_files, filename_t file_header) : _base_filename(std::move(base_filename)) , _tmp_ext(std::move(tmp_ext)) , _step_seconds(step_seconds) , _max_size(max_size) + , _delete_empty_files(delete_empty_files) { if (step_seconds == 0) { throw spdlog_ex("step_file_sink: Invalid time step in ctor"); } - if (max_size == 0) + + if (!file_header.empty()) + { + pattern_formatter formatter_for_file_header("%v"); + _file_header.raw << file_header; + formatter_for_file_header.format(_file_header); + } + + if (max_size <= _file_header.formatted.size()) { throw spdlog_ex("step_file_sink: Invalid max log size in ctor"); } @@ -102,6 +98,12 @@ public: _file_helper.open(_current_filename); _current_size = _file_helper.size(); // expensive. called only once + + if (!_current_size) + { + _current_size += _file_header.formatted.size(); + if (_current_size) _file_helper.write(_file_header); + } } ~step_file_sink() @@ -118,16 +120,33 @@ public: protected: void _sink_it(const details::log_msg &msg) override { - _current_size += msg.formatted.size(); - if (std::chrono::system_clock::now() >= _tp || _current_size > _max_size) + auto msg_size = msg.formatted.size(); + + if (std::chrono::system_clock::now() >= _tp || _current_size + msg_size > _max_size) { - close_current_file(); + filename_t new_filename; + std::tie(new_filename, std::ignore) = FileNameCalc::calc_filename(_base_filename, _tmp_ext); + + bool change_occured = !details::file_helper::file_exists(new_filename); + if (change_occured) + { + close_current_file(); + + _current_filename = std::move(new_filename); + + _file_helper.open(_current_filename); + } - std::tie(_current_filename, std::ignore) = FileNameCalc::calc_filename(_base_filename, _tmp_ext); - _file_helper.open(_current_filename); _tp = _next_tp(); - _current_size = msg.formatted.size() + RecordingStartActions::beginning_of_file(); + + if (change_occured) + { + _current_size = _file_header.formatted.size(); + if (_current_size) _file_helper.write(_file_header); + } } + + _current_size += msg_size; _file_helper.write(msg); } @@ -146,13 +165,24 @@ private: { using details::os::filename_to_str; - filename_t src = _current_filename, target; - std::tie(target, std::ignore) = details::file_helper::split_by_extenstion(src); + // Delete empty files, if required + if (_delete_empty_files && _current_size <= _file_header.formatted.size()) + { + if (details::os::remove(_current_filename) != 0) + { + throw spdlog_ex("step_file_sink: not remove " + filename_to_str(_current_filename), errno); + } + + return; + } + + filename_t target; + std::tie(target, std::ignore) = details::file_helper::split_by_extenstion(_current_filename); target += _ext; - if (details::file_helper::file_exists(src) && details::os::rename(src, target) != 0) + if (details::file_helper::file_exists(_current_filename) && details::os::rename(_current_filename, target) != 0) { - throw spdlog_ex("step_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno); + throw spdlog_ex("step_file_sink: failed renaming " + filename_to_str(_current_filename) + " to " + filename_to_str(target), errno); } } @@ -160,6 +190,7 @@ private: const filename_t _tmp_ext; const std::chrono::seconds _step_seconds; const unsigned _max_size; + const bool _delete_empty_files; std::chrono::system_clock::time_point _tp; filename_t _current_filename; @@ -167,6 +198,7 @@ private: unsigned _current_size; details::file_helper _file_helper; + details::log_msg _file_header; }; using step_file_sink_mt = step_file_sink<std::mutex>; |