Skip to content

Commit d693e22

Browse files
HNOONa-0sergiud
authored andcommitted
fix: truncate single file upon creation
1 parent 7fcf58a commit d693e22

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/logging.cc

+15
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,22 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) {
995995
if (FLAGS_timestamp_in_logfile_name) {
996996
// demand that the file is unique for our timestamp (fail if it exists).
997997
flags = flags | O_EXCL;
998+
} else {
999+
// logs are written to a single file, where: a log file is created for the
1000+
// the first time or a file is being recreated due to exceeding max size
1001+
1002+
struct stat statbuf;
1003+
if (stat(filename, &statbuf) == 0) {
1004+
// truncate the file if it exceeds the max size
1005+
if ((static_cast<uint32>(statbuf.st_size) >> 20U) >= MaxLogSize()) {
1006+
flags |= O_TRUNC;
1007+
}
1008+
1009+
// update file length to sync file size
1010+
file_length_ = static_cast<uint32>(statbuf.st_size);
1011+
}
9981012
}
1013+
9991014
FileDescriptor fd{
10001015
open(filename, flags, static_cast<mode_t>(FLAGS_logfile_mode))};
10011016
if (!fd) return false;

src/logging_unittest.cc

+43
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ static void TestLogSinkWaitTillSent();
110110
static void TestCHECK();
111111
static void TestDCHECK();
112112
static void TestSTREQ();
113+
static void TestMaxLogSizeWhenNoTimestamp();
113114
static void TestBasename();
114115
static void TestBasenameAppendWhenNoTimestamp();
115116
static void TestTwoProcessesWrite();
@@ -288,6 +289,7 @@ int main(int argc, char** argv) {
288289
MungeAndDiffTestStdout(FLAGS_test_srcdir + "/src/logging_unittest.out"));
289290
FLAGS_logtostdout = false;
290291

292+
TestMaxLogSizeWhenNoTimestamp();
291293
TestBasename();
292294
TestBasenameAppendWhenNoTimestamp();
293295
TestTwoProcessesWrite();
@@ -806,6 +808,47 @@ static void CheckFile(const string& name, const string& expected_string,
806808
<< expected_string << " in " << files[0];
807809
}
808810

811+
static void TestMaxLogSizeWhenNoTimestamp() {
812+
fprintf(stderr, "==== Test setting max log size without timestamp\n");
813+
const string dest = FLAGS_test_tmpdir + "/logging_test_max_log_size";
814+
DeleteFiles(dest + "*");
815+
816+
auto original_max_log_size = FLAGS_max_log_size;
817+
auto original_timestamp_in_logfile_name = FLAGS_timestamp_in_logfile_name;
818+
819+
FLAGS_max_log_size = 1; // Set max log size to 1MB
820+
FLAGS_timestamp_in_logfile_name = false;
821+
822+
// Set log destination
823+
SetLogDestination(GLOG_INFO, dest.c_str());
824+
825+
// 1e4 info logs -> is about 772 KB in size
826+
// 2e4 info logs -> is around 1500 KB in size -> 1.5MB
827+
// If our max_log_size constraint is respected, it will truncate earlier logs
828+
// and the file size will be lesser than 1MB (around 0.5MB)
829+
const int num_logs = 2e4;
830+
for (int i = 0; i < num_logs; i++) {
831+
LOG(INFO) << "Hello world";
832+
}
833+
FlushLogFiles(GLOG_INFO);
834+
835+
// Check log file size
836+
struct stat statbuf;
837+
stat(dest.c_str(), &statbuf);
838+
839+
// Verify file size is less than the max log size limit
840+
CHECK_LT(static_cast<unsigned int>(statbuf.st_size),
841+
FLAGS_max_log_size << 20U);
842+
843+
// Reset flag values to their original values
844+
FLAGS_max_log_size = original_max_log_size;
845+
FLAGS_timestamp_in_logfile_name = original_timestamp_in_logfile_name;
846+
847+
// Release file handle for the destination file to unlock the file in Windows.
848+
LogToStderr();
849+
DeleteFiles(dest + "*");
850+
}
851+
809852
static void TestBasename() {
810853
fprintf(stderr, "==== Test setting log file basename\n");
811854
const string dest = FLAGS_test_tmpdir + "/logging_test_basename";

0 commit comments

Comments
 (0)