1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. |
2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) |
3 | |
4 | #pragma once |
5 | |
6 | #include <spdlog/sinks/base_sink.h> |
7 | #include <spdlog/details/file_helper.h> |
8 | #include <spdlog/details/null_mutex.h> |
9 | #include <spdlog/details/synchronous_factory.h> |
10 | |
11 | #include <chrono> |
12 | #include <mutex> |
13 | #include <string> |
14 | |
15 | namespace spdlog { |
16 | namespace sinks { |
17 | |
18 | // |
19 | // Rotating file sink based on size |
20 | // |
21 | template<typename Mutex> |
22 | class rotating_file_sink final : public base_sink<Mutex> |
23 | { |
24 | public: |
25 | rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false, |
26 | const file_event_handlers &event_handlers = {}); |
27 | static filename_t calc_filename(const filename_t &filename, std::size_t index); |
28 | filename_t filename(); |
29 | |
30 | protected: |
31 | void sink_it_(const details::log_msg &msg) override; |
32 | void flush_() override; |
33 | |
34 | private: |
35 | // Rotate files: |
36 | // log.txt -> log.1.txt |
37 | // log.1.txt -> log.2.txt |
38 | // log.2.txt -> log.3.txt |
39 | // log.3.txt -> delete |
40 | void rotate_(); |
41 | |
42 | // delete the target if exists, and rename the src file to target |
43 | // return true on success, false otherwise. |
44 | bool rename_file_(const filename_t &src_filename, const filename_t &target_filename); |
45 | |
46 | filename_t base_filename_; |
47 | std::size_t max_size_; |
48 | std::size_t max_files_; |
49 | std::size_t current_size_; |
50 | details::file_helper file_helper_; |
51 | }; |
52 | |
53 | using rotating_file_sink_mt = rotating_file_sink<std::mutex>; |
54 | using rotating_file_sink_st = rotating_file_sink<details::null_mutex>; |
55 | |
56 | } // namespace sinks |
57 | |
58 | // |
59 | // factory functions |
60 | // |
61 | |
62 | template<typename Factory = spdlog::synchronous_factory> |
63 | inline std::shared_ptr<logger> rotating_logger_mt(const std::string &logger_name, const filename_t &filename, size_t max_file_size, |
64 | size_t max_files, bool rotate_on_open = false, const file_event_handlers &event_handlers = {}) |
65 | { |
66 | return Factory::template create<sinks::rotating_file_sink_mt>( |
67 | logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers); |
68 | } |
69 | |
70 | template<typename Factory = spdlog::synchronous_factory> |
71 | inline std::shared_ptr<logger> rotating_logger_st(const std::string &logger_name, const filename_t &filename, size_t max_file_size, |
72 | size_t max_files, bool rotate_on_open = false, const file_event_handlers &event_handlers = {}) |
73 | { |
74 | return Factory::template create<sinks::rotating_file_sink_st>( |
75 | logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers); |
76 | } |
77 | } // namespace spdlog |
78 | |
79 | #ifdef SPDLOG_HEADER_ONLY |
80 | # include "rotating_file_sink-inl.h" |
81 | #endif |
82 | |