From 828ac20063b6ab7ebedfe67e8c57bdb511599962 Mon Sep 17 00:00:00 2001 From: Romain Marcadier-Muller Date: Wed, 30 Jan 2019 10:08:13 +0100 Subject: [PATCH] feat(cloudwatch): Support 'datapointsToAlarm' on Alarms (#1631) Adds support for settingt the `dataPointsToAlarm` property of the CloudWatch `Alarm`s (also via the `Metric`s). Fixes #1626 --- packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts | 58 +------------------ .../@aws-cdk/aws-cloudwatch/lib/metric.ts | 18 +++++- .../integ.alarm-and-dashboard.expected.json | 7 ++- .../test/integ.alarm-and-dashboard.ts | 3 +- .../aws-cloudwatch/test/test.alarm.ts | 31 +++++++++- 5 files changed, 53 insertions(+), 64 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts b/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts index 078671e301b4e..6791c825f9854 100644 --- a/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts +++ b/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts @@ -1,13 +1,13 @@ import { Construct, Token } from '@aws-cdk/cdk'; import { CfnAlarm } from './cloudwatch.generated'; import { HorizontalAnnotation } from './graph'; -import { Dimension, Metric, Statistic, Unit } from './metric'; +import { Dimension, Metric, MetricAarmProps, Statistic, Unit } from './metric'; import { parseStatistic } from './util.statistic'; /** * Properties for Alarms */ -export interface AlarmProps { +export interface AlarmProps extends MetricAarmProps { /** * The metric to add the alarm on * @@ -15,59 +15,6 @@ export interface AlarmProps { * custom Metric objects by instantiating one. */ metric: Metric; - - /** - * Name of the alarm - * - * @default Automatically generated name - */ - alarmName?: string; - - /** - * Description for the alarm - * - * @default No description - */ - alarmDescription?: string; - - /** - * Comparison to use to check if metric is breaching - * - * @default GreaterThanOrEqualToThreshold - */ - comparisonOperator?: ComparisonOperator; - - /** - * The value against which the specified statistic is compared. - */ - threshold: number; - - /** - * The number of periods over which data is compared to the specified threshold. - */ - evaluationPeriods: number; - - /** - * Specifies whether to evaluate the data and potentially change the alarm - * state if there are too few data points to be statistically significant. - * - * Used only for alarms that are based on percentiles. - */ - evaluateLowSampleCountPercentile?: string; - - /** - * Sets how this alarm is to handle missing data points. - * - * @default TreatMissingData.Missing - */ - treatMissingData?: TreatMissingData; - - /** - * Whether the actions for this alarm are enabled - * - * @default true - */ - actionsEnabled?: boolean; } /** @@ -153,6 +100,7 @@ export class Alarm extends Construct { // Evaluation comparisonOperator, threshold: props.threshold, + datapointsToAlarm: props.datapointsToAlarm, evaluateLowSampleCountPercentile: props.evaluateLowSampleCountPercentile, evaluationPeriods: props.evaluationPeriods, treatMissingData: props.treatMissingData, diff --git a/packages/@aws-cdk/aws-cloudwatch/lib/metric.ts b/packages/@aws-cdk/aws-cloudwatch/lib/metric.ts index d3a5bc9b5d4e7..69511ec5e7008 100644 --- a/packages/@aws-cdk/aws-cloudwatch/lib/metric.ts +++ b/packages/@aws-cdk/aws-cloudwatch/lib/metric.ts @@ -148,7 +148,7 @@ export class Metric { * Combines both properties that may adjust the metric (aggregation) as well * as alarm properties. */ - public newAlarm(scope: cdk.Construct, id: string, props: NewAlarmProps): Alarm { + public newAlarm(scope: cdk.Construct, id: string, props: MetricAarmProps): Alarm { return new Alarm(scope, id, { metric: this.with({ statistic: props.statistic, @@ -157,6 +157,7 @@ export class Metric { alarmName: props.alarmName, alarmDescription: props.alarmDescription, comparisonOperator: props.comparisonOperator, + datapointsToAlarm: props.datapointsToAlarm, threshold: props.threshold, evaluationPeriods: props.evaluationPeriods, evaluateLowSampleCountPercentile: props.evaluateLowSampleCountPercentile, @@ -293,9 +294,9 @@ export interface MetricCustomization { } /** - * Properties to make an alarm from a metric + * Properties needed to make an alarm from a metric */ -export interface NewAlarmProps { +export interface MetricAarmProps { /** * The period over which the specified statistic is applied. * @@ -372,6 +373,17 @@ export interface NewAlarmProps { * @default true */ actionsEnabled?: boolean; + + /** + * The number of datapoints that must be breaching to trigger the alarm. This is used only if you are setting an "M + * out of N" alarm. In that case, this value is the M. For more information, see Evaluating an Alarm in the Amazon + * CloudWatch User Guide. + * + * @default ``evaluationPeriods`` + * + * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarm-evaluation + */ + datapointsToAlarm?: number; } function ifUndefined(x: T | undefined, def: T | undefined): T | undefined { diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.expected.json b/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.expected.json index bc6a19679b430..2a0b5888788c6 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.expected.json +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.expected.json @@ -8,10 +8,8 @@ "Properties": { "ComparisonOperator": "GreaterThanOrEqualToThreshold", "EvaluationPeriods": 3, - "MetricName": "ApproximateNumberOfMessagesVisible", - "Namespace": "AWS/SQS", - "Period": 300, "Threshold": 100, + "DatapointsToAlarm": 2, "Dimensions": [ { "Name": "QueueName", @@ -23,6 +21,9 @@ } } ], + "MetricName": "ApproximateNumberOfMessagesVisible", + "Namespace": "AWS/SQS", + "Period": 300, "Statistic": "Average" } }, diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts b/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts index 33e45b97c1b19..ac6944251406b 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts @@ -21,7 +21,8 @@ const metric = new cloudwatch.Metric({ const alarm = metric.newAlarm(stack, 'Alarm', { threshold: 100, - evaluationPeriods: 3 + evaluationPeriods: 3, + datapointsToAlarm: 2, }); const dashboard = new cloudwatch.Dashboard(stack, 'Dash'); diff --git a/packages/@aws-cdk/aws-cloudwatch/test/test.alarm.ts b/packages/@aws-cdk/aws-cloudwatch/test/test.alarm.ts index b2dac59fbe3c5..5ef3dfe2a4307 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/test.alarm.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/test.alarm.ts @@ -17,13 +17,40 @@ export = { new Alarm(stack, 'Alarm', { metric: testMetric, threshold: 1000, - evaluationPeriods: 2 + evaluationPeriods: 3, }); // THEN expect(stack).to(haveResource('AWS::CloudWatch::Alarm', { ComparisonOperator: "GreaterThanOrEqualToThreshold", - EvaluationPeriods: 2, + EvaluationPeriods: 3, + MetricName: "Metric", + Namespace: "CDK/Test", + Period: 300, + Statistic: 'Average', + Threshold: 1000, + })); + + test.done(); + }, + + 'can set DatapointsToAlarm'(test: Test) { + // GIVEN + const stack = new Stack(); + + // WHEN + new Alarm(stack, 'Alarm', { + metric: testMetric, + threshold: 1000, + evaluationPeriods: 3, + datapointsToAlarm: 2, + }); + + // THEN + expect(stack).to(haveResource('AWS::CloudWatch::Alarm', { + ComparisonOperator: "GreaterThanOrEqualToThreshold", + EvaluationPeriods: 3, + DatapointsToAlarm: 2, MetricName: "Metric", Namespace: "CDK/Test", Period: 300,