Skip to content

Commit b07f361

Browse files
authored
fix: make anomaly detection alarm work on math expression (#426)
Fixes #425 Fixes #340 ### Changes Changes to the implementation of `AnomalyDetectionMathExpression`: * Fixed an issue where `thresholdMetricId` was assigned the incorrect expression id when multiple math expressions were present in the generated CFN template. * Modified `returnData` to be true only for the `ANOMALY_DETECTION_BAND` function and its direct dependency, rather than for all of the metrics in `Metrics`. I haven't come across any internal or external documentation indicating that two `returnData: true` are necessary for anomaly detection. However, after doing some experiments on CFN, this appears to be true. ### Testing I copied the fix into my own CDK package, with the fix, I was able to deploy my stacks. --- _By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license_
1 parent 465e388 commit b07f361

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

lib/common/metric/AnomalyDetectionMathExpression.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,29 @@ export class AnomalyDetectionMathExpression extends MathExpression {
3131
createAlarm(scope: Construct, id: string, props: CreateAlarmOptions): Alarm {
3232
const alarm = super.createAlarm(scope, id, props);
3333

34+
// `usingMetrics` of an anomaly detection alarm can only ever have one entry.
35+
// Should the entry be a math expression, the math expression can have its own `usingMetrics`.
36+
const finalExpressionId = Object.keys(this.usingMetrics)[0];
37+
3438
// https://github.com/aws/aws-cdk/issues/10540#issuecomment-725222564
3539
const cfnAlarm = alarm.node.defaultChild as CfnAlarm;
3640
cfnAlarm.addPropertyDeletionOverride("Threshold");
3741
(cfnAlarm.metrics as CfnAlarm.MetricDataQueryProperty[]).forEach(
3842
(metric, index) => {
39-
if (metric.expression) {
43+
// To create an anomaly detection alarm, returned data should be set to true on two MetricDataQueryProperty(s):
44+
// 1. The metric or math expression that is being evaluated for anomaly detection (eg. expr_1)
45+
// 2. The actual expression of anomaly detection (eg. ANOMALY_DETECTION_BAND(expr_1, 1))
46+
let returnData = false;
47+
48+
if (metric.expression?.includes("ANOMALY_DETECTION_BAND")) {
49+
// thresholdMetricId is the ID of the ANOMALY_DETECTION_BAND function used as the threshold for the alarm.
4050
cfnAlarm.thresholdMetricId = metric.id;
51+
returnData = true;
52+
} else if (metric.id === finalExpressionId) {
53+
returnData = true;
4154
}
42-
cfnAlarm.addPropertyOverride(`Metrics.${index}.ReturnData`, true);
55+
56+
cfnAlarm.addPropertyOverride(`Metrics.${index}.ReturnData`, returnData);
4357
}
4458
);
4559

test/monitoring/custom/__snapshots__/CustomMonitoring.test.ts.snap

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

0 commit comments

Comments
 (0)