diff --git a/peach-stats/src/sbot.rs b/peach-stats/src/sbot.rs index 22a9579..ce4de0b 100644 --- a/peach-stats/src/sbot.rs +++ b/peach-stats/src/sbot.rs @@ -16,7 +16,9 @@ use crate::StatsError; #[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct SbotStat { /// Current process state. - pub state: String, + pub state: Option, + /// Current process boot state. + pub boot_state: Option, /// Current process memory usage in bytes. pub memory: Option, /// Uptime for the process (if state is `active`). @@ -29,7 +31,8 @@ impl SbotStat { /// Default builder for `SbotStat`. fn default() -> Self { Self { - state: String::new(), + state: None, + boot_state: None, memory: None, uptime: None, downtime: None, @@ -54,7 +57,7 @@ pub fn sbot_stats() -> Result { for line in service_info.lines() { if line.starts_with("ActiveState=") { if let Some(state) = line.strip_prefix("ActiveState=") { - status.state = state.to_string() + status.state = Some(state.to_string()) } } else if line.starts_with("MemoryCurrent=") { if let Some(memory) = line.strip_prefix("MemoryCurrent=") { @@ -68,15 +71,25 @@ pub fn sbot_stats() -> Result { .arg("status") .arg("go-sbot.service") .output() - .unwrap(); + .map_err(StatsError::Systemctl)?; let service_status = str::from_utf8(&status_output.stdout).map_err(StatsError::Utf8String)?; - // example of the output line we're looking for: - // `Active: active (running) since Mon 2022-01-24 16:22:51 SAST; 4min 14s ago` - for line in service_status.lines() { - if line.contains("Active:") { + // example of the output line we're looking for: + // `Loaded: loaded (/home/glyph/.config/systemd/user/go-sbot.service; enabled; vendor + // preset: enabled)` + if line.contains("Loaded:") { + let before_boot_state = line.find(';'); + let after_boot_state = line.rfind(';'); + if let (Some(start), Some(end)) = (before_boot_state, after_boot_state) { + // extract the enabled / disabled from the `Loaded: ...` line + // using the index of the first ';' + 2 and the last ';' + status.boot_state = Some(line[start + 2..end].to_string()); + } + // example of the output line we're looking for here: + // `Active: active (running) since Mon 2022-01-24 16:22:51 SAST; 4min 14s ago` + } else if line.contains("Active:") { let before_time = line.find(';'); let after_time = line.find(" ago"); if let (Some(start), Some(end)) = (before_time, after_time) { @@ -84,10 +97,10 @@ pub fn sbot_stats() -> Result { // using the index of ';' + 2 and the index of " ago" let time = Some(&line[start + 2..end]); // if service is active then the `time` reading is uptime - if status.state == "active" { + if status.state == Some("active".to_string()) { status.uptime = time.map(|t| t.to_string()) // if service is inactive then the `time` reading is downtime - } else if status.state == "inactive" { + } else if status.state == Some("inactive".to_string()) { status.downtime = time.map(|t| t.to_string()) } }