diff --git a/snitch-cli/src/main.rs b/snitch-cli/src/main.rs index c538e93..f986372 100644 --- a/snitch-cli/src/main.rs +++ b/snitch-cli/src/main.rs @@ -1,3 +1,5 @@ +use std::io::{stdin, BufRead}; + use chrono::Local; use clap::Parser; use eyre::{eyre, WrapErr}; @@ -17,9 +19,13 @@ struct Opt { #[clap(short, long, env = "SNITCH_SEVERITY", default_value = "Error")] severity: Severity, - /// Name of this service + /// Treat each line of the message as its own log message. + #[clap(short, long, env = "SNITCH_LINES")] + lines: bool, + + /// Log message to snitch. If this is omitted, the message will be read from stdin. #[clap(env = "SNITCH_MESSAGE")] - message: String, + message: Option, } fn main() { @@ -27,15 +33,55 @@ fn main() { eprintln!("snitch error: {e:?}"); } } + fn run() -> eyre::Result<()> { let opt = Opt::parse(); color_eyre::install()?; + if let Some(message) = &opt.message { + log_from(&opt, message.as_bytes()) + } else { + let stdin = stdin(); + log_from(&opt, stdin.lock()) + } +} + +/// Consume a reader and log everything to snitch +fn log_from(opt: &Opt, r: impl BufRead) -> eyre::Result<()> { + if opt.lines { + log_lines(opt, r) + } else { + log_reader(opt, r) + } +} + +/// Consume a reader and log everything as a single message to snitch +fn log_reader(opt: &Opt, mut r: impl BufRead) -> eyre::Result<()> { + let mut s = String::new(); + r.read_to_string(&mut s)?; + log_message(opt, &s) +} + +/// Log each line from a reader to snitch +fn log_lines(opt: &Opt, r: impl BufRead) -> eyre::Result<()> { + for line in r.lines() { + let line = line.wrap_err("Failed to read from stdin")?; + let line = line.trim(); + if !line.is_empty() { + log_message(&opt, &line)?; + } + } + + Ok(()) +} + +/// Log a single message to snitch +fn log_message(opt: &Opt, message: &str) -> eyre::Result<()> { let message = LogMsg { time: Some(Local::now()), severity: opt.severity, - service: opt.service, - message: opt.message, + service: opt.service.clone(), + message: message.to_string(), hostname: probe_hostname(), file: None, line: None, diff --git a/snitch-lib/src/message.rs b/snitch-lib/src/message.rs index e725f85..4c8936d 100644 --- a/snitch-lib/src/message.rs +++ b/snitch-lib/src/message.rs @@ -4,7 +4,7 @@ use chrono::{DateTime, Local}; use eyre::{eyre, ContextCompat}; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] pub enum Severity { Fatal, Error,