Skip to content

Commit bb054b3

Browse files
committed
Cap logfile size
See dechamps/FlexASIO#146
1 parent b69f2ee commit bb054b3

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

log.cpp

+28-2
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,40 @@ namespace dechamps_cpplog {
107107
Logger(this) << "Host process: " << GetModuleName();
108108
}
109109

110-
FileLogSink::FileLogSink(const std::filesystem::path& path) : stream(path, std::ios::app | std::ios::out) {
111-
Logger(this) << "Logfile opened: " << path;
110+
FileLogSink::FileLogSink(std::filesystem::path path, Options options) : path(std::move(path)), options(std::move(options)), stream(this->path, std::ios::app | std::ios::out) {
111+
Logger(this) << "Logfile opened: " << this->path;
112+
CheckSize();
112113
}
113114

114115
FileLogSink::~FileLogSink() {
115116
Logger(this) << "Closing logfile";
116117
}
117118

119+
void FileLogSink::Write(const std::string_view str) {
120+
if (!stream.is_open()) return;
121+
122+
stream_sink.Write(str);
123+
124+
const auto size = str.size();
125+
if (size >= bytesRemainingUntilSizeCheck) CheckSize();
126+
else bytesRemainingUntilSizeCheck -= size;
127+
}
128+
129+
void FileLogSink::CheckSize() {
130+
bytesRemainingUntilSizeCheck = (std::numeric_limits<uintmax_t>::max)();
131+
132+
const auto sizeBytes = std::filesystem::file_size(path);
133+
const auto maxSizeBytes = options.maxSizeBytes;
134+
Logger(this) << "Current log file size is " << sizeBytes << " bytes (maximum allowed: " << maxSizeBytes << " bytes)";
135+
136+
if (sizeBytes < maxSizeBytes) {
137+
bytesRemainingUntilSizeCheck = options.sizeCheckPeriodBytes;
138+
return;
139+
}
140+
Logger(this) << "Closing logfile as the maximum size is exceeded";
141+
stream.close();
142+
}
143+
118144
void ThreadSafeLogSink::Write(const std::string_view str) {
119145
std::scoped_lock lock(mutex);
120146
backend.Write(str);

log.h

+12-2
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,24 @@ namespace dechamps_cpplog {
3838

3939
class FileLogSink final : public LogSink {
4040
public:
41-
FileLogSink(const std::filesystem::path& path);
41+
struct Options final {
42+
uintmax_t maxSizeBytes = 1 * 1024 * 1024 * 1024;
43+
uintmax_t sizeCheckPeriodBytes = std::max<uintmax_t>(maxSizeBytes / 10, 1);
44+
};
45+
46+
FileLogSink(std::filesystem::path path, Options options = {});
4247
~FileLogSink();
4348

44-
void Write(const std::string_view str) override { stream_sink.Write(str); }
49+
void Write(const std::string_view str) override;
4550

4651
private:
52+
void CheckSize();
53+
54+
const std::filesystem::path path;
55+
Options options;
4756
std::ofstream stream;
4857
StreamLogSink stream_sink{ stream };
58+
uintmax_t bytesRemainingUntilSizeCheck = (std::numeric_limits<uintmax_t>::max)();
4959
};
5060

5161
class ThreadSafeLogSink final : public LogSink {

0 commit comments

Comments
 (0)