Skip to content

Commit

Permalink
Copy the average metrics back to sum.
Browse files Browse the repository at this point in the history
Add progress bars/indicators for the different steps.
  • Loading branch information
nand4011 committed Apr 2, 2024
1 parent eed4ddd commit 7527a71
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 17 deletions.
39 changes: 39 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions momento/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ aws-sdk-cloudwatch = "1.19.0"
aws-sdk-dynamodb = "1.19.0"
aws-sdk-elasticache = "1.18.0"
phf = { version = "0.11", features = ["macros"] }
indicatif = "0.17.8"

[dev-dependencies]
assert_cmd = "2.0.2"
Expand Down
26 changes: 19 additions & 7 deletions momento/src/commands/cloud_linter/dynamodb.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;

use aws_config::SdkConfig;
use aws_sdk_dynamodb::types::{TimeToLiveDescription, TimeToLiveStatus};
use governor::DefaultDirectRateLimiter;
use indicatif::{ProgressBar, ProgressStyle};
use phf::{phf_map, Map};
use serde::{Deserialize, Serialize};

use crate::commands::cloud_linter::metrics::{Metric, MetricTarget, ResourceWithMetrics};
use crate::commands::cloud_linter::resource::{DynamoDbResource, Resource, ResourceType};
use crate::commands::cloud_linter::utils::rate_limit;
use crate::error::CliError;
use crate::utils::console::console_info;

const DDB_TABLE_METRICS: Map<&'static str, &'static [&'static str]> = phf_map! {
"Sum" => &[
"ConsumedReadCapacityUnits",
"ConsumedWriteCapacityUnits",
"ProvisionedReadCapacityUnits",
"ProvisionedWriteCapacityUnits",
"ReadThrottleEvents",
"WriteThrottleEvents",
"TimeToLiveDeletedItemCount",
Expand All @@ -39,6 +44,10 @@ const DDB_TABLE_METRICS: Map<&'static str, &'static [&'static str]> = phf_map! {

const DDB_GSI_METRICS: Map<&'static str, &'static [&'static str]> = phf_map! {
"Sum" => &[
"ConsumedReadCapacityUnits",
"ConsumedWriteCapacityUnits",
"ProvisionedReadCapacityUnits",
"ProvisionedWriteCapacityUnits",
"ReadThrottleEvents",
"WriteThrottleEvents",
],
Expand Down Expand Up @@ -140,10 +149,7 @@ impl ResourceWithMetrics for DynamoDbResource {
targets: DDB_GSI_METRICS,
})
}
ResourceType::ElastiCacheRedisNode => Err(CliError {
msg: "Invalid resource type".to_string(),
}),
ResourceType::ElastiCacheMemcachedNode => Err(CliError {
_ => Err(CliError {
msg: "Invalid resource type".to_string(),
}),
}
Expand All @@ -164,10 +170,14 @@ pub(crate) async fn get_ddb_resources(
) -> Result<Vec<Resource>, CliError> {
let ddb_client = aws_sdk_dynamodb::Client::new(&config);

console_info!("Listing Dynamo DB tables");
let bar = ProgressBar::new_spinner().with_message("Listing Dynamo DB tables");
bar.enable_steady_tick(Duration::from_millis(100));
let table_names = list_table_names(&ddb_client, Arc::clone(&limiter)).await?;
bar.finish();

console_info!("Describing tables");
let bar =
ProgressBar::new(table_names.len() as u64).with_message("Describing Dynamo DB tables");
bar.set_style(ProgressStyle::with_template(" {msg} {bar} {eta}").expect("invalid template"));
let mut resources = Vec::new();
for table_name in table_names {
let instances = fetch_ddb_resources(&ddb_client, &table_name, Arc::clone(&limiter)).await?;
Expand All @@ -176,7 +186,9 @@ pub(crate) async fn get_ddb_resources(
.map(Resource::DynamoDb)
.collect::<Vec<Resource>>();
resources.extend(wrapped_resources);
bar.inc(1);
}
bar.finish();

Ok(resources)
}
Expand Down
12 changes: 6 additions & 6 deletions momento/src/commands/cloud_linter/elasticache.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;

use aws_config::SdkConfig;
use aws_sdk_elasticache::types::CacheCluster;
use governor::DefaultDirectRateLimiter;
use indicatif::ProgressBar;
use phf::{phf_map, Map};
use serde::Serialize;

use crate::commands::cloud_linter::metrics::{Metric, MetricTarget, ResourceWithMetrics};
use crate::commands::cloud_linter::resource::{ElastiCacheResource, Resource, ResourceType};
use crate::commands::cloud_linter::utils::rate_limit;
use crate::error::CliError;
use crate::utils::console::console_info;

pub(crate) const CACHE_METRICS: Map<&'static str, &'static [&'static str]> = phf_map! {
"Sum" => &[
Expand Down Expand Up @@ -84,10 +85,7 @@ impl ResourceWithMetrics for ElastiCacheResource {
]),
targets: CACHE_METRICS,
}),
ResourceType::DynamoDbGsi => Err(CliError {
msg: "Invalid resource type".to_string(),
}),
ResourceType::DynamoDbTable => Err(CliError {
_ => Err(CliError {
msg: "Invalid resource type".to_string(),
}),
}
Expand All @@ -106,7 +104,6 @@ pub(crate) async fn get_elasticache_resources(
config: &SdkConfig,
limiter: Arc<DefaultDirectRateLimiter>,
) -> Result<Vec<Resource>, CliError> {
console_info!("Describing ElastiCache clusters");
let region = config.region().map(|r| r.as_ref()).ok_or(CliError {
msg: "No region configured for client".to_string(),
})?;
Expand All @@ -121,6 +118,8 @@ async fn describe_clusters(
elasticache_client: &aws_sdk_elasticache::Client,
limiter: Arc<DefaultDirectRateLimiter>,
) -> Result<Vec<CacheCluster>, CliError> {
let bar = ProgressBar::new_spinner().with_message("Describing ElastiCache clusters");
bar.enable_steady_tick(Duration::from_millis(100));
let mut elasticache_clusters = Vec::new();
let mut elasticache_stream = elasticache_client
.describe_cache_clusters()
Expand All @@ -142,6 +141,7 @@ async fn describe_clusters(
}
}
}
bar.finish();

Ok(elasticache_clusters)
}
Expand Down
2 changes: 2 additions & 0 deletions momento/src/commands/cloud_linter/linter_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ pub async fn run_cloud_linter(region: String) -> Result<(), CliError> {
let limiter = Arc::new(RateLimiter::direct(quota));

let mut resources = get_ddb_resources(&config, Arc::clone(&limiter)).await?;

let mut elasticache_resources =
get_elasticache_resources(&config, Arc::clone(&limiter)).await?;
resources.append(&mut elasticache_resources);

let resources = append_metrics_to_resources(&config, Arc::clone(&limiter), resources).await?;

let data_format = DataFormat { resources };
Expand Down
11 changes: 7 additions & 4 deletions momento/src/commands/cloud_linter/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
use std::collections::HashMap;
use std::sync::Arc;

use crate::commands::cloud_linter::resource::Resource;
use crate::commands::cloud_linter::utils::rate_limit;
use aws_config::SdkConfig;
use aws_sdk_cloudwatch::primitives::DateTime;
use aws_sdk_cloudwatch::types::Metric as CloudwatchMetric;
use aws_sdk_cloudwatch::types::{Dimension, MetricDataQuery, MetricStat};
use aws_sdk_cloudwatch::Client;
use chrono::{Duration, Utc};
use governor::DefaultDirectRateLimiter;
use indicatif::{ProgressBar, ProgressStyle};
use phf::Map;
use serde::{Deserialize, Serialize};

use crate::commands::cloud_linter::resource::Resource;
use crate::commands::cloud_linter::utils::rate_limit;
use crate::error::CliError;
use crate::utils::console::console_info;

#[derive(Serialize, Deserialize)]
pub(crate) struct Metric {
Expand Down Expand Up @@ -68,7 +68,8 @@ pub(crate) async fn append_metrics_to_resources(
limiter: Arc<DefaultDirectRateLimiter>,
mut resources: Vec<Resource>,
) -> Result<Vec<Resource>, CliError> {
console_info!("Getting metrics...");
let bar = ProgressBar::new(resources.len() as u64).with_message("Querying metrics");
bar.set_style(ProgressStyle::with_template(" {msg} {bar} {eta}").expect("invalid template"));
let metrics_client = Client::new(config);

for resource in &mut resources {
Expand All @@ -84,7 +85,9 @@ pub(crate) async fn append_metrics_to_resources(
.await?;
}
}
bar.inc(1);
}
bar.finish();

Ok(resources)
}
Expand Down

0 comments on commit 7527a71

Please sign in to comment.