mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-19 02:56:18 +00:00
refactor(logging): standardize protocol and observability events (#3419)
* refactor(logging): standardize object capacity events * refactor(logging): standardize protocol server events * refactor(logging): standardize swift protocol events * refactor(logging): standardize observability events * refactor(logging): move masking helper and extend guardrails
This commit is contained in:
@@ -43,6 +43,18 @@ use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
||||
use tokio::sync::{Mutex, RwLock, watch};
|
||||
use tracing::{debug, info, warn};
|
||||
|
||||
const LOG_COMPONENT_CAPACITY: &str = "capacity";
|
||||
const LOG_SUBSYSTEM_REFRESH: &str = "refresh";
|
||||
const LOG_SUBSYSTEM_RUNTIME: &str = "runtime";
|
||||
const EVENT_CAPACITY_REFRESH_CACHE_UPDATED: &str = "capacity_refresh_cache_updated";
|
||||
const EVENT_CAPACITY_REFRESH_WRITE_RECORDED: &str = "capacity_refresh_write_recorded";
|
||||
const EVENT_CAPACITY_REFRESH_DEBOUNCE_STATE: &str = "capacity_refresh_debounce_state";
|
||||
const EVENT_CAPACITY_REFRESH_PANIC: &str = "capacity_refresh_panic";
|
||||
const EVENT_CAPACITY_REFRESH_RUNTIME_SUMMARY: &str = "capacity_refresh_runtime_summary";
|
||||
const EVENT_CAPACITY_REFRESH_INTERVAL_CLAMPED: &str = "capacity_refresh_interval_clamped";
|
||||
const EVENT_CAPACITY_REFRESH_SCHEDULED: &str = "capacity_refresh_scheduled";
|
||||
const EVENT_CAPACITY_REFRESH_SKIPPED: &str = "capacity_refresh_skipped";
|
||||
|
||||
// ============================================================================
|
||||
// Configuration Functions
|
||||
// ============================================================================
|
||||
@@ -649,8 +661,16 @@ impl HybridCapacityManager {
|
||||
}
|
||||
|
||||
debug!(
|
||||
"Capacity updated: {} bytes, files={}, estimated={}, source: {:?}",
|
||||
total_used, update.file_count, update.is_estimated, source
|
||||
event = EVENT_CAPACITY_REFRESH_CACHE_UPDATED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_REFRESH,
|
||||
result = "updated",
|
||||
total_used,
|
||||
file_count = update.file_count,
|
||||
estimated = update.is_estimated,
|
||||
source = source.as_metric_label(),
|
||||
elapsed_ms = start.elapsed().as_millis() as u64,
|
||||
"capacity refresh cache updated"
|
||||
);
|
||||
record_capacity_current_bytes(total_used);
|
||||
record_capacity_update_completed(source.as_metric_label(), start.elapsed(), total_used, update.is_estimated);
|
||||
@@ -664,8 +684,13 @@ impl HybridCapacityManager {
|
||||
|
||||
record_capacity_write_operation(recent_write_count);
|
||||
debug!(
|
||||
"Write operation recorded: total writes = {}, recent writes = {}",
|
||||
record.write_count, recent_write_count
|
||||
event = EVENT_CAPACITY_REFRESH_WRITE_RECORDED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_REFRESH,
|
||||
state = "recorded",
|
||||
total_writes = record.write_count,
|
||||
recent_writes = recent_write_count,
|
||||
"capacity refresh write recorded"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -721,15 +746,27 @@ impl HybridCapacityManager {
|
||||
|
||||
if time_since_write < self.config.write_trigger_delay {
|
||||
debug!(
|
||||
"Write-triggered refresh still debounced ({:?} ago, trigger_delay={:?}, writes/min={})",
|
||||
time_since_write, self.config.write_trigger_delay, write_frequency
|
||||
event = EVENT_CAPACITY_REFRESH_DEBOUNCE_STATE,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_REFRESH,
|
||||
state = "debounced",
|
||||
time_since_write_ms = time_since_write.as_millis() as u64,
|
||||
trigger_delay_ms = self.config.write_trigger_delay.as_millis() as u64,
|
||||
writes_per_minute = write_frequency,
|
||||
"capacity refresh debounce state changed"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
debug!(
|
||||
"Write-triggered refresh eligible after debounce ({:?} ago, trigger_delay={:?}, writes/min={})",
|
||||
time_since_write, self.config.write_trigger_delay, write_frequency
|
||||
event = EVENT_CAPACITY_REFRESH_DEBOUNCE_STATE,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_REFRESH,
|
||||
state = "eligible",
|
||||
time_since_write_ms = time_since_write.as_millis() as u64,
|
||||
trigger_delay_ms = self.config.write_trigger_delay.as_millis() as u64,
|
||||
writes_per_minute = write_frequency,
|
||||
"capacity refresh debounce state changed"
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@@ -808,7 +845,15 @@ impl HybridCapacityManager {
|
||||
|
||||
let refresh_start = Instant::now();
|
||||
let result = AssertUnwindSafe(refresh_fn()).catch_unwind().await.unwrap_or_else(|err| {
|
||||
warn!(error = ?err, "capacity refresh function panicked");
|
||||
warn!(
|
||||
event = EVENT_CAPACITY_REFRESH_PANIC,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_REFRESH,
|
||||
result = "panic",
|
||||
source = source.as_metric_label(),
|
||||
error = ?err,
|
||||
"capacity refresh panicked"
|
||||
);
|
||||
Err("capacity refresh panicked".to_string())
|
||||
});
|
||||
if let Ok(update) = &result {
|
||||
@@ -860,7 +905,15 @@ impl HybridCapacityManager {
|
||||
tokio::spawn(async move {
|
||||
let refresh_start = Instant::now();
|
||||
let result = AssertUnwindSafe(refresh_fn()).catch_unwind().await.unwrap_or_else(|err| {
|
||||
warn!(error = ?err, "capacity refresh function panicked");
|
||||
warn!(
|
||||
event = EVENT_CAPACITY_REFRESH_PANIC,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_REFRESH,
|
||||
result = "panic",
|
||||
source = source.as_metric_label(),
|
||||
error = ?err,
|
||||
"capacity refresh panicked"
|
||||
);
|
||||
Err("capacity refresh panicked".to_string())
|
||||
});
|
||||
if let Ok(update) = &result {
|
||||
@@ -909,22 +962,30 @@ impl HybridCapacityManager {
|
||||
|
||||
if let Some(cached) = cached {
|
||||
info!(
|
||||
event = EVENT_CAPACITY_REFRESH_RUNTIME_SUMMARY,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_RUNTIME,
|
||||
state = "cache_present",
|
||||
total_used = cached.total_used,
|
||||
file_count = cached.file_count,
|
||||
estimated = cached.is_estimated,
|
||||
source = ?cached.source,
|
||||
source = cached.source.as_metric_label(),
|
||||
cache_age_secs = cached.last_update.elapsed().as_secs(),
|
||||
writes_per_minute = recent_write_frequency,
|
||||
dirty_disk_count = dirty_disks.len(),
|
||||
refresh_inflight = refresh_running,
|
||||
"Capacity metrics summary"
|
||||
"capacity refresh runtime summary"
|
||||
);
|
||||
} else {
|
||||
info!(
|
||||
event = EVENT_CAPACITY_REFRESH_RUNTIME_SUMMARY,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_RUNTIME,
|
||||
state = "cache_empty",
|
||||
writes_per_minute = recent_write_frequency,
|
||||
dirty_disk_count = dirty_disks.len(),
|
||||
refresh_inflight = refresh_running,
|
||||
"Capacity metrics summary (cache empty)"
|
||||
"capacity refresh runtime summary"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -967,11 +1028,31 @@ pub async fn start_background_task(disks: Vec<CapacityDiskRef>) {
|
||||
|
||||
// Prevent panic in tokio::time::interval when misconfigured to 0
|
||||
if refresh_interval.is_zero() {
|
||||
warn!("RUSTFS_CAPACITY_SCHEDULED_INTERVAL is configured as 0; clamping to 1s to avoid panic");
|
||||
warn!(
|
||||
event = EVENT_CAPACITY_REFRESH_INTERVAL_CLAMPED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_RUNTIME,
|
||||
result = "clamped",
|
||||
env_var = ENV_CAPACITY_SCHEDULED_INTERVAL,
|
||||
configured_secs = 0,
|
||||
effective_secs = 1,
|
||||
reason = "zero_interval",
|
||||
"capacity refresh interval clamped"
|
||||
);
|
||||
refresh_interval = Duration::from_secs(1);
|
||||
}
|
||||
if metrics_interval.is_zero() {
|
||||
warn!("RUSTFS_CAPACITY_METRICS_INTERVAL is configured as 0; clamping to 1s to avoid panic");
|
||||
warn!(
|
||||
event = EVENT_CAPACITY_REFRESH_INTERVAL_CLAMPED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_RUNTIME,
|
||||
result = "clamped",
|
||||
env_var = ENV_CAPACITY_METRICS_INTERVAL,
|
||||
configured_secs = 0,
|
||||
effective_secs = 1,
|
||||
reason = "zero_interval",
|
||||
"capacity refresh interval clamped"
|
||||
);
|
||||
metrics_interval = Duration::from_secs(1);
|
||||
}
|
||||
|
||||
@@ -981,10 +1062,10 @@ pub async fn start_background_task(disks: Vec<CapacityDiskRef>) {
|
||||
loop {
|
||||
timer.tick().await;
|
||||
|
||||
info!("Starting scheduled capacity update");
|
||||
let start = Instant::now();
|
||||
let manager = manager_for_refresh.clone();
|
||||
let disks = disks.clone();
|
||||
let disk_count = disks.len();
|
||||
let started = manager
|
||||
.clone()
|
||||
.spawn_refresh_if_needed(
|
||||
@@ -994,9 +1075,26 @@ pub async fn start_background_task(disks: Vec<CapacityDiskRef>) {
|
||||
.await;
|
||||
|
||||
if started {
|
||||
debug!("Scheduled capacity refresh started in {:?}", start.elapsed());
|
||||
debug!(
|
||||
event = EVENT_CAPACITY_REFRESH_SCHEDULED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_RUNTIME,
|
||||
state = "started",
|
||||
source = DataSource::Scheduled.as_metric_label(),
|
||||
disk_count,
|
||||
enqueue_latency_ms = start.elapsed().as_millis() as u64,
|
||||
"capacity refresh scheduled"
|
||||
);
|
||||
} else {
|
||||
debug!("Scheduled capacity refresh skipped because another refresh is already in progress");
|
||||
debug!(
|
||||
event = EVENT_CAPACITY_REFRESH_SKIPPED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_RUNTIME,
|
||||
state = "inflight",
|
||||
source = DataSource::Scheduled.as_metric_label(),
|
||||
disk_count,
|
||||
"capacity refresh skipped"
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -32,6 +32,22 @@ use walkdir::WalkDir;
|
||||
|
||||
const MAX_CAPACITY_SCAN_CONCURRENCY: usize = 4;
|
||||
const CAPACITY_PROGRESS_CHECK_STRIDE: usize = 512;
|
||||
const LOG_COMPONENT_CAPACITY: &str = "capacity";
|
||||
const LOG_SUBSYSTEM_SCAN: &str = "scan";
|
||||
const LOG_SUBSYSTEM_SAMPLING: &str = "sampling";
|
||||
const EVENT_CAPACITY_SCAN_DISK_COMPLETED: &str = "capacity_scan_disk_completed";
|
||||
const EVENT_CAPACITY_SCAN_DISK_FAILED: &str = "capacity_scan_disk_failed";
|
||||
const EVENT_CAPACITY_SCAN_SUMMARY: &str = "capacity_scan_summary";
|
||||
const EVENT_CAPACITY_SCAN_SYMLINK_SKIPPED: &str = "capacity_scan_symlink_skipped";
|
||||
const EVENT_CAPACITY_SCAN_SYMLINK_SUMMARY: &str = "capacity_scan_symlink_summary";
|
||||
const EVENT_CAPACITY_SCAN_DYNAMIC_TIMEOUT: &str = "capacity_scan_dynamic_timeout";
|
||||
const EVENT_CAPACITY_SCAN_TIMEOUT: &str = "capacity_scan_timeout";
|
||||
const EVENT_CAPACITY_SCAN_STALL_DETECTED: &str = "capacity_scan_stall_detected";
|
||||
const EVENT_CAPACITY_SCAN_SAMPLING_CLAMPED: &str = "capacity_scan_sampling_clamped";
|
||||
const EVENT_CAPACITY_SCAN_TRAVERSAL_FAILED: &str = "capacity_scan_traversal_failed";
|
||||
const EVENT_CAPACITY_SCAN_METADATA_FAILED: &str = "capacity_scan_metadata_failed";
|
||||
const EVENT_CAPACITY_SCAN_SAMPLING_APPLIED: &str = "capacity_scan_sampling_applied";
|
||||
const EVENT_CAPACITY_SCAN_EXACT_COMPLETED: &str = "capacity_scan_exact_completed";
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DiskScanOutcome {
|
||||
@@ -138,8 +154,19 @@ async fn calculate_data_dir_used_capacity_report(
|
||||
scan.had_partial_errors,
|
||||
);
|
||||
debug!(
|
||||
"Data directory {} size: {} bytes, files={}, sampled={}, estimated={}, duration={:?}",
|
||||
outcome.drive_path, scan.used_bytes, scan.file_count, scan.sampled_count, scan.is_estimated, outcome.duration
|
||||
event = EVENT_CAPACITY_SCAN_DISK_COMPLETED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "ok",
|
||||
disk_label = %outcome.disk_label,
|
||||
drive_path = %outcome.drive_path,
|
||||
used_bytes = scan.used_bytes,
|
||||
file_count = scan.file_count,
|
||||
sampled_count = scan.sampled_count,
|
||||
estimated = scan.is_estimated,
|
||||
partial_errors = scan.had_partial_errors,
|
||||
duration_ms = outcome.duration.as_millis() as u64,
|
||||
"capacity scan disk completed"
|
||||
);
|
||||
total_used += scan.used_bytes;
|
||||
total_files += scan.file_count;
|
||||
@@ -159,7 +186,17 @@ async fn calculate_data_dir_used_capacity_report(
|
||||
}
|
||||
Err(e) => {
|
||||
record_capacity_scan_disk(outcome.disk_label.as_str(), outcome.duration, 0, 0, false, true);
|
||||
warn!("Failed to get size for directory {}: {:?}", outcome.drive_path, e);
|
||||
warn!(
|
||||
event = EVENT_CAPACITY_SCAN_DISK_FAILED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "error",
|
||||
disk_label = %outcome.disk_label,
|
||||
drive_path = %outcome.drive_path,
|
||||
duration_ms = outcome.duration.as_millis() as u64,
|
||||
error = ?e,
|
||||
"capacity scan disk failed"
|
||||
);
|
||||
has_failure = true;
|
||||
}
|
||||
}
|
||||
@@ -170,7 +207,19 @@ async fn calculate_data_dir_used_capacity_report(
|
||||
}
|
||||
|
||||
if has_failure {
|
||||
warn!("Some directories failed to calculate size, result may be incomplete");
|
||||
warn!(
|
||||
event = EVENT_CAPACITY_SCAN_SUMMARY,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "partial",
|
||||
disk_count = disks.len(),
|
||||
used_bytes = total_used,
|
||||
file_count = total_files,
|
||||
sampled_count = total_sampled,
|
||||
estimated = is_estimated,
|
||||
duration_ms = start.elapsed().as_millis() as u64,
|
||||
"capacity scan completed with partial failures"
|
||||
);
|
||||
}
|
||||
|
||||
let mut summary = CapacityScanResult {
|
||||
@@ -265,12 +314,30 @@ impl SymlinkTracker {
|
||||
|
||||
fn should_follow(&self, path: &Path, depth: u8) -> bool {
|
||||
if depth >= self.max_depth {
|
||||
debug!("Symlink depth limit reached: {} >= {}, not following {:?}", depth, self.max_depth, path);
|
||||
debug!(
|
||||
event = EVENT_CAPACITY_SCAN_SYMLINK_SKIPPED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "skipped",
|
||||
reason = "depth_limit",
|
||||
depth,
|
||||
max_depth = self.max_depth,
|
||||
path = ?path,
|
||||
"capacity scan symlink skipped"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.visited.contains(path) {
|
||||
warn!("Circular symlink reference detected: {:?}, skipping", path);
|
||||
warn!(
|
||||
event = EVENT_CAPACITY_SCAN_SYMLINK_SKIPPED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "skipped",
|
||||
reason = "cycle_detected",
|
||||
path = ?path,
|
||||
"capacity scan symlink skipped"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -343,8 +410,17 @@ impl ProgressMonitor {
|
||||
let clamped_timeout = adjusted_timeout.max(self.min_timeout).min(self.max_timeout);
|
||||
|
||||
debug!(
|
||||
"Dynamic timeout calculation: files={}, avg_size={}, multiplier={:.2}, base_timeout={:?}, adjusted_timeout={:?}, clamped_timeout={:?}",
|
||||
file_count, avg_file_size, multiplier, self.timeout, adjusted_timeout, clamped_timeout
|
||||
event = EVENT_CAPACITY_SCAN_DYNAMIC_TIMEOUT,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
state = "calculated",
|
||||
file_count,
|
||||
avg_file_size,
|
||||
multiplier,
|
||||
base_timeout_secs = self.timeout.as_secs(),
|
||||
adjusted_timeout_secs = adjusted_timeout.as_secs(),
|
||||
clamped_timeout_secs = clamped_timeout.as_secs(),
|
||||
"capacity scan dynamic timeout calculated"
|
||||
);
|
||||
|
||||
clamped_timeout
|
||||
@@ -360,8 +436,15 @@ impl ProgressMonitor {
|
||||
|
||||
if elapsed >= dynamic_timeout {
|
||||
warn!(
|
||||
"Directory size calculation timeout after {} files, elapsed: {:?}, timeout: {:?}",
|
||||
files_processed, elapsed, dynamic_timeout
|
||||
event = EVENT_CAPACITY_SCAN_TIMEOUT,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "timeout",
|
||||
file_count = files_processed,
|
||||
elapsed_ms = elapsed.as_millis() as u64,
|
||||
timeout_ms = dynamic_timeout.as_millis() as u64,
|
||||
dynamic_timeout_enabled = self.enable_dynamic_timeout,
|
||||
"capacity scan timed out"
|
||||
);
|
||||
|
||||
if self.enable_dynamic_timeout {
|
||||
@@ -380,8 +463,13 @@ impl ProgressMonitor {
|
||||
|
||||
if files_per_checkpoint == 0 && files_processed > 0 {
|
||||
warn!(
|
||||
"No progress detected for {:?}, possible stall at {} files",
|
||||
self.stall_timeout, files_processed
|
||||
event = EVENT_CAPACITY_SCAN_STALL_DETECTED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "stall",
|
||||
file_count = files_processed,
|
||||
stall_timeout_ms = self.stall_timeout.as_millis() as u64,
|
||||
"capacity scan stall detected"
|
||||
);
|
||||
|
||||
record_capacity_stall_detected();
|
||||
@@ -418,7 +506,16 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
let max_symlink_depth = get_max_symlink_depth();
|
||||
|
||||
let effective_sample_rate = if sample_rate == 0 {
|
||||
warn!("Invalid sampling configuration: sample_rate=0. Clamping to 1 to avoid panic.");
|
||||
warn!(
|
||||
event = EVENT_CAPACITY_SCAN_SAMPLING_CLAMPED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SAMPLING,
|
||||
result = "clamped",
|
||||
configured_sample_rate = 0,
|
||||
effective_sample_rate = 1,
|
||||
reason = "zero_sample_rate",
|
||||
"capacity scan sampling configuration clamped"
|
||||
);
|
||||
1
|
||||
} else {
|
||||
sample_rate
|
||||
@@ -453,7 +550,15 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
let entry = match entry_result {
|
||||
Ok(entry) => entry,
|
||||
Err(err) => {
|
||||
warn!("Failed to traverse directory entry under {:?}: {}", path, err);
|
||||
warn!(
|
||||
event = EVENT_CAPACITY_SCAN_TRAVERSAL_FAILED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "partial",
|
||||
root_path = ?path,
|
||||
error = %err,
|
||||
"capacity scan traversal failed"
|
||||
);
|
||||
had_partial_errors = true;
|
||||
continue;
|
||||
}
|
||||
@@ -479,7 +584,15 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
let metadata = match entry.metadata() {
|
||||
Ok(meta) => meta,
|
||||
Err(err) => {
|
||||
warn!("Failed to get metadata for {:?}: {}", entry.path(), err);
|
||||
warn!(
|
||||
event = EVENT_CAPACITY_SCAN_METADATA_FAILED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "partial",
|
||||
entry_path = ?entry.path(),
|
||||
error = %err,
|
||||
"capacity scan metadata failed"
|
||||
);
|
||||
had_partial_errors = true;
|
||||
continue;
|
||||
}
|
||||
@@ -502,8 +615,17 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
let estimated_overflow = overflow_sampled_bytes.saturating_mul(overflow_count as u64) / sampled_count as u64;
|
||||
let estimated_total = exact_prefix_bytes.saturating_add(estimated_overflow);
|
||||
info!(
|
||||
"Timeout/stall at {} files, using sampled estimate: exact_prefix={} overflow_estimate={} sampled={}",
|
||||
file_count, exact_prefix_bytes, estimated_overflow, sampled_count
|
||||
event = EVENT_CAPACITY_SCAN_SAMPLING_APPLIED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SAMPLING,
|
||||
result = "fallback_estimate",
|
||||
reason = "timeout_or_stall",
|
||||
file_count,
|
||||
exact_prefix_bytes,
|
||||
estimated_overflow_bytes = estimated_overflow,
|
||||
sampled_count,
|
||||
estimated_total_bytes = estimated_total,
|
||||
"capacity scan sampling applied"
|
||||
);
|
||||
progress_monitor.record_timeout_fallback();
|
||||
record_capacity_scan_sampling(sampled_count, true);
|
||||
@@ -534,8 +656,15 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
|
||||
if file_count.is_multiple_of(100_000) {
|
||||
debug!(
|
||||
"Processed {} files, exact_prefix_bytes={}, sampled_overflow={} files/{} bytes",
|
||||
file_count, exact_prefix_bytes, sampled_count, overflow_sampled_bytes
|
||||
event = EVENT_CAPACITY_SCAN_SAMPLING_APPLIED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SAMPLING,
|
||||
state = "progress",
|
||||
file_count,
|
||||
exact_prefix_bytes,
|
||||
sampled_count,
|
||||
sampled_overflow_bytes = overflow_sampled_bytes,
|
||||
"capacity scan sampling progress"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -555,8 +684,17 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
let estimated_overflow = overflow_sampled_bytes.saturating_mul(overflow_count as u64) / sampled_count as u64;
|
||||
let estimated_total = exact_prefix_bytes.saturating_add(estimated_overflow);
|
||||
info!(
|
||||
"Timeout/stall at {} files during final check, using sampled estimate: exact_prefix={} overflow_estimate={} sampled={}",
|
||||
file_count, exact_prefix_bytes, estimated_overflow, sampled_count
|
||||
event = EVENT_CAPACITY_SCAN_SAMPLING_APPLIED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SAMPLING,
|
||||
result = "fallback_estimate",
|
||||
reason = "final_timeout_or_stall",
|
||||
file_count,
|
||||
exact_prefix_bytes,
|
||||
estimated_overflow_bytes = estimated_overflow,
|
||||
sampled_count,
|
||||
estimated_total_bytes = estimated_total,
|
||||
"capacity scan sampling applied"
|
||||
);
|
||||
progress_monitor.record_timeout_fallback();
|
||||
record_capacity_scan_sampling(sampled_count, true);
|
||||
@@ -577,8 +715,13 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
let (symlink_count, symlink_size) = symlink_tracker.get_stats();
|
||||
if symlink_count > 0 {
|
||||
info!(
|
||||
"Symlink tracking: {} symlinks processed, total tracked size: {} bytes",
|
||||
symlink_count, symlink_size
|
||||
event = EVENT_CAPACITY_SCAN_SYMLINK_SUMMARY,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "observed",
|
||||
symlink_count,
|
||||
tracked_bytes = symlink_size,
|
||||
"capacity scan symlink summary"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -587,8 +730,19 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
let estimated_overflow = overflow_sampled_bytes.saturating_mul(overflow_count as u64) / sampled_count as u64;
|
||||
let estimated_size = exact_prefix_bytes.saturating_add(estimated_overflow);
|
||||
info!(
|
||||
"Large directory detected: {} files, estimated size: {} bytes (exact prefix: {}, sampled overflow {}/{})",
|
||||
file_count, estimated_size, exact_prefix_bytes, sampled_count, overflow_count
|
||||
event = EVENT_CAPACITY_SCAN_SAMPLING_APPLIED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SAMPLING,
|
||||
result = "estimated",
|
||||
reason = "overflow_sampling",
|
||||
file_count,
|
||||
threshold = max_files_threshold,
|
||||
exact_prefix_bytes,
|
||||
overflow_count,
|
||||
sampled_count,
|
||||
estimated_overflow_bytes = estimated_overflow,
|
||||
estimated_total_bytes = estimated_size,
|
||||
"capacity scan sampling applied"
|
||||
);
|
||||
record_capacity_scan_sampling(sampled_count, true);
|
||||
record_capacity_scan_mode("estimated");
|
||||
@@ -607,8 +761,20 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
let estimated_overflow = avg_prefix_size.saturating_mul(overflow_count as u64);
|
||||
let estimated_size = exact_prefix_bytes.saturating_add(estimated_overflow);
|
||||
info!(
|
||||
"Large directory detected: {} files, estimated size: {} bytes (no overflow samples, used prefix average {} bytes/file)",
|
||||
file_count, estimated_size, avg_prefix_size
|
||||
event = EVENT_CAPACITY_SCAN_SAMPLING_APPLIED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SAMPLING,
|
||||
result = "estimated",
|
||||
reason = "prefix_average",
|
||||
file_count,
|
||||
threshold = max_files_threshold,
|
||||
exact_prefix_bytes,
|
||||
overflow_count,
|
||||
sampled_count = 0,
|
||||
avg_prefix_size,
|
||||
estimated_overflow_bytes = estimated_overflow,
|
||||
estimated_total_bytes = estimated_size,
|
||||
"capacity scan sampling applied"
|
||||
);
|
||||
record_capacity_scan_sampling(0, true);
|
||||
record_capacity_scan_mode("estimated");
|
||||
@@ -623,10 +789,14 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
} else {
|
||||
record_capacity_scan_sampling(0, false);
|
||||
debug!(
|
||||
"Directory size calculation completed: {} files, {} bytes, took {:?}",
|
||||
event = EVENT_CAPACITY_SCAN_EXACT_COMPLETED,
|
||||
component = LOG_COMPONENT_CAPACITY,
|
||||
subsystem = LOG_SUBSYSTEM_SCAN,
|
||||
result = "exact",
|
||||
file_count,
|
||||
exact_prefix_bytes,
|
||||
start_time.elapsed()
|
||||
used_bytes = exact_prefix_bytes,
|
||||
duration_ms = start_time.elapsed().as_millis() as u64,
|
||||
"capacity scan exact completed"
|
||||
);
|
||||
record_capacity_scan_mode("exact");
|
||||
Ok(CapacityScanResult {
|
||||
|
||||
Reference in New Issue
Block a user