From 73526976a168e62cac3f9e7a89f679f7355ca368 Mon Sep 17 00:00:00 2001 From: Keagan McClelland Date: Thu, 12 Aug 2021 10:35:49 -0600 Subject: [PATCH] adds log querying (#401) * adds log querying * Apply suggestions from code review Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> * formatting Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> --- appmgr/src/error.rs | 2 ++ appmgr/src/lib.rs | 1 + appmgr/src/system.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 appmgr/src/system.rs diff --git a/appmgr/src/error.rs b/appmgr/src/error.rs index 85d5081e1..4509804e6 100644 --- a/appmgr/src/error.rs +++ b/appmgr/src/error.rs @@ -49,6 +49,7 @@ pub enum ErrorKind { ParseNetAddress = 41, ParseSshKey = 42, SoundError = 43, + ParseTimestamp = 44, } impl ErrorKind { pub fn as_str(&self) -> &'static str { @@ -97,6 +98,7 @@ impl ErrorKind { ParseNetAddress => "Net Address Parsing Error", ParseSshKey => "SSH Key Parsing Error", SoundError => "Sound Interface Error", + ParseTimestamp => "Timestamp Parsing Error", } } } diff --git a/appmgr/src/lib.rs b/appmgr/src/lib.rs index 13b90b943..04ad4d4d7 100644 --- a/appmgr/src/lib.rs +++ b/appmgr/src/lib.rs @@ -38,6 +38,7 @@ pub mod s9pk; pub mod sound; pub mod ssh; pub mod status; +pub mod system; pub mod util; pub mod version; pub mod volume; diff --git a/appmgr/src/system.rs b/appmgr/src/system.rs new file mode 100644 index 000000000..d09652e32 --- /dev/null +++ b/appmgr/src/system.rs @@ -0,0 +1,65 @@ +use chrono::{DateTime, Utc}; +use clap::ArgMatches; +use rpc_toolkit::command; +use tokio::process::Command; + +use crate::context::RpcContext; +use crate::{Error, ErrorKind, ResultExt}; + +pub const SYSTEMD_UNIT: &'static str = "embassyd"; + +fn parse_datetime(text: &str, _matches: &ArgMatches) -> Result, Error> { + text.parse().with_kind(ErrorKind::ParseTimestamp) +} + +#[command(rpc_only)] +pub async fn logs( + #[context] _ctx: RpcContext, + #[arg(parse(crate::system::parse_datetime))] before: Option>, + #[arg] limit: Option, +) -> Result, Error> { + let before = before.unwrap_or(Utc::now()); + let limit = limit.unwrap_or(50); + // Journalctl has unexpected behavior where "until" does not play well with "lines" unless the output is reversed. + // Keep this in mind if you are changing the code below + let out = Command::new("journalctl") + .args(&[ + "-u", + SYSTEMD_UNIT, + &format!( + "-U\"{} {} UTC\"", + before.date().naive_utc(), + before.time().format("%H:%M:%S") + ), + "--output=short-iso", + "--no-hostname", + "--utc", + "--reverse", + &format!("-n{}", limit), + ]) + .output() + .await? + .stdout; + let out_string = String::from_utf8(out)?; + let lines = out_string.lines(); + let mut split_lines = lines + .skip(1) // ditch the journalctl header + .map(|s| { + // split the timestamp off from the log line + let (ts, l) = s.split_once(" ").unwrap(); + (ts.to_owned(), l.to_owned()) + }) + .collect::>(); + // reverse output again because we reversed it above + split_lines.reverse(); + Ok(split_lines) +} + +#[test] +pub fn test_output() { + println!( + "{} {} UTC", + Utc::now().date().naive_utc(), + Utc::now().time().format("%H:%M:%S") + ) +}