Photon 1.0.0
Loading...
Searching...
No Matches
hourly_file_sink.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#include <spdlog/common.h>
9#include <spdlog/fmt/fmt.h>
11#include <spdlog/details/os.h>
14
15#include <chrono>
16#include <cstdio>
17#include <ctime>
18#include <mutex>
19#include <string>
20
21namespace spdlog
22{
23 namespace sinks
24 {
25
26 /*
27 * Generator of Hourly log file names in format basename.YYYY-MM-DD-HH.ext
28 */
30 {
31 // Create filename for the form basename.YYYY-MM-DD-H
32 static filename_t calc_filename(const filename_t& filename, const tm& now_tm)
33 {
34 filename_t basename, ext;
35 std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
36 return fmt_lib::format(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}_{:02d}{}"), basename, now_tm.tm_year + 1900, now_tm.tm_mon + 1,
37 now_tm.tm_mday, now_tm.tm_hour, ext);
38 }
39 };
40
41 /*
42 * Rotating file sink based on time.
43 * If truncate != false , the created file will be truncated.
44 * If max_files > 0, retain only the last max_files and delete previous.
45 */
46 template <typename Mutex, typename FileNameCalc = hourly_filename_calculator>
47 class hourly_file_sink final : public base_sink<Mutex>
48 {
49 public:
50 // create hourly file sink which rotates on given time
52 filename_t base_filename, bool truncate = false, uint16_t max_files = 0, const file_event_handlers& event_handlers = {})
53 : base_filename_(std::move(base_filename)), file_helper_{event_handlers}, truncate_(truncate), max_files_(max_files), filenames_q_()
54 {
55 auto now = log_clock::now();
56 auto filename = FileNameCalc::calc_filename(base_filename_, now_tm(now));
60
61 if (max_files_ > 0)
62 {
64 }
65 }
66
68 {
69 std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
70 return file_helper_.filename();
71 }
72
73 protected:
74 void sink_it_(const details::log_msg& msg) override
75 {
76 auto time = msg.time;
77 bool should_rotate = time >= rotation_tp_;
78 if (should_rotate)
79 {
81 {
84 }
85 auto filename = FileNameCalc::calc_filename(base_filename_, now_tm(time));
88 }
89 remove_init_file_ = false;
90 memory_buf_t formatted;
91 base_sink<Mutex>::formatter_->format(msg, formatted);
92 file_helper_.write(formatted);
93
94 // Do the cleaning only at the end because it might throw on failure.
95 if (should_rotate && max_files_ > 0)
96 {
98 }
99 }
100
101 void flush_() override
102 {
104 }
105
106 private:
108 {
110
112 std::vector<filename_t> filenames;
113 auto now = log_clock::now();
114 while (filenames.size() < max_files_)
115 {
116 auto filename = FileNameCalc::calc_filename(base_filename_, now_tm(now));
117 if (!path_exists(filename))
118 {
119 break;
120 }
121 filenames.emplace_back(filename);
122 now -= std::chrono::hours(1);
123 }
124 for (auto iter = filenames.rbegin(); iter != filenames.rend(); ++iter)
125 {
126 filenames_q_.push_back(std::move(*iter));
127 }
128 }
129
130 tm now_tm(log_clock::time_point tp)
131 {
132 time_t tnow = log_clock::to_time_t(tp);
134 }
135
136 log_clock::time_point next_rotation_tp_()
137 {
138 auto now = log_clock::now();
139 tm date = now_tm(now);
140 date.tm_min = 0;
141 date.tm_sec = 0;
142 auto rotation_time = log_clock::from_time_t(std::mktime(&date));
143 if (rotation_time > now)
144 {
145 return rotation_time;
146 }
147 return {rotation_time + std::chrono::hours(1)};
148 }
149
150 // Delete the file N rotations ago.
151 // Throw spdlog_ex on failure to delete the old file.
153 {
156
157 filename_t current_file = file_helper_.filename();
158 if (filenames_q_.full())
159 {
160 auto old_filename = std::move(filenames_q_.front());
162 bool ok = remove_if_exists(old_filename) == 0;
163 if (!ok)
164 {
165 filenames_q_.push_back(std::move(current_file));
166 SPDLOG_THROW(spdlog_ex("Failed removing hourly file " + filename_to_str(old_filename), errno));
167 }
168 }
169 filenames_q_.push_back(std::move(current_file));
170 }
171
173 log_clock::time_point rotation_tp_;
176 uint16_t max_files_;
179 };
180
183
184 } // namespace sinks
185
186 //
187 // factory functions
188 //
189 template <typename Factory = spdlog::synchronous_factory>
190 inline std::shared_ptr<logger> hourly_logger_mt(const std::string& logger_name, const filename_t& filename, bool truncate = false, uint16_t max_files = 0, const file_event_handlers& event_handlers = {})
191 {
192 return Factory::template create<sinks::hourly_file_sink_mt>(logger_name, filename, truncate, max_files, event_handlers);
193 }
194
195 template <typename Factory = spdlog::synchronous_factory>
196 inline std::shared_ptr<logger> hourly_logger_st(const std::string& logger_name, const filename_t& filename, bool truncate = false, uint16_t max_files = 0, const file_event_handlers& event_handlers = {})
197 {
198 return Factory::template create<sinks::hourly_file_sink_st>(logger_name, filename, truncate, max_files, event_handlers);
199 }
200} // namespace spdlog
Definition circular_q.h:16
void pop_front()
Definition circular_q.h:103
const T & front() const
Definition circular_q.h:70
void push_back(T &&item)
Definition circular_q.h:53
bool full() const
Definition circular_q.h:113
Definition file_helper.h:19
const filename_t & filename() const
Definition file_helper-inl.h:142
size_t size() const
Definition file_helper-inl.h:133
void flush()
Definition file_helper-inl.h:88
void write(const memory_buf_t &buf)
Definition file_helper-inl.h:123
static std::tuple< filename_t, filename_t > split_by_extension(const filename_t &fname)
Definition file_helper-inl.h:160
void close()
Definition file_helper-inl.h:104
void open(const filename_t &fname, bool truncate=false)
Definition file_helper-inl.h:35
Definition base_sink.h:22
Definition hourly_file_sink.h:48
hourly_file_sink(filename_t base_filename, bool truncate=false, uint16_t max_files=0, const file_event_handlers &event_handlers={})
Definition hourly_file_sink.h:51
log_clock::time_point rotation_tp_
Definition hourly_file_sink.h:173
tm now_tm(log_clock::time_point tp)
Definition hourly_file_sink.h:130
bool remove_init_file_
Definition hourly_file_sink.h:178
details::circular_q< filename_t > filenames_q_
Definition hourly_file_sink.h:177
filename_t filename()
Definition hourly_file_sink.h:67
void flush_() override
Definition hourly_file_sink.h:101
void delete_old_()
Definition hourly_file_sink.h:152
void init_filenames_q_()
Definition hourly_file_sink.h:107
details::file_helper file_helper_
Definition hourly_file_sink.h:174
filename_t base_filename_
Definition hourly_file_sink.h:172
log_clock::time_point next_rotation_tp_()
Definition hourly_file_sink.h:136
void sink_it_(const details::log_msg &msg) override
Definition hourly_file_sink.h:74
uint16_t max_files_
Definition hourly_file_sink.h:176
bool truncate_
Definition hourly_file_sink.h:175
Definition common.h:298
#define SPDLOG_FILENAME_T(s)
Definition common.h:132
#define SPDLOG_THROW(ex)
Definition common.h:108
SPDLOG_INLINE std::string filename_to_str(const filename_t &filename)
Definition os-inl.h:399
SPDLOG_INLINE int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT
Definition os-inl.h:177
SPDLOG_INLINE int remove(const filename_t &filename) SPDLOG_NOEXCEPT
Definition os-inl.h:168
SPDLOG_INLINE std::tm localtime() SPDLOG_NOEXCEPT
Definition os-inl.h:102
SPDLOG_INLINE bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT
Definition os-inl.h:192
hourly_file_sink< details::null_mutex > hourly_file_sink_st
Definition hourly_file_sink.h:182
hourly_file_sink< std::mutex > hourly_file_sink_mt
Definition hourly_file_sink.h:181
Definition async.h:26
std::string filename_t
Definition common.h:131
std::shared_ptr< logger > hourly_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate=false, uint16_t max_files=0, const file_event_handlers &event_handlers={})
Definition hourly_file_sink.h:196
fmt::basic_memory_buffer< char, 250 > memory_buf_t
Definition common.h:173
std::shared_ptr< logger > hourly_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate=false, uint16_t max_files=0, const file_event_handlers &event_handlers={})
Definition hourly_file_sink.h:190
Definition uuid.h:926
Definition log_msg.h:14
log_clock::time_point time
Definition log_msg.h:24
Definition common.h:329
Definition hourly_file_sink.h:30
static filename_t calc_filename(const filename_t &filename, const tm &now_tm)
Definition hourly_file_sink.h:32
time
Definition tag_strings.h:53