From 3ad22cd4b50e63f84477e6ceb9ba74037927af42 Mon Sep 17 00:00:00 2001 From: Yoandy Rodriguez Date: Fri, 10 Apr 2020 10:10:05 -0400 Subject: [PATCH] feature: add filter requests --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 109 ++++++++++++---------------------------------------- src/util.rs | 8 +++- 4 files changed, 33 insertions(+), 88 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2cb338..28f79ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,7 +52,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "awstail" -version = "0.4.0" +version = "0.5.0" dependencies = [ "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 759c0a6..16667b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "awstail" -version = "0.4.0" +version = "0.5.0" authors = ["Yoandy Rodriguez "] edition = '2018' homepage = "https://github.com/yorodm/awstail" diff --git a/src/main.rs b/src/main.rs index 3c3bd25..53fba46 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,7 @@ -use clap::{App, Arg, ArgMatches}; use ctrlc; mod util; use humantime::parse_duration; use rusoto_core::Region; -use rusoto_logs::CloudWatchLogsClient; use std::str::FromStr; use structopt::StructOpt; use util::{ @@ -14,106 +12,49 @@ use util::{ #[derive(Debug, StructOpt)] #[structopt(name = "awstail", about = "Like tail but for Amazon")] pub struct CliOptions { - #[structopt(short, long)] + #[structopt(short, long,conflicts_with_all(&["group", "watch", "since", "filter"]))] list: bool, #[structopt(short, long)] - group: String, + group: Option, + #[structopt(short, long, default_value = "30s")] + watch: String, + #[structopt(short, long, default_value = "5min")] + since: String, #[structopt(short, long)] - watch: bool, -} - -fn get_options<'a>() -> ArgMatches<'a> { - return App::new("awstail") - .version("0.4.0") - .author("Yoandy Rodriguez ") - .about("like tail -f for AWS Cloudwatch") - .arg( - Arg::with_name("list") - .short("l") - .required(true) - .takes_value(false) - .help("List existing log groups") - .conflicts_with_all(&["group", "watch", "since"]), - ) - .arg( - Arg::with_name("group") - .short("g") - .required(true) - .takes_value(true) - .value_name("LOG_GROUP") - .conflicts_with("list") - .help("Log group name"), - ) - .arg( - Arg::with_name("region") - .short("r") - .required(false) - .value_name("REGION") - .help("AWS region (defaults to us-east-1)"), - ) - .arg( - Arg::with_name("profile") - .short("p") - .required(false) - .value_name("PROFILE") - .help("Profile if using other than 'default'"), - ) - .arg( - Arg::with_name("since") - .short("s") - .required(false) - .value_name("SINCE") - .help("Take logs since given time (defaults to 5 minutes)"), - ) - .arg( - Arg::with_name("watch") - .short("w") - .required(false) - .value_name("WATCH") - .help("Keep watching for new logs every n seconds (defaults to 10)"), - ) - .get_matches(); + filter: Option, + #[structopt(short, long, default_value = "us-east-1")] + region: String, + #[structopt(short, long, default_value = "default")] + profile: String, + #[structopt(short, long, default_value = "30s")] + timeout: String, } fn main() { ctrlc::set_handler(move || std::process::exit(0)) .expect("Could not set Ctrl+C handler...bailing out"); - let matches = get_options(); - let region = match matches.value_of("region") { - Some(m) => Region::from_str(m), - None => Ok(Region::UsEast1), - }; - let client = match matches.value_of("profile") { - Some(m) => client_with_profile(m, region.unwrap()), - None => CloudWatchLogsClient::new(region.unwrap()), - }; - if matches.is_present("list") { + let matches = CliOptions::from_args(); + let region = Region::from_str(&matches.region).unwrap(); + let client = client_with_profile(&matches.profile, region); + if matches.list { list_log_groups(&client).unwrap(); } else { - let group = matches.value_of("group").unwrap(); - let mtime = match matches.value_of("since") { - Some(m) => parse_duration(m), - None => parse_duration("5m"), - }; - let timeout = match matches.value_of("timeout") { - Some(m) => parse_duration(m), - None => parse_duration("30s"), - }; - let sleep_for = match matches.value_of("watch") { - Some(m) => parse_duration(m), - None => parse_duration("10s"), - }; + let group = matches.group.unwrap(); + let mtime = parse_duration(&matches.since); + let timeout = parse_duration(&matches.timeout); + let sleep_for = parse_duration(&matches.watch); + let filter = matches.filter; let mut token: Option = None; - let mut req = create_filter_request(group, mtime.unwrap(), token); + let mut req = create_filter_request(&group, mtime.unwrap(), filter.clone(), token); loop { match fetch_logs(&client, req, timeout.unwrap()) { AWSResponse::Token(x) => { token = Some(x); - req = create_filter_request(group, mtime.unwrap(), token); + req = create_filter_request(&group, mtime.unwrap(), filter.clone(), token); } AWSResponse::LastLog(t) => { token = None; - req = create_filter_from_timestamp(group, t, token); + req = create_filter_from_timestamp(&group, t, filter.clone(), token); std::thread::sleep(sleep_for.unwrap()); } }; diff --git a/src/util.rs b/src/util.rs index e0850b0..10a8e57 100644 --- a/src/util.rs +++ b/src/util.rs @@ -23,8 +23,9 @@ fn calculate_start_time(from: DateTime, delta: Duration) -> Option { } pub fn create_filter_request( - group: &str, + group: &String, start: Duration, + filter: Option, token: Option, ) -> FilterLogEventsRequest { let mut req = FilterLogEventsRequest::default(); @@ -32,19 +33,22 @@ pub fn create_filter_request( req.start_time = delta; req.next_token = token; req.limit = Some(100); + req.filter_pattern = filter; req.log_group_name = group.to_string(); return req; } pub fn create_filter_from_timestamp( - group: &str, + group: &String, start: Option, + filter: Option, token: Option, ) -> FilterLogEventsRequest { let mut req = FilterLogEventsRequest::default(); req.start_time = start; req.next_token = token; req.limit = Some(100); + req.filter_pattern = filter; req.log_group_name = group.to_string(); return req; }