Skip to content

Commit 3c1f088

Browse files
authored
feat(rds): add support for Aurora Serverless Clusters (#395)
Added new AuroraCluster Monitoring with Aurora specific metrics/alarms. Fixes #217 --- _By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license_
1 parent 84609a4 commit 3c1f088

File tree

13 files changed

+2415
-10
lines changed

13 files changed

+2415
-10
lines changed

API.md

Lines changed: 1227 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ You can browse the documentation at https://constructs.dev/packages/cdk-monitori
6565
| AWS API Gateway (REST API) (`.monitorApiGateway()`) | TPS, latency, errors | Latency, error count/rate, low/high TPS | To see metrics, you have to enable Advanced Monitoring |
6666
| AWS API Gateway V2 (HTTP API) (`.monitorApiGatewayV2HttpApi()`) | TPS, latency, errors | Latency, error count/rate, low/high TPS | To see route level metrics, you have to enable Advanced Monitoring |
6767
| AWS AppSync (GraphQL API) (`.monitorAppSyncApi()`) | TPS, latency, errors | Latency, error count/rate, low/high TPS | |
68+
| Amazon Aurora (`.monitorAuroraCluster()`) | Query duration, connections, latency, CPU usage, Serverless Database Capacity | Connections, Serverless Database Capacity and CPU usage | |
6869
| AWS Billing (`.monitorBilling()`) | AWS account cost | Total cost (anomaly) | [Requires enabling](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/gs_monitor_estimated_charges_with_cloudwatch.html#gs_turning_on_billing_metrics) the **Receive Billing Alerts** option in AWS Console / Billing Preferences |
6970
| AWS Certificate Manager (`.monitorCertificate()`) | Certificate expiration | Days until expiration | |
7071
| AWS CloudFront (`.monitorCloudFrontDistribution()`) | TPS, traffic, latency, errors | Error rate, low/high TPS | |
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {
2+
ComparisonOperator,
3+
TreatMissingData,
4+
} from "aws-cdk-lib/aws-cloudwatch";
5+
6+
import { AlarmFactory, CustomAlarmThreshold } from "../../alarm";
7+
import { MetricWithAlarmSupport } from "../../metric";
8+
9+
export interface HighServerlessDatabaseCapacityThreshold
10+
extends CustomAlarmThreshold {
11+
readonly maxServerlessDatabaseCapacity: number;
12+
}
13+
14+
export class AuroraAlarmFactory {
15+
protected readonly alarmFactory: AlarmFactory;
16+
17+
constructor(alarmFactory: AlarmFactory) {
18+
this.alarmFactory = alarmFactory;
19+
}
20+
21+
addMaxServerlessDatabaseCapacity(
22+
metric: MetricWithAlarmSupport,
23+
props: HighServerlessDatabaseCapacityThreshold,
24+
disambiguator?: string
25+
) {
26+
return this.alarmFactory.addAlarm(metric, {
27+
treatMissingData:
28+
props.treatMissingDataOverride ?? TreatMissingData.MISSING,
29+
comparisonOperator:
30+
props.comparisonOperatorOverride ??
31+
ComparisonOperator.GREATER_THAN_THRESHOLD,
32+
...props,
33+
disambiguator,
34+
threshold: props.maxServerlessDatabaseCapacity,
35+
alarmNameSuffix: "Serverless-Database-Capacity-High",
36+
alarmDescription: "Serverless Database Capacity usage is too high.",
37+
});
38+
}
39+
}

lib/common/monitoring/alarms/UsageAlarmFactory.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,25 @@ export class UsageAlarmFactory {
3737
this.alarmFactory = alarmFactory;
3838
}
3939

40+
addMaxUsageCountAlarm(
41+
metric: MetricWithAlarmSupport,
42+
props: UsageCountThreshold,
43+
disambiguator?: string
44+
) {
45+
return this.alarmFactory.addAlarm(metric, {
46+
treatMissingData:
47+
props.treatMissingDataOverride ?? TreatMissingData.MISSING,
48+
comparisonOperator:
49+
props.comparisonOperatorOverride ??
50+
ComparisonOperator.GREATER_THAN_THRESHOLD,
51+
...props,
52+
disambiguator,
53+
threshold: props.maxUsageCount,
54+
alarmNameSuffix: "Usage-Count",
55+
alarmDescription: "The count is too high.",
56+
});
57+
}
58+
4059
addMinUsageCountAlarm(
4160
percentMetric: MetricWithAlarmSupport,
4261
props: MinUsageCountThreshold,

lib/common/monitoring/alarms/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from "./AgeAlarmFactory";
22
export * from "./AnomalyDetectingAlarmFactory";
3+
export * from "./AuroraAlarmFactory";
34
export * from "./CustomAlarmFactory";
45
export * from "./ConnectionAlarmFactory";
56
export * from "./DynamoAlarmFactory";

lib/facade/IMonitoringAspect.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
ApiGatewayMonitoringOptions,
33
ApiGatewayV2MonitoringOptions,
44
AppSyncMonitoringOptions,
5+
AuroraClusterMonitoringOptions,
56
AutoScalingGroupMonitoringOptions,
67
BillingMonitoringOptions,
78
CertificateManagerMonitoringOptions,
@@ -47,6 +48,7 @@ export interface MonitoringAspectProps {
4748
readonly apiGateway?: MonitoringAspectType<ApiGatewayMonitoringOptions>;
4849
readonly apiGatewayV2?: MonitoringAspectType<ApiGatewayV2MonitoringOptions>;
4950
readonly appSync?: MonitoringAspectType<AppSyncMonitoringOptions>;
51+
readonly auroraCluster?: MonitoringAspectType<AuroraClusterMonitoringOptions>;
5052
readonly autoScalingGroup?: MonitoringAspectType<AutoScalingGroupMonitoringOptions>;
5153
readonly billing?: MonitoringAspectType<BillingMonitoringOptions>;
5254
readonly cloudFront?: MonitoringAspectType<CloudFrontDistributionMonitoringOptions>;

lib/facade/MonitoringAspect.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export class MonitoringAspect implements IAspect {
5252
this.monitorApiGateway(node);
5353
this.monitorApiGatewayV2(node);
5454
this.monitorAppSync(node);
55+
this.monitorAuroraCluster(node);
5556
this.monitorAutoScalingGroup(node);
5657
this.monitorCloudFront(node);
5758
this.monitorCodeBuild(node);
@@ -135,6 +136,19 @@ export class MonitoringAspect implements IAspect {
135136
}
136137
}
137138

139+
private monitorAuroraCluster(node: IConstruct) {
140+
const [isEnabled, props] = this.getMonitoringDetails(
141+
this.props.auroraCluster
142+
);
143+
if (isEnabled && node instanceof rds.ServerlessCluster) {
144+
this.monitoringFacade.monitorAuroraCluster({
145+
cluster: node,
146+
alarmFriendlyName: node.node.path,
147+
...props,
148+
});
149+
}
150+
}
151+
138152
private monitorAutoScalingGroup(node: IConstruct) {
139153
const [isEnabled, props] = this.getMonitoringDetails(
140154
this.props.autoScalingGroup

lib/facade/MonitoringFacade.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ import {
3838
ApiGatewayV2HttpApiMonitoringProps,
3939
AppSyncMonitoring,
4040
AppSyncMonitoringProps,
41+
AuroraClusterMonitoring,
42+
AuroraClusterMonitoringProps,
4143
AutoScalingGroupMonitoring,
4244
AutoScalingGroupMonitoringProps,
4345
BillingMonitoring,
@@ -415,6 +417,12 @@ export class MonitoringFacade extends MonitoringScope {
415417
return this;
416418
}
417419

420+
monitorAuroraCluster(props: AuroraClusterMonitoringProps) {
421+
const segment = new AuroraClusterMonitoring(this, props);
422+
this.addSegment(segment, props);
423+
return this;
424+
}
425+
418426
monitorCertificate(props: CertificateManagerMonitoringProps) {
419427
const segment = new CertificateManagerMonitoring(this, props);
420428
this.addSegment(segment, props);

0 commit comments

Comments
 (0)