fix(obs): validate numeric env settings (#4474)

Co-authored-by: heihutu <heihutu@gmail.com>
This commit is contained in:
houseme
2026-07-08 18:42:09 +08:00
committed by GitHub
parent 757f9b3b7b
commit 3ddade24f2
5 changed files with 189 additions and 14 deletions
+46 -1
View File
@@ -40,6 +40,12 @@ use tracing::{debug, error, info, warn};
const LOG_COMPONENT_OBS: &str = "obs";
const LOG_SUBSYSTEM_LOG_CLEANER: &str = "log_cleaner";
const EVENT_LOG_CLEANER_STATE: &str = "log_cleaner_state";
const SECONDS_PER_DAY: u64 = 24 * 60 * 60;
const MAX_RETENTION_DAYS_BEFORE_SATURATION: u64 = u64::MAX / SECONDS_PER_DAY;
fn compressed_file_retention_window(days: u64) -> Duration {
Duration::from_secs(days.saturating_mul(SECONDS_PER_DAY))
}
#[derive(Debug)]
struct CompressionTaskResult {
@@ -231,7 +237,18 @@ impl LogCleaner {
/// Select compressed archives whose age exceeds the archive retention window.
fn select_expired_compressed(&self, files: &mut [FileInfo]) -> Vec<FileInfo> {
let retention = Duration::from_secs(self.compressed_file_retention_days * 24 * 3600);
if self.compressed_file_retention_days > MAX_RETENTION_DAYS_BEFORE_SATURATION {
warn!(
event = EVENT_LOG_CLEANER_STATE,
component = LOG_COMPONENT_OBS,
subsystem = LOG_SUBSYSTEM_LOG_CLEANER,
result = "retention_days_saturated",
configured_days = self.compressed_file_retention_days,
fallback_days = MAX_RETENTION_DAYS_BEFORE_SATURATION,
"log cleaner state changed"
);
}
let retention = compressed_file_retention_window(self.compressed_file_retention_days);
let now = SystemTime::now();
let mut expired = Vec::new();
@@ -785,3 +802,31 @@ impl LogCleanerBuilder {
}
}
}
#[cfg(test)]
mod tests {
use super::{MAX_RETENTION_DAYS_BEFORE_SATURATION, SECONDS_PER_DAY, compressed_file_retention_window};
use std::time::Duration;
#[test]
fn compressed_file_retention_window_scales_days_without_wrap() {
assert_eq!(compressed_file_retention_window(3), Duration::from_secs(3 * SECONDS_PER_DAY));
}
#[test]
fn compressed_file_retention_window_saturates_on_large_values() {
assert_eq!(compressed_file_retention_window(u64::MAX), Duration::from_secs(u64::MAX));
}
#[test]
fn retention_day_saturation_boundary_is_safe() {
assert_eq!(
compressed_file_retention_window(MAX_RETENTION_DAYS_BEFORE_SATURATION),
Duration::from_secs(MAX_RETENTION_DAYS_BEFORE_SATURATION * SECONDS_PER_DAY)
);
assert_eq!(
compressed_file_retention_window(MAX_RETENTION_DAYS_BEFORE_SATURATION.saturating_add(1)),
Duration::from_secs(u64::MAX)
);
}
}