spdlog
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 {
24namespace sinks {
25
26template<typename Mutex>
28 filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open)
29 : base_filename_(std::move(base_filename))
30 , max_size_(max_size)
31 , max_files_(max_files)
32{
34 current_size_ = file_helper_.size(); // expensive. called only once
35 if (rotate_on_open && current_size_ > 0)
36 {
37 rotate_();
38 }
39}
40
41// calc filename according to index and file extension if exists.
42// e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt".
43template<typename Mutex>
45{
46 if (index == 0u)
47 {
48 return filename;
49 }
50
51 filename_t basename, ext;
52 std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
53 return fmt::format(SPDLOG_FILENAME_T("{}.{}{}"), basename, index, ext);
54}
55
56template<typename Mutex>
62
63template<typename Mutex>
65{
66 memory_buf_t formatted;
67 base_sink<Mutex>::formatter_->format(msg, formatted);
68 current_size_ += formatted.size();
69 if (current_size_ > max_size_)
70 {
71 rotate_();
72 current_size_ = formatted.size();
73 }
74 file_helper_.write(formatted);
75}
76
77template<typename Mutex>
79{
80 file_helper_.flush();
81}
82
83// Rotate files:
84// log.txt -> log.1.txt
85// log.1.txt -> log.2.txt
86// log.2.txt -> log.3.txt
87// log.3.txt -> delete
88template<typename Mutex>
90{
93 file_helper_.close();
94 for (auto i = max_files_; i > 0; --i)
95 {
96 filename_t src = calc_filename(base_filename_, i - 1);
97 if (!path_exists(src))
98 {
99 continue;
100 }
101 filename_t target = calc_filename(base_filename_, i);
102
103 if (!rename_file_(src, target))
104 {
105 // if failed try again after a small delay.
106 // this is a workaround to a windows issue, where very high rotation
107 // rates can cause the rename to fail with permission denied (because of antivirus?).
109 if (!rename_file_(src, target))
110 {
111 file_helper_.reopen(true); // truncate the log file anyway to prevent it to grow beyond its limit!
112 current_size_ = 0;
113 throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno);
114 }
115 }
116 }
117 file_helper_.reopen(true);
118}
119
120// delete the target if exists, and rename the src file to target
121// return true on success, false otherwise.
122template<typename Mutex>
123SPDLOG_INLINE bool rotating_file_sink<Mutex>::rename_file_(const filename_t &src_filename, const filename_t &target_filename)
124{
125 // try to delete the target file in case it already exists.
126 (void)details::os::remove(target_filename);
127 return details::os::rename(src_filename, target_filename) == 0;
128}
129
130} // namespace sinks
131} // namespace spdlog
static std::tuple< filename_t, filename_t > split_by_extension(const filename_t &fname)
void open(const filename_t &fname, bool truncate=false)
bool rename_file_(const filename_t &src_filename, const filename_t &target_filename)
rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open=false)
static filename_t calc_filename(const filename_t &filename, std::size_t index)
void sink_it_(const details::log_msg &msg) override
#define SPDLOG_FILENAME_T(s)
Definition common.h:107
#define SPDLOG_INLINE
Definition common.h:33
SPDLOG_INLINE std::string filename_to_str(const filename_t &filename)
Definition os-inl.h:387
SPDLOG_INLINE int remove(const filename_t &filename) SPDLOG_NOEXCEPT
Definition os-inl.h:163
SPDLOG_INLINE int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT
Definition os-inl.h:177
SPDLOG_INLINE bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT
Definition os-inl.h:187
SPDLOG_INLINE void sleep_for_millis(unsigned int milliseconds) SPDLOG_NOEXCEPT
Definition os-inl.h:369
Definition async.h:25
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno)
Definition common-inl.h:68
fmt::basic_memory_buffer< char, 250 > memory_buf_t
Definition common.h:116
T tie(T... args)