diff --git a/src/cleaner.rs b/src/cleaner.rs index 469a7f2..7c1d34c 100644 --- a/src/cleaner.rs +++ b/src/cleaner.rs @@ -1,6 +1,6 @@ // src/cleaner.rs -use chrono::{Duration as ChronoDuration, TimeZone, Utc}; +use chrono::{Duration as ChronoDuration, NaiveDate, TimeZone, Utc}; use sqlx::{PgPool, Row}; use std::path::{Path, PathBuf}; use std::time::Duration; @@ -162,29 +162,66 @@ async fn cleanup_files( return Ok(()); } + let threshold_date = threshold.date_naive(); + let mut entries = tokio::fs::read_dir(log_dir).await?; while let Some(entry) = entries.next_entry().await? { let path = entry.path(); - if path.is_file() { - if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) { - // 【重要】增加了前缀匹配,更加安全 - if !file_name.starts_with(prefix) || !file_name.ends_with(".log") { - continue; + if path.is_file() + && let Some(file_name) = path.file_name().and_then(|n| n.to_str()) + { + // 【重要】增加了前缀匹配,更加安全 + if !file_name.starts_with(prefix) || !file_name.ends_with(".log") { + continue; + } + let mut should_delete = false; + + let rest = &file_name[prefix.len()..]; + // 处理可能存在的连接符,比如 prefix="order-service",文件名是 "order-service-2023..." + let date_part = if rest.starts_with('-') || rest.starts_with('_') { + &rest[1..] + } else { + rest + }; + if date_part.len() >= 10 { + let date_str = &date_part[0..10]; + if let Ok(file_date) = NaiveDate::parse_from_str(date_str, "%Y-%m-%d") { + // 成功从文件名解析出日期! + println!( + " -> Parsed date from filename: {} ({})", + file_name, file_date + ); + + if file_date < threshold_date { + should_delete = true; + } + } else { + // 解析失败,说明文件名格式不对,回退到使用 Mtime + should_delete = check_by_mtime(&entry, threshold).await; } + } else { + // 长度不够,回退到 Mtime + should_delete = check_by_mtime(&entry, threshold).await; } - let metadata = entry.metadata().await?; - if let Ok(modified_sys) = metadata.modified() { - let modified: chrono::DateTime = modified_sys.into(); - if modified < threshold { - if let Err(e) = tokio::fs::remove_file(&path).await { - eprintln!("Failed cleanup file {:?}: {}", path, e); - } else { - println!("Removed expired log file: {:?}", path); - } + if should_delete { + if let Err(e) = tokio::fs::remove_file(&path).await { + eprintln!("Failed cleanup file {:?}: {}", path, e); + } else { + println!("Removed expired log file: {:?}", path); } } } } Ok(()) } + +async fn check_by_mtime(entry: &tokio::fs::DirEntry, threshold: chrono::DateTime) -> bool { + if let Ok(metadata) = entry.metadata().await + && let Ok(modified_sys) = metadata.modified() + { + let modified: chrono::DateTime = modified_sys.into(); + return modified < threshold; + } + false +}