From 9a64b88971757400e05872809c7302e2f005cd6a Mon Sep 17 00:00:00 2001 From: Yoandy Rodriguez Date: Tue, 28 Jan 2020 15:21:13 -0500 Subject: [PATCH] feature: add list logs features --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 68 +++++++++++++++++++++++++++++++++++------ src/{cmd.rs => util.rs} | 61 ++++-------------------------------- 4 files changed, 66 insertions(+), 67 deletions(-) rename src/{cmd.rs => util.rs} (68%) diff --git a/Cargo.lock b/Cargo.lock index fa71281..2dbf7eb 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.3.0" +version = "0.4.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 14cee86..63b6e18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "awstail" -version = "0.3.0" +version = "0.4.0" authors = ["Yoandy Rodriguez "] edition = '2018' homepage = "https://github.com/yorodm/awstail" diff --git a/src/main.rs b/src/main.rs index f735acc..52a96df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,18 @@ -use clap::{App, Arg}; -use cmd::run; +use clap::{App, Arg, ArgMatches}; use ctrlc; -mod cmd; +mod util; +use humantime::parse_duration; +use rusoto_core::Region; +use rusoto_logs::CloudWatchLogsClient; +use std::str::FromStr; +use util::{ + client_with_profile, create_filter_from_timestamp, create_filter_request, fetch_logs, + list_log_groups, AWSResponse, +}; -fn main() { - ctrlc::set_handler(move || std::process::exit(0)) - .expect("Could not set Ctrl+C handler...bailing out"); - let matches = App::new("awstail") - .version("0.3.0") +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( @@ -56,7 +61,50 @@ fn main() { .help("Keep watching for new logs every n seconds (defaults to 10)"), ) .get_matches(); - if let Err(_e) = run(matches) { - std::process::exit(0); +} + +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") { + 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 mut token: Option = None; + let mut req = create_filter_request(group, mtime.unwrap(), token); + loop { + match fetch_logs(&client, req, timeout.unwrap()) { + AWSResponse::Token(x) => { + token = Some(x); + req = create_filter_request(group, mtime.unwrap(), token); + } + AWSResponse::LastLog(t) => { + token = None; + req = create_filter_from_timestamp(group, t, token); + std::thread::sleep(sleep_for.unwrap()); + } + }; + } } } diff --git a/src/cmd.rs b/src/util.rs similarity index 68% rename from src/cmd.rs rename to src/util.rs index 08335ba..e0850b0 100644 --- a/src/cmd.rs +++ b/src/util.rs @@ -1,20 +1,15 @@ use chrono::Duration as Delta; use chrono::{DateTime, Local, NaiveDateTime, Utc}; -use clap::ArgMatches; use console::Style; -use humantime::parse_duration; -use rusoto_core::HttpClient; -use rusoto_core::Region; +use rusoto_core::{HttpClient, Region}; use rusoto_credential::{AutoRefreshingProvider, ChainProvider, ProfileProvider}; use rusoto_logs::{ - CloudWatchLogs, CloudWatchLogsClient, DescribeLogGroupsRequest, DescribeLogGroupsResponse, - FilterLogEventsRequest, + CloudWatchLogs, CloudWatchLogsClient, DescribeLogGroupsRequest, FilterLogEventsRequest, }; use std::result::Result; -use std::str::FromStr; use std::time::Duration; -enum AWSResponse { +pub enum AWSResponse { Token(String), LastLog(Option), } @@ -27,7 +22,7 @@ fn calculate_start_time(from: DateTime, delta: Duration) -> Option { return Some(utc_time.timestamp_millis()); } -fn create_filter_request( +pub fn create_filter_request( group: &str, start: Duration, token: Option, @@ -41,7 +36,7 @@ fn create_filter_request( return req; } -fn create_filter_from_timestamp( +pub fn create_filter_from_timestamp( group: &str, start: Option, token: Option, @@ -67,7 +62,7 @@ fn print_date(time: Option) -> String { } } -fn fetch_logs( +pub fn fetch_logs( client: &CloudWatchLogsClient, req: FilterLogEventsRequest, timeout: Duration, @@ -145,47 +140,3 @@ pub fn list_log_groups(c: &CloudWatchLogsClient) -> Result<(), String> { } Ok(()) } - -pub fn run(matches: ArgMatches) -> Result<(), String> { - 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") { - return list_log_groups(&client); - } 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 mut token: Option = None; - let mut req = create_filter_request(group, mtime.unwrap(), token); - loop { - match fetch_logs(&client, req, timeout.unwrap()) { - AWSResponse::Token(x) => { - token = Some(x); - req = create_filter_request(group, mtime.unwrap(), token); - } - AWSResponse::LastLog(t) => { - token = None; - req = create_filter_from_timestamp(group, t, token); - std::thread::sleep(sleep_for.unwrap()); - } - }; - } - } - Ok(()) -}