diff --git a/src/experimental/constructs/__snapshots__/error-budget-alarm.test.ts.snap b/src/experimental/constructs/__snapshots__/error-budget-alarm.test.ts.snap index 2d9858bf19..179eb44af3 100644 --- a/src/experimental/constructs/__snapshots__/error-budget-alarm.test.ts.snap +++ b/src/experimental/constructs/__snapshots__/error-budget-alarm.test.ts.snap @@ -10,9 +10,9 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "gu:cdk:version": "TEST", }, "Resources": { - "ChildAlarmForFastBurnOver1hour45C7AB22": { + "ChildAlarmLongPeriodMapiFrontsAvailabilityFastBurnCompositeAlarmF1A44641": { "Properties": { - "AlarmName": "ChildAlarmForFastBurnOver1 hour", + "AlarmName": "ChildAlarmLongPeriodMapiFrontsAvailabilityFastBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -85,9 +85,9 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio }, "Type": "AWS::CloudWatch::Alarm", }, - "ChildAlarmForFastBurnOver5minutes67EDAF36": { + "ChildAlarmLongPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarmB28EFC34": { "Properties": { - "AlarmName": "ChildAlarmForFastBurnOver5 minutes", + "AlarmName": "ChildAlarmLongPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -108,7 +108,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "LbHttpErrors", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 300, + "Period": 21600, "Stat": "Average", }, "ReturnData": false, @@ -120,7 +120,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "TargetHttpErrors", "Namespace": "TestTargetMetrics", }, - "Period": 300, + "Period": 21600, "Stat": "Average", }, "ReturnData": false, @@ -137,7 +137,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "HttpRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 300, + "Period": 21600, "Stat": "Average", }, "ReturnData": false, @@ -149,20 +149,20 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "BadRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 300, + "Period": 21600, "Stat": "Average", }, "ReturnData": false, }, ], - "Threshold": 0.014400000000000013, + "Threshold": 0.006000000000000005, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ChildAlarmForMediumBurnOver30minutesF70BC2E5": { + "ChildAlarmLongPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarm31625779": { "Properties": { - "AlarmName": "ChildAlarmForMediumBurnOver30 minutes", + "AlarmName": "ChildAlarmLongPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -183,7 +183,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "LbHttpErrors", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 1800, + "Period": 86400, "Stat": "Average", }, "ReturnData": false, @@ -195,7 +195,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "TargetHttpErrors", "Namespace": "TestTargetMetrics", }, - "Period": 1800, + "Period": 86400, "Stat": "Average", }, "ReturnData": false, @@ -212,7 +212,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "HttpRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 1800, + "Period": 86400, "Stat": "Average", }, "ReturnData": false, @@ -224,20 +224,20 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "BadRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 1800, + "Period": 86400, "Stat": "Average", }, "ReturnData": false, }, ], - "Threshold": 0.006000000000000005, + "Threshold": 0.0030000000000000027, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ChildAlarmForMediumBurnOver6hoursC8B7C019": { + "ChildAlarmShortPeriodMapiFrontsAvailabilityFastBurnCompositeAlarmCF3AFF0A": { "Properties": { - "AlarmName": "ChildAlarmForMediumBurnOver6 hours", + "AlarmName": "ChildAlarmShortPeriodMapiFrontsAvailabilityFastBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -258,7 +258,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "LbHttpErrors", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 21600, + "Period": 300, "Stat": "Average", }, "ReturnData": false, @@ -270,7 +270,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "TargetHttpErrors", "Namespace": "TestTargetMetrics", }, - "Period": 21600, + "Period": 300, "Stat": "Average", }, "ReturnData": false, @@ -287,7 +287,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "HttpRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 21600, + "Period": 300, "Stat": "Average", }, "ReturnData": false, @@ -299,20 +299,20 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "BadRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 21600, + "Period": 300, "Stat": "Average", }, "ReturnData": false, }, ], - "Threshold": 0.006000000000000005, + "Threshold": 0.014400000000000013, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ChildAlarmForSlowBurnOver1day9466C64F": { + "ChildAlarmShortPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarmDBEC21EA": { "Properties": { - "AlarmName": "ChildAlarmForSlowBurnOver1 day", + "AlarmName": "ChildAlarmShortPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -333,7 +333,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "LbHttpErrors", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 86400, + "Period": 1800, "Stat": "Average", }, "ReturnData": false, @@ -345,7 +345,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "TargetHttpErrors", "Namespace": "TestTargetMetrics", }, - "Period": 86400, + "Period": 1800, "Stat": "Average", }, "ReturnData": false, @@ -362,7 +362,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "HttpRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 86400, + "Period": 1800, "Stat": "Average", }, "ReturnData": false, @@ -374,20 +374,20 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "MetricName": "BadRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 86400, + "Period": 1800, "Stat": "Average", }, "ReturnData": false, }, ], - "Threshold": 0.0030000000000000027, + "Threshold": 0.006000000000000005, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ChildAlarmForSlowBurnOver2hoursC240626B": { + "ChildAlarmShortPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarmCA6C81C2": { "Properties": { - "AlarmName": "ChildAlarmForSlowBurnOver2 hours", + "AlarmName": "ChildAlarmShortPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -488,14 +488,14 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "(ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForFastBurnOver1hour45C7AB22", + "ChildAlarmLongPeriodMapiFrontsAvailabilityFastBurnCompositeAlarmF1A44641", "Arn", ], }, "") AND ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForFastBurnOver5minutes67EDAF36", + "ChildAlarmShortPeriodMapiFrontsAvailabilityFastBurnCompositeAlarmCF3AFF0A", "Arn", ], }, @@ -542,14 +542,14 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "(ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForMediumBurnOver6hoursC8B7C019", + "ChildAlarmLongPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarmB28EFC34", "Arn", ], }, "") AND ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForMediumBurnOver30minutesF70BC2E5", + "ChildAlarmShortPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarmDBEC21EA", "Arn", ], }, @@ -596,14 +596,14 @@ exports[`The ErrorBudgetAlarmExperimental construct should accept math expressio "(ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForSlowBurnOver1day9466C64F", + "ChildAlarmLongPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarm31625779", "Arn", ], }, "") AND ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForSlowBurnOver2hoursC240626B", + "ChildAlarmShortPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarmCA6C81C2", "Arn", ], }, @@ -628,9 +628,9 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "gu:cdk:version": "TEST", }, "Resources": { - "ChildAlarmForFastBurnOver1hour45C7AB22": { + "ChildAlarmLongPeriodMapiFrontsAvailabilityFastBurnCompositeAlarmF1A44641": { "Properties": { - "AlarmName": "ChildAlarmForFastBurnOver1 hour", + "AlarmName": "ChildAlarmLongPeriodMapiFrontsAvailabilityFastBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -669,9 +669,9 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re }, "Type": "AWS::CloudWatch::Alarm", }, - "ChildAlarmForFastBurnOver5minutes67EDAF36": { + "ChildAlarmLongPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarmB28EFC34": { "Properties": { - "AlarmName": "ChildAlarmForFastBurnOver5 minutes", + "AlarmName": "ChildAlarmLongPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -687,7 +687,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "MetricName": "HttpErrors", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 300, + "Period": 21600, "Stat": "Average", }, "ReturnData": false, @@ -699,20 +699,20 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "MetricName": "HttpRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 300, + "Period": 21600, "Stat": "Average", }, "ReturnData": false, }, ], - "Threshold": 0.014400000000000013, + "Threshold": 0.006000000000000005, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ChildAlarmForMediumBurnOver30minutesF70BC2E5": { + "ChildAlarmLongPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarm31625779": { "Properties": { - "AlarmName": "ChildAlarmForMediumBurnOver30 minutes", + "AlarmName": "ChildAlarmLongPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -728,7 +728,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "MetricName": "HttpErrors", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 1800, + "Period": 86400, "Stat": "Average", }, "ReturnData": false, @@ -740,20 +740,20 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "MetricName": "HttpRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 1800, + "Period": 86400, "Stat": "Average", }, "ReturnData": false, }, ], - "Threshold": 0.006000000000000005, + "Threshold": 0.0030000000000000027, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ChildAlarmForMediumBurnOver6hoursC8B7C019": { + "ChildAlarmShortPeriodMapiFrontsAvailabilityFastBurnCompositeAlarmCF3AFF0A": { "Properties": { - "AlarmName": "ChildAlarmForMediumBurnOver6 hours", + "AlarmName": "ChildAlarmShortPeriodMapiFrontsAvailabilityFastBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -769,7 +769,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "MetricName": "HttpErrors", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 21600, + "Period": 300, "Stat": "Average", }, "ReturnData": false, @@ -781,20 +781,20 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "MetricName": "HttpRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 21600, + "Period": 300, "Stat": "Average", }, "ReturnData": false, }, ], - "Threshold": 0.006000000000000005, + "Threshold": 0.014400000000000013, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ChildAlarmForSlowBurnOver1day9466C64F": { + "ChildAlarmShortPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarmDBEC21EA": { "Properties": { - "AlarmName": "ChildAlarmForSlowBurnOver1 day", + "AlarmName": "ChildAlarmShortPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -810,7 +810,7 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "MetricName": "HttpErrors", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 86400, + "Period": 1800, "Stat": "Average", }, "ReturnData": false, @@ -822,20 +822,20 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "MetricName": "HttpRequests", "Namespace": "TestLoadBalancerMetrics", }, - "Period": 86400, + "Period": 1800, "Stat": "Average", }, "ReturnData": false, }, ], - "Threshold": 0.0030000000000000027, + "Threshold": 0.006000000000000005, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ChildAlarmForSlowBurnOver2hoursC240626B": { + "ChildAlarmShortPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarmCA6C81C2": { "Properties": { - "AlarmName": "ChildAlarmForSlowBurnOver2 hours", + "AlarmName": "ChildAlarmShortPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ @@ -902,14 +902,14 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "(ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForFastBurnOver1hour45C7AB22", + "ChildAlarmLongPeriodMapiFrontsAvailabilityFastBurnCompositeAlarmF1A44641", "Arn", ], }, "") AND ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForFastBurnOver5minutes67EDAF36", + "ChildAlarmShortPeriodMapiFrontsAvailabilityFastBurnCompositeAlarmCF3AFF0A", "Arn", ], }, @@ -956,14 +956,14 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "(ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForMediumBurnOver6hoursC8B7C019", + "ChildAlarmLongPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarmB28EFC34", "Arn", ], }, "") AND ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForMediumBurnOver30minutesF70BC2E5", + "ChildAlarmShortPeriodMapiFrontsAvailabilityMediumBurnCompositeAlarmDBEC21EA", "Arn", ], }, @@ -1010,14 +1010,14 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "(ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForSlowBurnOver1day9466C64F", + "ChildAlarmLongPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarm31625779", "Arn", ], }, "") AND ALARM("", { "Fn::GetAtt": [ - "ChildAlarmForSlowBurnOver2hoursC240626B", + "ChildAlarmShortPeriodMapiFrontsAvailabilitySlowBurnCompositeAlarmCA6C81C2", "Arn", ], }, diff --git a/src/experimental/constructs/error-budget-alarm.test.ts b/src/experimental/constructs/error-budget-alarm.test.ts index 8c5ee16991..6af06bd88c 100644 --- a/src/experimental/constructs/error-budget-alarm.test.ts +++ b/src/experimental/constructs/error-budget-alarm.test.ts @@ -39,4 +39,24 @@ describe("The ErrorBudgetAlarmExperimental construct", () => { }); expect(Template.fromStack(stack).toJSON()).toMatchSnapshot(); }); + + it("should support multiple GuErrorBudgetAlarmExperimentals in a single stack", () => { + const stack = simpleGuStackForTesting(); + new GuErrorBudgetAlarmExperimental(stack, { + sloName: "MapiFrontsAvailability", + sloTarget: 0.999, + badEvents: new Metric({ metricName: "HttpErrors", namespace: "TestLoadBalancerMetrics" }), + validEvents: new Metric({ metricName: "HttpRequests", namespace: "TestLoadBalancerMetrics" }), + snsTopicNameForAlerts: "test-sns-topic", + }); + new GuErrorBudgetAlarmExperimental(stack, { + sloName: "MapiFrontsLatency", + sloTarget: 0.999, + badEvents: new Metric({ metricName: "SlowResponses", namespace: "TestLoadBalancerMetrics" }), + validEvents: new Metric({ metricName: "HttpRequests", namespace: "TestLoadBalancerMetrics" }), + snsTopicNameForAlerts: "test-sns-topic", + }); + // Each GuErrorBudgetAlarmExperimental creates 3 composite alarms (fast, medium, slow) so we expect 6 in total here + Template.fromStack(stack).resourceCountIs("AWS::CloudWatch::CompositeAlarm", 6); + }); }); diff --git a/src/experimental/constructs/error-budget-alarm.ts b/src/experimental/constructs/error-budget-alarm.ts index 7500cdfa45..484e3d4d9b 100644 --- a/src/experimental/constructs/error-budget-alarm.ts +++ b/src/experimental/constructs/error-budget-alarm.ts @@ -145,9 +145,8 @@ export class GuErrorBudgetAlarmExperimental extends Construct { class MonitorBurnRateForPeriod extends Alarm { constructor(scope: GuStack, props: MonitorBurnRateForPeriodProps) { const undesirableErrorBudgetConsumption = props.errorBudget * props.burnRateSpeed.burnRate; - const alarmName = `ChildAlarmFor${props.burnRateSpeed.speed}BurnOver${props.period.toHumanString()}`; - super(scope, alarmName, { - alarmName: alarmName, + super(scope, props.alarmName, { + alarmName: props.alarmName, metric: new MathExpression({ expression: "badEvents/validEvents", label: "Observed failure rate",