Skip to content

Commit 7d49ee8

Browse files
authored
Replace log rotation with timestamped log files and cleanup by age (#58)
Allows multiple apps to run concurrently, because the second file won't try to rename the log file created by the first.
1 parent 8455fa1 commit 7d49ee8

1 file changed

Lines changed: 22 additions & 23 deletions

File tree

  • {{ cookiecutter.format }}/{{ cookiecutter.formal_name }}

{{ cookiecutter.format }}/{{ cookiecutter.formal_name }}/Main.cpp

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ using namespace System;
1313
using namespace System::Diagnostics;
1414
using namespace System::IO;
1515
using namespace System::Windows::Forms;
16+
using namespace System::Globalization; // for timestamp formatting
1617

1718

1819
// A global indicator of the debug level
@@ -21,6 +22,8 @@ char *debug_mode;
2122
#define info_log(...) printf(__VA_ARGS__)
2223
#define debug_log(...) if (debug_mode) printf(__VA_ARGS__)
2324

25+
#define MAX_LOG_FILE_AGE_DAYS 7
26+
2427
wchar_t* wstr(String^);
2528
void setup_stdout(FileVersionInfo^);
2629
void crash_dialog(String^);
@@ -336,7 +339,6 @@ void crash_dialog(System::String^ details) {
336339
void setup_stdout(FileVersionInfo^ version_info) {
337340
String^ log_folder;
338341
String^ src_log;
339-
String^ dst_log;
340342
FILE *log;
341343

342344
// If we can attach to the console, then we're running in a terminal;
@@ -350,37 +352,34 @@ void setup_stdout(FileVersionInfo^ version_info) {
350352
// If log folder doesn't exist, create it
351353
Directory::CreateDirectory(log_folder);
352354
} else {
353-
// If it does, rotate the logs in that folder.
354-
// - Delete <app name>-9.log
355-
src_log = log_folder + "\\" + version_info->InternalName + "-9.log";
356-
if (File::Exists(src_log)) {
357-
File::Delete(src_log);
358-
}
359-
360-
// - Move <app name>-8.log -> <app name>-9.log
361-
// - Move <app name>-7.log -> <app name>-8.log
362-
// - ...
363-
// - Move <app name>.log -> <app name>-2.log
364-
for (int dst_index = 9; dst_index >= 2; dst_index--) {
365-
if (dst_index == 2) {
366-
src_log = log_folder + "\\" + version_info->InternalName + ".log";
367-
} else {
368-
src_log = log_folder + "\\" + version_info->InternalName + "-" + (dst_index - 1) + ".log";
355+
// Attempt to delete log files older than the configured time
356+
TimeSpan maxAge = TimeSpan::FromDays(MAX_LOG_FILE_AGE_DAYS);
357+
array<String^>^ logFiles = Directory::GetFiles(log_folder, version_info->InternalName + "_*.log");
358+
DateTime now = DateTime::Now;
359+
for each (String^ file in logFiles) {
360+
try {
361+
DateTime creationTime = File::GetCreationTime(file);
362+
if (now - creationTime > maxAge) {
363+
File::Delete(file);
364+
}
369365
}
370-
dst_log = log_folder + "\\" + version_info->InternalName + "-" + dst_index + ".log";
371-
372-
if (File::Exists(src_log)) {
373-
File::Move(src_log, dst_log);
366+
catch (Exception^ ex) {
367+
// Log a message if the file could not be deleted
368+
debug_log("Could not delete old log file: %S (%S)\n", wstr(file), wstr(ex->Message));
374369
}
375370
}
376371
}
377372

378-
// Redirect stdout to a log file <app name>.log, in the
373+
// Redirect stdout to a log file, in the
379374
// user's local Logs folder for the app.
380375
// stderr doesn't exist when running without an attached console;
381376
// sys.stderr will be None in the Python interpreter. This causes
382377
// all error output to be written to stdout.
383-
_wfreopen_s(&log, wstr(log_folder + "\\" + version_info->InternalName + ".log"), L"w", stdout);
378+
379+
// Get current timestamp in format yyyyMMdd_HHmmss_fff (with milliseconds)
380+
String^ timestamp = DateTime::Now.ToString("yyyyMMdd_HHmmss_fff", CultureInfo::InvariantCulture);
381+
src_log = log_folder + "\\" + version_info->InternalName + "." + timestamp + ".log";
382+
_wfreopen_s(&log, wstr(src_log), L"w", stdout);
384383
}
385384

386385
debug_log("Log started: %S\n", wstr(DateTime::Now.ToString("yyyy-MM-dd HH:mm:ssZ")));

0 commit comments

Comments
 (0)