Testing
This commit is contained in:
parent
fb91d8346f
commit
9c836e0862
@ -312,7 +312,7 @@ impl Collector for BackupCollector {
|
|||||||
// Try to get borgbackup metrics first, fall back to restic if not available
|
// Try to get borgbackup metrics first, fall back to restic if not available
|
||||||
let borgbackup_result = self.get_borgbackup_metrics().await;
|
let borgbackup_result = self.get_borgbackup_metrics().await;
|
||||||
|
|
||||||
let (backup_info, overall_status) = match borgbackup_result {
|
let (backup_info, overall_status) = match &borgbackup_result {
|
||||||
Ok(borg_metrics) => {
|
Ok(borg_metrics) => {
|
||||||
// Parse borgbackup timestamp to DateTime
|
// Parse borgbackup timestamp to DateTime
|
||||||
let last_success = chrono::DateTime::from_timestamp(borg_metrics.timestamp, 0);
|
let last_success = chrono::DateTime::from_timestamp(borg_metrics.timestamp, 0);
|
||||||
@ -329,6 +329,7 @@ impl Collector for BackupCollector {
|
|||||||
last_success,
|
last_success,
|
||||||
last_failure: None, // borgbackup metrics don't include failure info
|
last_failure: None, // borgbackup metrics don't include failure info
|
||||||
size_gb: borg_metrics.repository.total_repository_size_bytes as f32 / (1024.0 * 1024.0 * 1024.0),
|
size_gb: borg_metrics.repository.total_repository_size_bytes as f32 / (1024.0 * 1024.0 * 1024.0),
|
||||||
|
latest_archive_size_gb: Some(borg_metrics.repository.latest_archive_size_bytes as f32 / (1024.0 * 1024.0 * 1024.0)),
|
||||||
snapshot_count: borg_metrics.repository.total_archives as u32,
|
snapshot_count: borg_metrics.repository.total_archives as u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -356,12 +357,14 @@ impl Collector for BackupCollector {
|
|||||||
last_success: stats.last_success,
|
last_success: stats.last_success,
|
||||||
last_failure,
|
last_failure,
|
||||||
size_gb: stats.total_size as f32 / (1024.0 * 1024.0 * 1024.0),
|
size_gb: stats.total_size as f32 / (1024.0 * 1024.0 * 1024.0),
|
||||||
|
latest_archive_size_gb: None, // Restic doesn't provide this easily
|
||||||
snapshot_count: stats.snapshot_count,
|
snapshot_count: stats.snapshot_count,
|
||||||
},
|
},
|
||||||
Err(_) => BackupInfo {
|
Err(_) => BackupInfo {
|
||||||
last_success: None,
|
last_success: None,
|
||||||
last_failure,
|
last_failure,
|
||||||
size_gb: 0.0,
|
size_gb: 0.0,
|
||||||
|
latest_archive_size_gb: None,
|
||||||
snapshot_count: 0,
|
snapshot_count: 0,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -380,13 +383,27 @@ impl Collector for BackupCollector {
|
|||||||
last_message: None,
|
last_message: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
let backup_metrics = json!({
|
// Add disk information if available from borgbackup metrics
|
||||||
|
let mut backup_json = json!({
|
||||||
"overall_status": overall_status,
|
"overall_status": overall_status,
|
||||||
"backup": backup_info,
|
"backup": backup_info,
|
||||||
"service": service_data,
|
"service": service_data,
|
||||||
"timestamp": Utc::now()
|
"timestamp": Utc::now()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If we got borgbackup metrics, include disk information
|
||||||
|
if let Ok(borg_metrics) = &borgbackup_result {
|
||||||
|
backup_json["disk"] = json!({
|
||||||
|
"device": borg_metrics.backup_disk.device,
|
||||||
|
"health": borg_metrics.backup_disk.health,
|
||||||
|
"total_gb": borg_metrics.backup_disk.total_bytes as f32 / (1024.0 * 1024.0 * 1024.0),
|
||||||
|
"used_gb": borg_metrics.backup_disk.used_bytes as f32 / (1024.0 * 1024.0 * 1024.0),
|
||||||
|
"usage_percent": borg_metrics.backup_disk.usage_percent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let backup_metrics = backup_json;
|
||||||
|
|
||||||
Ok(CollectorOutput {
|
Ok(CollectorOutput {
|
||||||
agent_type: AgentType::Backup,
|
agent_type: AgentType::Backup,
|
||||||
data: backup_metrics,
|
data: backup_metrics,
|
||||||
@ -419,6 +436,7 @@ struct BackupInfo {
|
|||||||
last_success: Option<DateTime<Utc>>,
|
last_success: Option<DateTime<Utc>>,
|
||||||
last_failure: Option<DateTime<Utc>>,
|
last_failure: Option<DateTime<Utc>>,
|
||||||
size_gb: f32,
|
size_gb: f32,
|
||||||
|
latest_archive_size_gb: Option<f32>,
|
||||||
snapshot_count: u32,
|
snapshot_count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -97,6 +97,8 @@ pub struct BackupMetrics {
|
|||||||
pub overall_status: BackupStatus,
|
pub overall_status: BackupStatus,
|
||||||
pub backup: BackupInfo,
|
pub backup: BackupInfo,
|
||||||
pub service: BackupServiceInfo,
|
pub service: BackupServiceInfo,
|
||||||
|
#[serde(default)]
|
||||||
|
pub disk: Option<BackupDiskInfo>,
|
||||||
pub timestamp: DateTime<Utc>,
|
pub timestamp: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +107,8 @@ pub struct BackupInfo {
|
|||||||
pub last_success: Option<DateTime<Utc>>,
|
pub last_success: Option<DateTime<Utc>>,
|
||||||
pub last_failure: Option<DateTime<Utc>>,
|
pub last_failure: Option<DateTime<Utc>>,
|
||||||
pub size_gb: f32,
|
pub size_gb: f32,
|
||||||
|
#[serde(default)]
|
||||||
|
pub latest_archive_size_gb: Option<f32>,
|
||||||
pub snapshot_count: u32,
|
pub snapshot_count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +119,15 @@ pub struct BackupServiceInfo {
|
|||||||
pub last_message: Option<String>,
|
pub last_message: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct BackupDiskInfo {
|
||||||
|
pub device: String,
|
||||||
|
pub health: String,
|
||||||
|
pub total_gb: f32,
|
||||||
|
pub used_gb: f32,
|
||||||
|
pub usage_percent: f32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum BackupStatus {
|
pub enum BackupStatus {
|
||||||
Healthy,
|
Healthy,
|
||||||
|
|||||||
@ -35,60 +35,68 @@ fn render_metrics(frame: &mut Frame, _host: &HostDisplayData, metrics: &BackupMe
|
|||||||
let mut data = WidgetData::new(
|
let mut data = WidgetData::new(
|
||||||
"Backups",
|
"Backups",
|
||||||
Some(WidgetStatus::new(widget_status)),
|
Some(WidgetStatus::new(widget_status)),
|
||||||
vec!["Aspect".to_string(), "Details".to_string()]
|
vec!["Backup".to_string(), "Status".to_string(), "Details".to_string()]
|
||||||
);
|
);
|
||||||
|
|
||||||
let repo_status = repo_status_level(metrics);
|
// Latest backup
|
||||||
|
let (latest_status, latest_time) = if let Some(last_success) = metrics.backup.last_success.as_ref() {
|
||||||
|
let hours_ago = chrono::Utc::now().signed_duration_since(*last_success).num_hours();
|
||||||
|
let time_str = if hours_ago < 24 {
|
||||||
|
format!("{}h ago", hours_ago)
|
||||||
|
} else {
|
||||||
|
format!("{}d ago", hours_ago / 24)
|
||||||
|
};
|
||||||
|
(StatusLevel::Ok, time_str)
|
||||||
|
} else {
|
||||||
|
(StatusLevel::Warning, "Never".to_string())
|
||||||
|
};
|
||||||
|
|
||||||
data.add_row(
|
data.add_row(
|
||||||
Some(WidgetStatus::new(repo_status)),
|
Some(WidgetStatus::new(latest_status)),
|
||||||
|
vec![],
|
||||||
|
vec![
|
||||||
|
"Latest".to_string(),
|
||||||
|
latest_time,
|
||||||
|
format!("{:.1} GiB", metrics.backup.latest_archive_size_gb.unwrap_or(metrics.backup.size_gb)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Repository total
|
||||||
|
data.add_row(
|
||||||
|
Some(WidgetStatus::new(StatusLevel::Ok)),
|
||||||
vec![],
|
vec![],
|
||||||
vec![
|
vec![
|
||||||
"Repo".to_string(),
|
"Repo".to_string(),
|
||||||
format!(
|
format!("{} archives", metrics.backup.snapshot_count),
|
||||||
"Snapshots: {} • Size: {:.1} GiB",
|
format!("{:.1} GiB total", metrics.backup.size_gb),
|
||||||
metrics.backup.snapshot_count, metrics.backup.size_gb
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
let service_status = service_status_level(metrics);
|
// Disk usage
|
||||||
data.add_row(
|
if let Some(disk) = &metrics.disk {
|
||||||
Some(WidgetStatus::new(service_status)),
|
let disk_status = match disk.health.as_str() {
|
||||||
vec![],
|
"ok" => StatusLevel::Ok,
|
||||||
vec![
|
"failed" => StatusLevel::Error,
|
||||||
"Service".to_string(),
|
_ => StatusLevel::Warning,
|
||||||
format!(
|
|
||||||
"Enabled: {} • Pending jobs: {}",
|
|
||||||
metrics.service.enabled, metrics.service.pending_jobs
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(last_failure) = metrics.backup.last_failure.as_ref() {
|
|
||||||
data.add_row(
|
|
||||||
Some(WidgetStatus::new(StatusLevel::Error)),
|
|
||||||
vec![],
|
|
||||||
vec![
|
|
||||||
"Last failure".to_string(),
|
|
||||||
format_timestamp(Some(last_failure)),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(message) = metrics.service.last_message.as_ref() {
|
|
||||||
let status_level = match metrics.overall_status {
|
|
||||||
BackupStatus::Failed => StatusLevel::Error,
|
|
||||||
BackupStatus::Warning => StatusLevel::Warning,
|
|
||||||
BackupStatus::Unknown => StatusLevel::Unknown,
|
|
||||||
BackupStatus::Healthy => StatusLevel::Ok,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
data.add_row(
|
data.add_row(
|
||||||
Some(WidgetStatus::new(status_level)),
|
Some(WidgetStatus::new(disk_status)),
|
||||||
vec![],
|
vec![],
|
||||||
vec![
|
vec![
|
||||||
"Last message".to_string(),
|
"Disk usage".to_string(),
|
||||||
message.clone(),
|
disk.health.clone(),
|
||||||
|
format!("{:.0} GB, {:.0}% used", disk.total_gb, disk.usage_percent),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
data.add_row(
|
||||||
|
Some(WidgetStatus::new(StatusLevel::Unknown)),
|
||||||
|
vec![],
|
||||||
|
vec![
|
||||||
|
"Disk usage".to_string(),
|
||||||
|
"Unknown".to_string(),
|
||||||
|
"—".to_string(),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user