Photon 1.0.0
Loading...
Searching...
No Matches
rotating_file_sink-inl.h
Go to the documentation of this file.
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#ifndef SPDLOG_HEADER_ONLY
8#endif
9
10#include <spdlog/common.h>
11
14#include <spdlog/fmt/fmt.h>
15
16#include <cerrno>
17#include <chrono>
18#include <ctime>
19#include <mutex>
20#include <string>
21#include <tuple>
22
23namespace spdlog
24{
25 namespace sinks
26 {
27
28 template <typename Mutex>
30 filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open, const file_event_handlers& event_handlers)
31 : base_filename_(std::move(base_filename)), max_size_(max_size), max_files_(max_files), file_helper_{event_handlers}
32 {
33 if (max_size == 0)
34 {
35 throw_spdlog_ex("rotating sink constructor: max_size arg cannot be zero");
36 }
37
38 if (max_files > 200000)
39 {
40 throw_spdlog_ex("rotating sink constructor: max_files arg cannot exceed 200000");
41 }
43 current_size_ = file_helper_.size(); // expensive. called only once
44 if (rotate_on_open && current_size_ > 0)
45 {
46 rotate_();
47 current_size_ = 0;
48 }
49 }
50
51 // calc filename according to index and file extension if exists.
52 // e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt".
53 template <typename Mutex>
55 {
56 if (index == 0u)
57 {
58 return filename;
59 }
60
61 filename_t basename, ext;
62 std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
63 return fmt_lib::format(SPDLOG_FILENAME_T("{}.{}{}"), basename, index, ext);
64 }
65
66 template <typename Mutex>
68 {
69 std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
70 return file_helper_.filename();
71 }
72
73 template <typename Mutex>
75 {
76 memory_buf_t formatted;
77 base_sink<Mutex>::formatter_->format(msg, formatted);
78 auto new_size = current_size_ + formatted.size();
79
80 // rotate if the new estimated file size exceeds max size.
81 // rotate only if the real size > 0 to better deal with full disk (see issue #2261).
82 // we only check the real size when new_size > max_size_ because it is relatively expensive.
83 if (new_size > max_size_)
84 {
85 file_helper_.flush();
86 if (file_helper_.size() > 0)
87 {
88 rotate_();
89 new_size = formatted.size();
90 }
91 }
92 file_helper_.write(formatted);
93 current_size_ = new_size;
94 }
95
96 template <typename Mutex>
98 {
99 file_helper_.flush();
100 }
101
102 // Rotate files:
103 // log.txt -> log.1.txt
104 // log.1.txt -> log.2.txt
105 // log.2.txt -> log.3.txt
106 // log.3.txt -> delete
107 template <typename Mutex>
109 {
112
113 file_helper_.close();
114 for (auto i = max_files_; i > 0; --i)
115 {
116 filename_t src = calc_filename(base_filename_, i - 1);
117 if (!path_exists(src))
118 {
119 continue;
120 }
121 filename_t target = calc_filename(base_filename_, i);
122
123 if (!rename_file_(src, target))
124 {
125 // if failed try again after a small delay.
126 // this is a workaround to a windows issue, where very high rotation
127 // rates can cause the rename to fail with permission denied (because of antivirus?).
129 if (!rename_file_(src, target))
130 {
131 file_helper_.reopen(true); // truncate the log file anyway to prevent it to grow beyond its limit!
132 current_size_ = 0;
133 throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno);
134 }
135 }
136 }
137 file_helper_.reopen(true);
138 }
139
140 // delete the target if exists, and rename the src file to target
141 // return true on success, false otherwise.
142 template <typename Mutex>
143 SPDLOG_INLINE bool rotating_file_sink<Mutex>::rename_file_(const filename_t& src_filename, const filename_t& target_filename)
144 {
145 // try to delete the target file in case it already exists.
146 (void)details::os::remove(target_filename);
147 return details::os::rename(src_filename, target_filename) == 0;
148 }
149
150 } // namespace sinks
151} // namespace spdlog
size_t size() const
Definition file_helper-inl.h:133
static std::tuple< filename_t, filename_t > split_by_extension(const filename_t &fname)
Definition file_helper-inl.h:160
void open(const filename_t &fname, bool truncate=false)
Definition file_helper-inl.h:35
Definition base_sink.h:22
void flush() final
Definition base_sink-inl.h:35
bool rename_file_(const filename_t &src_filename, const filename_t &target_filename)
Definition rotating_file_sink-inl.h:143
filename_t base_filename_
Definition rotating_file_sink.h:47
void flush_() override
Definition rotating_file_sink-inl.h:97
std::size_t current_size_
Definition rotating_file_sink.h:50
filename_t filename()
Definition rotating_file_sink-inl.h:67
static filename_t calc_filename(const filename_t &filename, std::size_t index)
Definition rotating_file_sink-inl.h:54
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 &event_handlers={})
Definition rotating_file_sink-inl.h:29
void sink_it_(const details::log_msg &msg) override
Definition rotating_file_sink-inl.h:74
details::file_helper file_helper_
Definition rotating_file_sink.h:51
void rotate_()
Definition rotating_file_sink-inl.h:108
#define SPDLOG_FILENAME_T(s)
Definition common.h:132
#define SPDLOG_INLINE
Definition common.h:47
SPDLOG_INLINE std::string filename_to_str(const filename_t &filename)
Definition os-inl.h:399
SPDLOG_INLINE int remove(const filename_t &filename) SPDLOG_NOEXCEPT
Definition os-inl.h:168
SPDLOG_INLINE int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT
Definition os-inl.h:182
SPDLOG_INLINE bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT
Definition os-inl.h:192
SPDLOG_INLINE void sleep_for_millis(unsigned int milliseconds) SPDLOG_NOEXCEPT
Definition os-inl.h:381
Definition async.h:26
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno)
Definition common-inl.h:75
std::string filename_t
Definition common.h:131
fmt::basic_memory_buffer< char, 250 > memory_buf_t
Definition common.h:173
Definition uuid.h:926
Definition log_msg.h:14
Definition common.h:329
u
Definition tag_strings.h:62
i
Definition tag_strings.h:60