mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-30 00:47:13 +00:00
refactor(obs): optimize logging with custom RollingAppender and improved cleanup (#2151)
Signed-off-by: houseme <housemecn@gmail.com> Signed-off-by: heihutu <30542132+heihutu@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: houseme <4829346+houseme@users.noreply.github.com> Co-authored-by: heihutu <30542132+heihutu@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -33,21 +33,23 @@
|
||||
//! use rustfs_obs::LogCleaner;
|
||||
//! use rustfs_obs::types::FileMatchMode;
|
||||
//!
|
||||
//! let cleaner = LogCleaner::new(
|
||||
//! let cleaner = LogCleaner::builder(
|
||||
//! PathBuf::from("/var/log/rustfs"),
|
||||
//! "rustfs.log.".to_string(),
|
||||
//! FileMatchMode::Prefix,
|
||||
//! 10, // keep_files
|
||||
//! 2 * 1024 * 1024 * 1024, // max_total_size_bytes (2 GiB)
|
||||
//! 0, // max_single_file_size_bytes (unlimited)
|
||||
//! true, // compress_old_files
|
||||
//! 6, // gzip_compression_level
|
||||
//! 30, // compressed_file_retention_days
|
||||
//! vec![], // exclude_patterns
|
||||
//! true, // delete_empty_files
|
||||
//! 3600, // min_file_age_seconds (1 hour)
|
||||
//! false, // dry_run
|
||||
//! );
|
||||
//! "rustfs.log".to_string(),
|
||||
//! )
|
||||
//! .match_mode(FileMatchMode::Prefix)
|
||||
//! .keep_files(10)
|
||||
//! .max_total_size_bytes(2 * 1024 * 1024 * 1024) // 2 GiB
|
||||
//! .max_single_file_size_bytes(0) // unlimited
|
||||
//! .compress_old_files(true)
|
||||
//! .gzip_compression_level(6)
|
||||
//! .compressed_file_retention_days(30)
|
||||
//! .exclude_patterns(vec![])
|
||||
//! .delete_empty_files(true)
|
||||
//! .min_file_age_seconds(3600) // 1 hour
|
||||
//! .dry_run(false)
|
||||
//! .build();
|
||||
//!
|
||||
//! let (deleted, freed_bytes) = cleaner.cleanup().expect("cleanup failed");
|
||||
//! println!("Deleted {deleted} files, freed {freed_bytes} bytes");
|
||||
@@ -79,21 +81,13 @@ mod tests {
|
||||
|
||||
/// Build a cleaner with sensible test defaults (no compression, no age gate).
|
||||
fn make_cleaner(dir: std::path::PathBuf, keep: usize, max_bytes: u64) -> LogCleaner {
|
||||
LogCleaner::new(
|
||||
dir,
|
||||
"app.log.".to_string(),
|
||||
FileMatchMode::Prefix,
|
||||
keep,
|
||||
max_bytes,
|
||||
0, // max_single_file_size_bytes
|
||||
false, // compress_old_files
|
||||
6, // gzip_compression_level
|
||||
30, // compressed_file_retention_days
|
||||
Vec::new(), // exclude_patterns
|
||||
true, // delete_empty_files
|
||||
0, // min_file_age_seconds (0 = no age gate in tests)
|
||||
false, // dry_run
|
||||
)
|
||||
LogCleaner::builder(dir, "app.log.".to_string(), "app.log".to_string())
|
||||
.match_mode(FileMatchMode::Prefix)
|
||||
.keep_files(keep)
|
||||
.max_total_size_bytes(max_bytes)
|
||||
.min_file_age_seconds(0) // 0 = no age gate in tests
|
||||
.delete_empty_files(true)
|
||||
.build()
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -141,11 +135,15 @@ mod tests {
|
||||
create_log_file(&dir, "app.log.2024-01-02", 1024)?;
|
||||
create_log_file(&dir, "other.log", 512)?; // different prefix
|
||||
|
||||
let cleaner = make_cleaner(dir.clone(), 1, 512);
|
||||
// keep_files=1 and max_bytes=1500: deleting one managed file (1024 bytes) leaves
|
||||
// a single managed file of 1024 bytes, which satisfies both the file-count and
|
||||
// size limits. "other.log" (different prefix) must never be touched.
|
||||
let cleaner = make_cleaner(dir.clone(), 1, 1500);
|
||||
let (deleted, _) = cleaner.cleanup()?;
|
||||
|
||||
// "other.log" must not be counted or deleted.
|
||||
// "other.log" must not be counted or deleted; only 1 managed file removed.
|
||||
assert_eq!(deleted, 1, "only managed files should be deleted");
|
||||
assert!(dir.join("other.log").exists(), "unrelated file must not be deleted");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -158,8 +156,8 @@ mod tests {
|
||||
create_log_file(&dir, "app.log.2024-01-02", 2048)?;
|
||||
create_log_file(&dir, "other.log", 512)?;
|
||||
|
||||
let files = scanner::collect_log_files(&dir, "app.log.", FileMatchMode::Prefix, &[], 0, true, false)?;
|
||||
assert_eq!(files.len(), 2, "scanner should find exactly 2 managed files");
|
||||
let result = scanner::scan_log_directory(&dir, "app.log.", Some("app.log"), FileMatchMode::Prefix, &[], 0, true, false)?;
|
||||
assert_eq!(result.logs.len(), 2, "scanner should find exactly 2 managed files");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -172,21 +170,12 @@ mod tests {
|
||||
create_log_file(&dir, "app.log.2024-01-02", 1024)?;
|
||||
create_log_file(&dir, "app.log.2024-01-03", 1024)?;
|
||||
|
||||
let cleaner = LogCleaner::new(
|
||||
dir.clone(),
|
||||
"app.log.".to_string(),
|
||||
FileMatchMode::Prefix,
|
||||
1,
|
||||
1024,
|
||||
0,
|
||||
false,
|
||||
6,
|
||||
30,
|
||||
vec![],
|
||||
true,
|
||||
0,
|
||||
true,
|
||||
);
|
||||
let cleaner = LogCleaner::builder(dir.clone(), "app.log.".to_string(), "app.log".to_string())
|
||||
.match_mode(FileMatchMode::Prefix)
|
||||
.keep_files(1)
|
||||
.max_total_size_bytes(1024)
|
||||
.dry_run(true)
|
||||
.build();
|
||||
let (deleted, _freed) = cleaner.cleanup()?;
|
||||
|
||||
// dry_run=true reports deletions but doesn't actually remove files.
|
||||
@@ -204,21 +193,11 @@ mod tests {
|
||||
create_log_file(&dir, "2026-03-01-06-22.rustfs.log", 1024)?;
|
||||
create_log_file(&dir, "other.log", 1024)?; // not managed
|
||||
|
||||
let cleaner = LogCleaner::new(
|
||||
dir.clone(),
|
||||
"rustfs.log".to_string(),
|
||||
FileMatchMode::Suffix,
|
||||
1,
|
||||
1024,
|
||||
0,
|
||||
false,
|
||||
6,
|
||||
30,
|
||||
vec![],
|
||||
true,
|
||||
0,
|
||||
false,
|
||||
);
|
||||
let cleaner = LogCleaner::builder(dir.clone(), ".rustfs.log".to_string(), "current.log".to_string())
|
||||
.match_mode(FileMatchMode::Suffix)
|
||||
.keep_files(1)
|
||||
.max_total_size_bytes(1024)
|
||||
.build();
|
||||
let (deleted, freed) = cleaner.cleanup()?;
|
||||
|
||||
assert_eq!(deleted, 1, "should delete exactly one file");
|
||||
|
||||
Reference in New Issue
Block a user