-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(docdb): add monitoring for Document DB (#174)
Fixes #167 --- _By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license_
- Loading branch information
Showing
17 changed files
with
3,512 additions
and
267 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { DimensionsMap } from "aws-cdk-lib/aws-cloudwatch"; | ||
import { IDatabaseCluster } from "aws-cdk-lib/aws-docdb"; | ||
|
||
import { | ||
getLatencyTypeLabel, | ||
getLatencyTypeStatistic, | ||
LatencyType, | ||
MetricFactory, | ||
MetricStatistic, | ||
} from "../../common"; | ||
|
||
const DocumentDbNamespace = "AWS/DocDB"; | ||
|
||
export interface DocumentDbMetricFactoryProps { | ||
/** | ||
* database cluster | ||
*/ | ||
readonly cluster: IDatabaseCluster; | ||
} | ||
|
||
export class DocumentDbMetricFactory { | ||
readonly clusterIdentifier: string; | ||
protected readonly metricFactory: MetricFactory; | ||
protected readonly dimensionsMap: DimensionsMap; | ||
|
||
constructor( | ||
metricFactory: MetricFactory, | ||
props: DocumentDbMetricFactoryProps | ||
) { | ||
this.metricFactory = metricFactory; | ||
this.clusterIdentifier = props.cluster.clusterIdentifier; | ||
this.dimensionsMap = { DBClusterIdentifier: this.clusterIdentifier }; | ||
} | ||
|
||
metricAverageCpuUsageInPercent() { | ||
return this.metric("CPUUtilization", MetricStatistic.AVERAGE, "CPU Usage"); | ||
} | ||
|
||
metricMaxConnectionCount() { | ||
return this.metric( | ||
"DatabaseConnectionsMax", | ||
MetricStatistic.MAX, | ||
"Connections" | ||
); | ||
} | ||
|
||
metricMaxCursorCount() { | ||
return this.metric("DatabaseCursorsMax", MetricStatistic.MAX, "Cursors"); | ||
} | ||
|
||
metricMaxTransactionOpenCount() { | ||
return this.metric( | ||
"TransactionsOpenMax", | ||
MetricStatistic.MAX, | ||
"Transactions" | ||
); | ||
} | ||
|
||
metricOperationsThrottledDueLowMemoryCount() { | ||
return this.metric( | ||
"LowMemNumOperationsThrottled", | ||
MetricStatistic.SUM, | ||
"Operations throttled (low mem)" | ||
); | ||
} | ||
|
||
metricReadLatencyInMillis(latencyType: LatencyType) { | ||
const label = "Read " + getLatencyTypeLabel(latencyType); | ||
return this.metric( | ||
"ReadLatency", | ||
getLatencyTypeStatistic(latencyType), | ||
label | ||
); | ||
} | ||
|
||
metricWriteLatencyInMillis(latencyType: LatencyType) { | ||
const label = "Write " + getLatencyTypeLabel(latencyType); | ||
return this.metric( | ||
"WriteLatency", | ||
getLatencyTypeStatistic(latencyType), | ||
label | ||
); | ||
} | ||
|
||
private metric( | ||
metricName: string, | ||
statistic: MetricStatistic, | ||
label: string | ||
) { | ||
return this.metricFactory.createMetric( | ||
metricName, | ||
statistic, | ||
label, | ||
this.dimensionsMap, | ||
undefined, | ||
DocumentDbNamespace | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
import { | ||
GraphWidget, | ||
HorizontalAnnotation, | ||
IWidget, | ||
} from "aws-cdk-lib/aws-cloudwatch"; | ||
import { | ||
BaseMonitoringProps, | ||
CountAxisFromZero, | ||
DefaultGraphWidgetHeight, | ||
DefaultSummaryWidgetHeight, | ||
LatencyType, | ||
MetricWithAlarmSupport, | ||
Monitoring, | ||
MonitoringScope, | ||
PercentageAxisFromZeroToHundred, | ||
QuarterWidth, | ||
ThirdWidth, | ||
TimeAxisMillisFromZero, | ||
UsageAlarmFactory, | ||
UsageThreshold, | ||
} from "../../common"; | ||
import { | ||
MonitoringHeaderWidget, | ||
MonitoringNamingStrategy, | ||
} from "../../dashboard"; | ||
import { | ||
DocumentDbMetricFactory, | ||
DocumentDbMetricFactoryProps, | ||
} from "./DocumentDbMetricFactory"; | ||
|
||
export interface DocumentDbMonitoringOptions extends BaseMonitoringProps { | ||
readonly addCpuUsageAlarm?: Record<string, UsageThreshold>; | ||
} | ||
|
||
export interface DocumentDbMonitoringProps | ||
extends DocumentDbMetricFactoryProps, | ||
DocumentDbMonitoringOptions {} | ||
|
||
export class DocumentDbMonitoring extends Monitoring { | ||
protected readonly title: string; | ||
protected readonly url?: string; | ||
|
||
protected readonly usageAlarmFactory: UsageAlarmFactory; | ||
protected readonly usageAnnotations: HorizontalAnnotation[]; | ||
|
||
protected readonly cpuUsageMetric: MetricWithAlarmSupport; | ||
protected readonly readLatencyMetric: MetricWithAlarmSupport; | ||
protected readonly writeLatencyMetric: MetricWithAlarmSupport; | ||
protected readonly connectionsMetric: MetricWithAlarmSupport; | ||
protected readonly cursorsMetric: MetricWithAlarmSupport; | ||
protected readonly transactionsMetric: MetricWithAlarmSupport; | ||
protected readonly throttledMetric: MetricWithAlarmSupport; | ||
|
||
constructor(scope: MonitoringScope, props: DocumentDbMonitoringProps) { | ||
super(scope, props); | ||
|
||
const metricFactory = new DocumentDbMetricFactory( | ||
scope.createMetricFactory(), | ||
props | ||
); | ||
this.cpuUsageMetric = metricFactory.metricAverageCpuUsageInPercent(); | ||
this.readLatencyMetric = metricFactory.metricReadLatencyInMillis( | ||
LatencyType.P90 | ||
); | ||
this.writeLatencyMetric = metricFactory.metricWriteLatencyInMillis( | ||
LatencyType.P90 | ||
); | ||
this.connectionsMetric = metricFactory.metricMaxConnectionCount(); | ||
this.cursorsMetric = metricFactory.metricMaxCursorCount(); | ||
this.transactionsMetric = metricFactory.metricMaxTransactionOpenCount(); | ||
this.throttledMetric = | ||
metricFactory.metricOperationsThrottledDueLowMemoryCount(); | ||
|
||
const namingStrategy = new MonitoringNamingStrategy({ | ||
...props, | ||
fallbackConstructName: metricFactory.clusterIdentifier, | ||
namedConstruct: props.cluster, | ||
}); | ||
this.title = namingStrategy.resolveHumanReadableName(); | ||
this.url = scope | ||
.createAwsConsoleUrlFactory() | ||
.getDocumentDbClusterUrl(metricFactory.clusterIdentifier); | ||
const alarmFactory = this.createAlarmFactory( | ||
namingStrategy.resolveAlarmFriendlyName() | ||
); | ||
|
||
this.usageAlarmFactory = new UsageAlarmFactory(alarmFactory); | ||
this.usageAnnotations = []; | ||
|
||
for (const disambiguator in props.addCpuUsageAlarm) { | ||
const alarmProps = props.addCpuUsageAlarm[disambiguator]; | ||
const createdAlarm = this.usageAlarmFactory.addMaxCpuUsagePercentAlarm( | ||
this.cpuUsageMetric, | ||
alarmProps, | ||
disambiguator | ||
); | ||
this.usageAnnotations.push(createdAlarm.annotation); | ||
this.addAlarm(createdAlarm); | ||
} | ||
|
||
props.useCreatedAlarms?.consume(this.createdAlarms()); | ||
} | ||
|
||
summaryWidgets(): IWidget[] { | ||
return [ | ||
this.createTitleWidget(), | ||
this.createResourceUsageWidget(ThirdWidth, DefaultSummaryWidgetHeight), | ||
this.createConnectionsWidget(ThirdWidth, DefaultSummaryWidgetHeight), | ||
this.createLatencyWidget(ThirdWidth, DefaultSummaryWidgetHeight), | ||
]; | ||
} | ||
|
||
widgets(): IWidget[] { | ||
return [ | ||
this.createTitleWidget(), | ||
this.createResourceUsageWidget(QuarterWidth, DefaultGraphWidgetHeight), | ||
this.createConnectionsWidget(QuarterWidth, DefaultGraphWidgetHeight), | ||
this.createTransactionsWidget(QuarterWidth, DefaultGraphWidgetHeight), | ||
this.createLatencyWidget(QuarterWidth, DefaultGraphWidgetHeight), | ||
]; | ||
} | ||
|
||
protected createTitleWidget() { | ||
return new MonitoringHeaderWidget({ | ||
family: "DocumentDB", | ||
title: this.title, | ||
goToLinkUrl: this.url, | ||
}); | ||
} | ||
|
||
protected createResourceUsageWidget(width: number, height: number) { | ||
return new GraphWidget({ | ||
width, | ||
height, | ||
title: "CPU Usage", | ||
left: [this.cpuUsageMetric], | ||
leftYAxis: PercentageAxisFromZeroToHundred, | ||
leftAnnotations: this.usageAnnotations, | ||
}); | ||
} | ||
|
||
protected createConnectionsWidget(width: number, height: number) { | ||
return new GraphWidget({ | ||
width, | ||
height, | ||
title: "Connections", | ||
left: [this.connectionsMetric], | ||
leftYAxis: CountAxisFromZero, | ||
}); | ||
} | ||
|
||
protected createTransactionsWidget(width: number, height: number) { | ||
return new GraphWidget({ | ||
width, | ||
height, | ||
title: "Transactions", | ||
left: [this.transactionsMetric, this.cursorsMetric], | ||
leftYAxis: CountAxisFromZero, | ||
}); | ||
} | ||
|
||
protected createLatencyWidget(width: number, height: number) { | ||
return new GraphWidget({ | ||
width, | ||
height, | ||
title: "Latency", | ||
left: [this.readLatencyMetric, this.writeLatencyMetric], | ||
leftYAxis: TimeAxisMillisFromZero, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./DocumentDbMetricFactory"; | ||
export * from "./DocumentDbMonitoring"; |
Oops, something went wrong.