cargo-aws-lambda 0.3.0

Cross-compile, package and deploy AWS Lambda functions with only docker as a dependency using cargo aws-lambda.
use rusoto_core::credential::{ChainProvider, ProfileProvider, StaticProvider};
use rusoto_core::{HttpClient, Region};
use rusoto_logs::{CloudWatchLogs, CloudWatchLogsClient, FilterLogEventsRequest};
use std::collections::HashSet;
use std::str::FromStr;
use std::time::{Duration, SystemTime};
use crate::Opt;

pub(crate) fn create_client(opt: &Opt, region: &str) -> CloudWatchLogsClient {
    let dispatcher = HttpClient::new().expect("failed to create request dispatcher");
    let region = Region::from_str(region).unwrap();

    match (&opt.access_key, &opt.secret_key, &opt.profile) {
        (Some(access_key), Some(secret_key), _) => {
            let creds = StaticProvider::new_minimal(access_key.to_owned(), secret_key.to_owned());
            CloudWatchLogsClient::new_with(dispatcher, creds, region)
        },
        (_, _, Some(profile)) => {
            let mut creds = ProfileProvider::new().unwrap();
            creds.set_profile(profile.to_owned());
            CloudWatchLogsClient::new_with(dispatcher, creds, region)
        },
        _ => {
            let creds = ChainProvider::new();
            CloudWatchLogsClient::new_with(dispatcher, creds, region)
        }
    }
}

pub fn tail(
    logs_client: &CloudWatchLogsClient,
    function_name: &str,
) -> Result<(), Box<dyn ::std::error::Error>> {
    let unix = || {
        SystemTime::now()
            .duration_since(SystemTime::UNIX_EPOCH)
            .unwrap()
            .as_millis() as i64
            - 5 * 60 * 1000
    };
    let user_time = SystemTime::now()
        .duration_since(SystemTime::UNIX_EPOCH)
        .unwrap()
        .as_millis() as i64;
    let mut next_token = None;
    let mut start_time = Some(unix());
    let mut seen = HashSet::new();

    loop {
        let input = FilterLogEventsRequest {
            end_time: None,
            filter_pattern: None,
            limit: Some(10000),
            log_group_name: format!("/aws/lambda/{}", function_name),
            log_stream_name_prefix: None,
            log_stream_names: None,
            next_token: next_token.clone(),
            start_time,
        };

        let res = logs_client.filter_log_events(input).sync()?;

        if let Some(events) = res.events {
            for event in events {
                let ts = event.timestamp.unwrap_or(::std::i64::MAX);
                if !seen.contains(event.event_id.as_ref().unwrap()) && ts > user_time {
                    print!("{}", event.message.unwrap());
                    seen.insert(event.event_id.unwrap().clone());
                }
            }
        }

        next_token = res.next_token;

        if next_token.is_none() {
            start_time = Some(unix());
        }
        ::std::thread::sleep(Duration::from_millis(3000));
    }
}