1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-08 12:40:44 +00:00

Fix file loggin log rotation

Fixes #97066

`RBSet` were used on `RotatedFileLogger` because it guarantees that
iterating it is done via `operator<`. This is important because
`RotatedFileLogger` depends on this behavior to delete the oldest log file.
On #61194 `HashSet` was added and all `RBSet` uses were replaced by
`HashSet`.
When that happened, the iteration in order is guaranteed to be the insertion
order, wich made that `RotatedFileLogger` delete the newest log file.
As a bonus, I added unit test for `RotatedFileLogger` and `CompositeLogger`.
This commit is contained in:
Pablo Andres Fuente
2024-10-16 00:19:05 -03:00
committed by Pablo Andres Fuente
parent f0f5319b0b
commit d1338528f9
3 changed files with 178 additions and 4 deletions

View File

@@ -33,6 +33,7 @@
#include "core/core_globals.h"
#include "core/io/dir_access.h"
#include "core/os/time.h"
#include "core/templates/rb_set.h"
#include "modules/modules_enabled.gen.h" // For regex.
#ifdef MODULE_REGEX_ENABLED
@@ -129,7 +130,9 @@ void RotatedFileLogger::clear_old_backups() {
da->list_dir_begin();
String f = da->get_next();
HashSet<String> backups;
// backups is a RBSet because it guarantees that iterating on it is done in sorted order.
// RotatedFileLogger depends on this behavior to delete the oldest log file first.
RBSet<String> backups;
while (!f.is_empty()) {
if (!da->current_is_dir() && f.begins_with(basename) && f.get_extension() == extension && f != base_path.get_file()) {
backups.insert(f);
@@ -138,12 +141,12 @@ void RotatedFileLogger::clear_old_backups() {
}
da->list_dir_end();
if (backups.size() > (uint32_t)max_backups) {
if (backups.size() > max_backups) {
// since backups are appended with timestamp and Set iterates them in sorted order,
// first backups are the oldest
int to_delete = backups.size() - max_backups;
for (HashSet<String>::Iterator E = backups.begin(); E && to_delete > 0; ++E, --to_delete) {
da->remove(*E);
for (RBSet<String>::Element *E = backups.front(); E && to_delete > 0; E = E->next(), --to_delete) {
da->remove(E->get());
}
}
}