Remove hardcoded /tmp autodetection and implement proper tmpfs monitoring
- Remove /tmp autodetection from disk collector (57 lines removed) - Add tmpfs monitoring to memory collector with get_tmpfs_metrics() method - Generate memory_tmp_* metrics for proper RAM-based tmpfs monitoring - Fix type annotations in tmpfs parsing for compilation - System widget now correctly displays tmpfs usage in RAM section
This commit is contained in:
parent
39fc9cd22f
commit
9e80d6b654
@ -527,63 +527,6 @@ impl Collector for DiskCollector {
|
|||||||
timestamp: chrono::Utc::now().timestamp() as u64,
|
timestamp: chrono::Utc::now().timestamp() as u64,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Monitor /tmp directory size (keep existing functionality)
|
|
||||||
match self.get_directory_size("/tmp") {
|
|
||||||
Ok(tmp_size_bytes) => {
|
|
||||||
let tmp_size_mb = tmp_size_bytes as f64 / (1024.0 * 1024.0);
|
|
||||||
|
|
||||||
// Get /tmp filesystem info (usually tmpfs with 2GB limit)
|
|
||||||
let (total_bytes, _) = match self.get_filesystem_info("/tmp") {
|
|
||||||
Ok((total, used)) => (total, used),
|
|
||||||
Err(_) => {
|
|
||||||
// Fallback: assume 2GB limit for tmpfs
|
|
||||||
(2 * 1024 * 1024 * 1024, tmp_size_bytes)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let total_mb = total_bytes as f64 / (1024.0 * 1024.0);
|
|
||||||
let usage_percent = (tmp_size_bytes as f64 / total_bytes as f64) * 100.0;
|
|
||||||
let status = self.calculate_usage_status(tmp_size_bytes, total_bytes);
|
|
||||||
|
|
||||||
metrics.push(Metric {
|
|
||||||
name: "disk_tmp_size_mb".to_string(),
|
|
||||||
value: MetricValue::Float(tmp_size_mb as f32),
|
|
||||||
unit: Some("MB".to_string()),
|
|
||||||
description: Some(format!("Used: {:.1} MB", tmp_size_mb)),
|
|
||||||
status,
|
|
||||||
timestamp: chrono::Utc::now().timestamp() as u64,
|
|
||||||
});
|
|
||||||
|
|
||||||
metrics.push(Metric {
|
|
||||||
name: "disk_tmp_total_mb".to_string(),
|
|
||||||
value: MetricValue::Float(total_mb as f32),
|
|
||||||
unit: Some("MB".to_string()),
|
|
||||||
description: Some(format!("Total: {:.1} MB", total_mb)),
|
|
||||||
status: Status::Ok,
|
|
||||||
timestamp: chrono::Utc::now().timestamp() as u64,
|
|
||||||
});
|
|
||||||
|
|
||||||
metrics.push(Metric {
|
|
||||||
name: "disk_tmp_usage_percent".to_string(),
|
|
||||||
value: MetricValue::Float(usage_percent as f32),
|
|
||||||
unit: Some("%".to_string()),
|
|
||||||
description: Some(format!("Usage: {:.1}%", usage_percent)),
|
|
||||||
status,
|
|
||||||
timestamp: chrono::Utc::now().timestamp() as u64,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
debug!("Failed to get /tmp size: {}", e);
|
|
||||||
metrics.push(Metric {
|
|
||||||
name: "disk_tmp_size_mb".to_string(),
|
|
||||||
value: MetricValue::String("error".to_string()),
|
|
||||||
unit: Some("MB".to_string()),
|
|
||||||
description: Some(format!("Error: {}", e)),
|
|
||||||
status: Status::Unknown,
|
|
||||||
timestamp: chrono::Utc::now().timestamp() as u64,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let collection_time = start_time.elapsed();
|
let collection_time = start_time.elapsed();
|
||||||
debug!(
|
debug!(
|
||||||
|
|||||||
@ -188,8 +188,98 @@ impl MemoryCollector {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Monitor tmpfs (/tmp) usage
|
||||||
|
if let Ok(tmpfs_metrics) = self.get_tmpfs_metrics() {
|
||||||
|
metrics.extend(tmpfs_metrics);
|
||||||
|
}
|
||||||
|
|
||||||
metrics
|
metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get tmpfs (/tmp) usage metrics
|
||||||
|
fn get_tmpfs_metrics(&self) -> Result<Vec<Metric>, CollectorError> {
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
let output = Command::new("df")
|
||||||
|
.arg("--block-size=1")
|
||||||
|
.arg("/tmp")
|
||||||
|
.output()
|
||||||
|
.map_err(|e| CollectorError::SystemRead {
|
||||||
|
path: "/tmp".to_string(),
|
||||||
|
error: e.to_string(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
return Ok(Vec::new()); // Return empty if /tmp not available
|
||||||
|
}
|
||||||
|
|
||||||
|
let output_str = String::from_utf8(output.stdout)
|
||||||
|
.map_err(|e| CollectorError::Parse {
|
||||||
|
value: "df output".to_string(),
|
||||||
|
error: e.to_string(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let lines: Vec<&str> = output_str.lines().collect();
|
||||||
|
if lines.len() < 2 {
|
||||||
|
return Ok(Vec::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
let fields: Vec<&str> = lines[1].split_whitespace().collect();
|
||||||
|
if fields.len() < 4 {
|
||||||
|
return Ok(Vec::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
let total_bytes: u64 = fields[1].parse()
|
||||||
|
.map_err(|e: std::num::ParseIntError| CollectorError::Parse {
|
||||||
|
value: fields[1].to_string(),
|
||||||
|
error: e.to_string(),
|
||||||
|
})?;
|
||||||
|
let used_bytes: u64 = fields[2].parse()
|
||||||
|
.map_err(|e: std::num::ParseIntError| CollectorError::Parse {
|
||||||
|
value: fields[2].to_string(),
|
||||||
|
error: e.to_string(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let total_gb = total_bytes as f32 / (1024.0 * 1024.0 * 1024.0);
|
||||||
|
let used_gb = used_bytes as f32 / (1024.0 * 1024.0 * 1024.0);
|
||||||
|
let usage_percent = if total_bytes > 0 {
|
||||||
|
(used_bytes as f32 / total_bytes as f32) * 100.0
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut metrics = Vec::new();
|
||||||
|
let timestamp = chrono::Utc::now().timestamp() as u64;
|
||||||
|
|
||||||
|
metrics.push(Metric {
|
||||||
|
name: "memory_tmp_usage_percent".to_string(),
|
||||||
|
value: MetricValue::Float(usage_percent),
|
||||||
|
unit: Some("%".to_string()),
|
||||||
|
description: Some("tmpfs /tmp usage percentage".to_string()),
|
||||||
|
status: Status::Ok,
|
||||||
|
timestamp,
|
||||||
|
});
|
||||||
|
|
||||||
|
metrics.push(Metric {
|
||||||
|
name: "memory_tmp_used_gb".to_string(),
|
||||||
|
value: MetricValue::Float(used_gb),
|
||||||
|
unit: Some("GB".to_string()),
|
||||||
|
description: Some("tmpfs /tmp used space".to_string()),
|
||||||
|
status: Status::Ok,
|
||||||
|
timestamp,
|
||||||
|
});
|
||||||
|
|
||||||
|
metrics.push(Metric {
|
||||||
|
name: "memory_tmp_total_gb".to_string(),
|
||||||
|
value: MetricValue::Float(total_gb),
|
||||||
|
unit: Some("GB".to_string()),
|
||||||
|
description: Some("tmpfs /tmp total space".to_string()),
|
||||||
|
status: Status::Ok,
|
||||||
|
timestamp,
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(metrics)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
@ -202,7 +202,10 @@ impl SystemWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.storage_pools = pools.into_values().collect();
|
// Convert to sorted vec for consistent ordering
|
||||||
|
let mut pool_list: Vec<StoragePool> = pools.into_values().collect();
|
||||||
|
pool_list.sort_by(|a, b| a.name.cmp(&b.name)); // Sort alphabetically by name
|
||||||
|
self.storage_pools = pool_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract pool name from disk metric name
|
/// Extract pool name from disk metric name
|
||||||
@ -354,21 +357,6 @@ impl Widget for SystemWidget {
|
|||||||
self.memory_total_gb = Some(total);
|
self.memory_total_gb = Some(total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"disk_tmp_usage_percent" => {
|
|
||||||
if let MetricValue::Float(usage) = metric.value {
|
|
||||||
self.tmp_usage_percent = Some(usage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"disk_tmp_used_gb" => {
|
|
||||||
if let MetricValue::Float(used) = metric.value {
|
|
||||||
self.tmp_used_gb = Some(used);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"disk_tmp_total_gb" => {
|
|
||||||
if let MetricValue::Float(total) = metric.value {
|
|
||||||
self.tmp_total_gb = Some(total);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -430,8 +418,7 @@ impl Widget for SystemWidget {
|
|||||||
// Storage section with tree structure
|
// Storage section with tree structure
|
||||||
lines.extend(self.render_storage());
|
lines.extend(self.render_storage());
|
||||||
|
|
||||||
let paragraph = Paragraph::new(Text::from(lines))
|
let paragraph = Paragraph::new(Text::from(lines));
|
||||||
.block(Block::default().borders(Borders::ALL).title("System"));
|
|
||||||
|
|
||||||
frame.render_widget(paragraph, area);
|
frame.render_widget(paragraph, area);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user