in usecases/guest-webapp-sample/lib/blea-dashboard-stack.ts [20:793]
constructor(scope: cdk.Construct, id: string, props: BLEADashboardStackProps) {
super(scope, id, props);
/*
*
* Metrics definition
* Note: These definitions do not create any resource. Just dashboard widget refer to these metrics.
*
*/
// CloudFront
// Available metrics: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/programming-cloudwatch-metrics.html
const cfRequests = new cw.Metric({
namespace: 'AWS/CloudFront',
metricName: 'Requests',
dimensions: {
Region: 'Global',
DistributionId: props.webFront.cfDistribution.distributionId,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.NONE,
region: 'us-east-1', // cloudfront defined on us-east-1
});
const cf5xxErrorRate = new cw.Metric({
namespace: 'AWS/CloudFront',
metricName: '5xxErrorRate',
dimensions: {
Region: 'Global',
DistributionId: props.webFront.cfDistribution.distributionId,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.PERCENT,
region: 'us-east-1', // cloudfront defined on us-east-1
});
const cf4xxErrorRate = new cw.Metric({
namespace: 'AWS/CloudFront',
metricName: '4xxErrorRate',
dimensions: {
Region: 'Global',
DistributionId: props.webFront.cfDistribution.distributionId,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.PERCENT,
region: 'us-east-1', // cloudfront defined on us-east-1
});
const cfTotalErrorRate = new cw.Metric({
namespace: 'AWS/CloudFront',
metricName: 'TotalErrorRate',
dimensions: {
Region: 'Global',
DistributionId: props.webFront.cfDistribution.distributionId,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.PERCENT,
region: 'us-east-1', // cloudfront defined on us-east-1
});
// Application Load Balancing
// Available metrics: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html
const albRequests = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'RequestCount',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const albNewConnectionCount = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'NewConnectionCount',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const albRejectedConnectionCount = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'RejectedConnectionCount',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const albTLSNegotiationErrors = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'ClientTLSNegotiationErrorCount',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const alb5xxErrors = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'HTTPCode_ELB_5XX_Count',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const alb4xxErrors = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'HTTPCode_ELB_4XX_Count',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
// Target Group
// Available metrics: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html
const albTgRequests = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'HTTPCode_Target_2XX_Count',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const albTg5xxErrors = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'HTTPCode_Target_5XX_Count',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const albTg4xxErrors = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'HTTPCode_Target_4XX_Count',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const albTgConnectionErrors = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'TargetConnectionErrorCount',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const albTgTLSNegotiationErrors = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'TargetConnectionErrorCount',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const albTgResponseTime = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'TargetResponseTime',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.SECONDS,
});
const albTgRequestCountPerTarget = new cw.Metric({
namespace: 'AWS/ApplicationELB',
metricName: 'RequestCountPerTarget',
dimensions: {
LoadBalancer: props.webFront.appAlb.loadBalancerFullName,
TargetGroup: props.appTargetGroupName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
// ECS
// Available metrics:
// - https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cloudwatch-metrics.html
// - https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-metrics-ECS.html
const ecsCPUUtilization = new cw.Metric({
namespace: 'AWS/ECS',
metricName: 'CPUUtilization',
dimensions: {
ClusterName: props.ecsClusterName,
ServiceName: props.ecsServiceName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.PERCENT,
});
const ecsMemoryUtilization = new cw.Metric({
namespace: 'AWS/ECS',
metricName: 'MemoryUtilization',
dimensions: {
ClusterName: props.ecsClusterName,
ServiceName: props.ecsServiceName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.PERCENT,
});
const ecsDesiredTaskCount = new cw.Metric({
namespace: 'ECS/ContainerInsights',
metricName: 'DesiredTaskCount',
dimensions: {
ClusterName: props.ecsClusterName,
ServiceName: props.ecsServiceName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const ecsRunningTaskCount = new cw.Metric({
namespace: 'ECS/ContainerInsights',
metricName: 'RunningTaskCount',
dimensions: {
ClusterName: props.ecsClusterName,
ServiceName: props.ecsServiceName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const ecsPendingTaskCount = new cw.Metric({
namespace: 'ECS/ContainerInsights',
metricName: 'PendingTaskCount',
dimensions: {
ClusterName: props.ecsClusterName,
ServiceName: props.ecsServiceName,
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
// Aurora
// Available metrics: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraMySQL.Monitoring.Metrics.html
// for Writer & Reader
const dbWriterDatabaseConnections = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'DatabaseConnections',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "Writer: ${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const dbReaderDatabaseConnections = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'DatabaseConnections',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'READER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.SUM,
label: "Reader: ${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.COUNT,
});
const dbWriterCPUUtilization = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'CPUUtilization',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "Writer: ${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.PERCENT,
});
const dbReaderCPUUtilization = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'CPUUtilization',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'READER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "Reader: ${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.PERCENT,
});
const dbWriterFreeableMemory = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'FreeableMemory',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "Writer: ${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MEGABITS,
});
const dbReaderFreeableMemory = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'FreeableMemory',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'READER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "Reader: ${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MEGABITS,
});
const dbWriterFreeLocalStorage = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'FreeLocalStorage',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "Writer: ${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MEGABITS,
});
const dbReaderFreeLocalStorage = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'FreeLocalStorage',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'READER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "Reader: ${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MEGABITS,
});
// for Writer
const dbWriterInsertLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'InsertLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MILLISECONDS,
});
const dbWriterSelectLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'SelectLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MILLISECONDS,
});
const dbWriterUpdateLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'UpdateLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MILLISECONDS,
});
const dbWriterCommitLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'CommitLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MILLISECONDS,
});
const dbWriterDDLLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'DDLLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MILLISECONDS,
});
const dbWriterDeleteLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'DeleteLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MILLISECONDS,
});
const dbWriterDMLLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'DeleteLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MILLISECONDS,
});
const dbWriterReadLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'ReadLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.SECONDS,
});
const dbWriterWriteLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'WriteLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'WRITER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.SECONDS,
});
// for Reader
const dbReaderSelectLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'SelectLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'READER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.MILLISECONDS,
});
const dbReaderReadLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'ReadLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'READER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.SECONDS,
});
const dbReaderWriteLatency = new cw.Metric({
namespace: 'AWS/RDS',
metricName: 'WriteLatency',
dimensions: {
DBClusterIdentifier: props.dbClusterName,
Role: 'READER',
},
period: cdk.Duration.minutes(1),
statistic: cw.Statistic.AVERAGE,
label: "${PROP('MetricName')} /${PROP('Period')}sec",
unit: cw.Unit.SECONDS,
});
/*
*
* Dashboard definition
*
* Note:
* - This sample summarize widgets in metrics group such as Requests, ResponseTime, Errors, Resources.
* We added header text widget on top of each metrics group.
* - If you use the name CloudWatch-Default, the dashboard appears on the overview on the CloudWatch home page.
* See: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/create_dashboard.html
*
* - Widget Array Structure (height, width, x, y)
* width=24 means Full screen width. This sample is define widget height as 6.
* You can just add widgets in array, x and y axis are defined well by CDK.
* See: https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/CloudWatch-Dashboard-Body-Structure.html#CloudWatch-Dashboard-Properties-Widgets-Structure
*
* - "stacked: true," means stack(add) each metrics.
*
* - Label for each metrics is defined on metrics object and you can use "Dynamic Label".
* We usually use "${PROP('MetricName')} /${PROP('Period')}sec" so we can see period of the metrics.
* See: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/graph-dynamic-labels.html
*
*/
const dashboard = new cw.Dashboard(this, 'Dashboard', {
dashboardName: props.dashboardName,
});
dashboard.addWidgets(
// Canary
new cw.TextWidget({
markdown: '# Canary',
height: 1,
width: 24,
}),
new cw.AlarmWidget({
title: 'Canary response time',
width: 12,
height: 6,
alarm: props.canaryDurationAlarm,
}),
new cw.AlarmWidget({
title: 'Canary request failed',
width: 12,
height: 6,
alarm: props.canaryFailedAlarm,
}),
// Requests
new cw.TextWidget({
markdown: '# Requests',
height: 1,
width: 24,
}),
new cw.GraphWidget({
title: 'CloudFront Requests',
width: 6,
height: 6,
stacked: false,
left: [cfRequests],
}),
new cw.GraphWidget({
title: 'ALB Requests',
width: 6,
height: 6,
stacked: false,
left: [albRequests, albNewConnectionCount, albRejectedConnectionCount],
}),
new cw.GraphWidget({
title: 'Target Group Requests',
width: 6,
height: 6,
stacked: false,
left: [albTgRequests],
}),
new cw.GraphWidget({
title: 'Aurora Connections',
width: 6,
height: 6,
stacked: false,
left: [dbWriterDatabaseConnections, dbReaderDatabaseConnections],
}),
// Response Time
new cw.TextWidget({
markdown: '# Response Time',
height: 1,
width: 24,
}),
new cw.GraphWidget({
title: 'Target Group Response Time',
width: 8,
height: 6,
stacked: false,
left: [albTgResponseTime],
}),
new cw.GraphWidget({
title: 'Aurora Operation Lantency (Writer)',
width: 8,
height: 6,
stacked: false,
left: [
dbWriterInsertLatency,
dbWriterSelectLatency,
dbWriterUpdateLatency,
dbWriterCommitLatency,
dbWriterDDLLatency,
dbWriterDeleteLatency,
dbWriterDMLLatency,
],
right: [dbWriterReadLatency, dbWriterWriteLatency],
}),
new cw.GraphWidget({
title: 'Aurora Operation Lantency (Reader)',
width: 8,
height: 6,
stacked: false,
left: [dbReaderSelectLatency],
right: [dbReaderReadLatency, dbReaderWriteLatency],
}),
// Errors
new cw.TextWidget({
markdown: '# Errors',
height: 1,
width: 24,
}),
new cw.GraphWidget({
title: 'CloudFront Error Rates',
width: 6,
height: 6,
// stacked: false,
// left: [cf5xxErrorRate, cf4xxErrorRate, cfTotalErrorRate],
stacked: true,
left: [cf5xxErrorRate, cf4xxErrorRate],
}),
new cw.GraphWidget({
title: 'ALB Errors',
width: 6,
height: 6,
stacked: false,
left: [albTLSNegotiationErrors, alb5xxErrors, alb4xxErrors],
}),
new cw.AlarmWidget({
title: 'Alarm for UnHealthy Host in Target Group',
width: 6,
height: 6,
alarm: props.albTgUnHealthyHostCountAlarm, // This alarm is defined on ECSApp Stack
}),
new cw.GraphWidget({
title: 'Target Group Errors',
width: 6,
height: 6,
// stacked: false,
stacked: true,
left: [albTg5xxErrors, albTg4xxErrors, albTgConnectionErrors, albTgTLSNegotiationErrors],
}),
// Resources
new cw.TextWidget({
markdown: '# Resources',
height: 1,
width: 24,
}),
new cw.GraphWidget({
title: 'ECS CPU Utilization',
width: 6,
height: 6,
stacked: false,
left: [ecsCPUUtilization],
}),
new cw.GraphWidget({
title: 'ECS Memory Utilization',
width: 6,
height: 6,
stacked: false,
left: [ecsMemoryUtilization],
}),
new cw.GraphWidget({
title: 'ECS Desired Task Count',
width: 6,
height: 6,
stacked: false,
left: [ecsDesiredTaskCount],
}),
new cw.GraphWidget({
title: 'ECS Task Count',
width: 6,
height: 6,
stacked: true,
left: [ecsRunningTaskCount, ecsPendingTaskCount],
}),
new cw.GraphWidget({
title: 'ECS Auto Scaling with Requests per tasks',
width: 12,
height: 6,
stacked: false,
left: [albTgRequestCountPerTarget],
leftAnnotations: [
{
value: props.ecsScaleOnRequestCount, // Defined on ECSApp Stack
label: 'Threshold: Requests per tasks',
color: '#aec7e8',
fill: cw.Shading.BELOW,
},
],
right: [ecsRunningTaskCount, ecsPendingTaskCount],
}),
new cw.GraphWidget({
title: 'ECS Auto Scaling with CPU Utilization',
width: 12,
height: 6,
stacked: false,
left: [ecsCPUUtilization],
leftAnnotations: [
{
value: props.ecsTargetUtilizationPercent, // Defined on ECSApp Stack
label: 'Threshold: CPU Utilization',
color: '#aec7e8',
fill: cw.Shading.BELOW,
},
],
right: [ecsRunningTaskCount, ecsPendingTaskCount],
}),
new cw.GraphWidget({
title: 'Aurora CPU Utilization',
width: 6,
height: 6,
stacked: false,
left: [dbWriterCPUUtilization, dbReaderCPUUtilization],
}),
new cw.GraphWidget({
title: 'Aurora Free Memory',
width: 6,
height: 6,
stacked: false,
left: [dbWriterFreeableMemory, dbReaderFreeableMemory],
}),
new cw.GraphWidget({
title: 'Aurora Free Local Storage',
width: 6,
height: 6,
stacked: false,
left: [dbWriterFreeLocalStorage, dbReaderFreeLocalStorage],
}),
);
}