@guardian/cdk 50.11.0 → 50.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,7 +20,7 @@ class GuApiGateway5xxPercentageAlarm extends alarm_1.GuAlarm {
20
20
  label: `% of 5XX responses served for ${props.app}`,
21
21
  period: aws_cdk_lib_1.Duration.minutes(1),
22
22
  });
23
- const defaultAlarmName = `High 5XX error % from ${props.app} (ApiGateway) in ${scope.stage}`;
23
+ const defaultAlarmName = `High 5XX error percentage from ${props.app} (ApiGateway) in ${scope.stage}`;
24
24
  const defaultDescription = `${props.app} exceeded ${props.tolerated5xxPercentage}% error rate`;
25
25
  const alarmProps = {
26
26
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"api-gateway-alarms.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/api-gateway-alarms.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AAEvC,+DAAkG;AAElG,kCAAsC;AAEtC,mCAAkC;AASlC;;;GAGG;AACH,MAAa,8BAA+B,SAAQ,eAAO;IACzD,YAAY,KAAc,EAAE,KAA0C;QACpE,MAAM,cAAc,GAAG,IAAI,+BAAc,CAAC;YACxC,UAAU,EAAE,WAAW;YACvB,YAAY,EAAE;gBACZ,EAAE,EAAE,KAAK,CAAC,kBAAkB,CAAC,iBAAiB,EAAE;gBAChD,EAAE,EAAE,KAAK,CAAC,kBAAkB,CAAC,WAAW,EAAE;aAC3C;YACD,KAAK,EAAE,iCAAiC,KAAK,CAAC,GAAG,EAAE;YACnD,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;SAC5B,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,yBAAyB,KAAK,CAAC,GAAG,oBAAoB,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7F,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,GAAG,aAAa,KAAK,CAAC,sBAAsB,cAAc,CAAC;QAC/F,MAAM,UAAU,GAAG;YACjB,GAAG,KAAK;YACR,MAAM,EAAE,cAAc;YACtB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,KAAK,CAAC,sBAAsB;YACvC,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,gBAAgB;YAC9C,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,kBAAkB;YAC9D,iBAAiB,EAAE,KAAK,CAAC,wCAAwC,IAAI,CAAC;SACvE,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,kCAAkC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC9F,CAAC;CACF;AAzBD,wEAyBC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport type { RestApi } from \"aws-cdk-lib/aws-apigateway\";\nimport { ComparisonOperator, MathExpression, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity } from \"../core\";\nimport type { GuAlarmProps, Http5xxAlarmProps } from \"./alarm\";\nimport { GuAlarm } from \"./alarm\";\n\ninterface GuApiGateway5xxPercentageAlarmProps\n extends Pick<GuAlarmProps, \"snsTopicName\">,\n Http5xxAlarmProps,\n AppIdentity {\n apiGatewayInstance: RestApi;\n}\n\n/**\n * Creates an alarm which is triggered whenever the percentage of requests with a 5xx response code exceeds\n * the specified threshold.\n */\nexport class GuApiGateway5xxPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuApiGateway5xxPercentageAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*m1/m2\",\n usingMetrics: {\n m1: props.apiGatewayInstance.metricServerError(),\n m2: props.apiGatewayInstance.metricCount(),\n },\n label: `% of 5XX responses served for ${props.app}`,\n period: Duration.minutes(1),\n });\n const defaultAlarmName = `High 5XX error % from ${props.app} (ApiGateway) in ${scope.stage}`;\n const defaultDescription = `${props.app} exceeded ${props.tolerated5xxPercentage}% error rate`;\n const alarmProps = {\n ...props,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.tolerated5xxPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n };\n super(scope, AppIdentity.suffixText(props, \"ApiGatewayHigh5xxPercentageAlarm\"), alarmProps);\n }\n}\n"]}
1
+ {"version":3,"file":"api-gateway-alarms.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/api-gateway-alarms.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AAEvC,+DAAkG;AAElG,kCAAsC;AAEtC,mCAAkC;AASlC;;;GAGG;AACH,MAAa,8BAA+B,SAAQ,eAAO;IACzD,YAAY,KAAc,EAAE,KAA0C;QACpE,MAAM,cAAc,GAAG,IAAI,+BAAc,CAAC;YACxC,UAAU,EAAE,WAAW;YACvB,YAAY,EAAE;gBACZ,EAAE,EAAE,KAAK,CAAC,kBAAkB,CAAC,iBAAiB,EAAE;gBAChD,EAAE,EAAE,KAAK,CAAC,kBAAkB,CAAC,WAAW,EAAE;aAC3C;YACD,KAAK,EAAE,iCAAiC,KAAK,CAAC,GAAG,EAAE;YACnD,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;SAC5B,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,kCAAkC,KAAK,CAAC,GAAG,oBAAoB,KAAK,CAAC,KAAK,EAAE,CAAC;QACtG,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,GAAG,aAAa,KAAK,CAAC,sBAAsB,cAAc,CAAC;QAC/F,MAAM,UAAU,GAAG;YACjB,GAAG,KAAK;YACR,MAAM,EAAE,cAAc;YACtB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,KAAK,CAAC,sBAAsB;YACvC,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,gBAAgB;YAC9C,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,kBAAkB;YAC9D,iBAAiB,EAAE,KAAK,CAAC,wCAAwC,IAAI,CAAC;SACvE,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,kCAAkC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC9F,CAAC;CACF;AAzBD,wEAyBC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport type { RestApi } from \"aws-cdk-lib/aws-apigateway\";\nimport { ComparisonOperator, MathExpression, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity } from \"../core\";\nimport type { GuAlarmProps, Http5xxAlarmProps } from \"./alarm\";\nimport { GuAlarm } from \"./alarm\";\n\ninterface GuApiGateway5xxPercentageAlarmProps\n extends Pick<GuAlarmProps, \"snsTopicName\">,\n Http5xxAlarmProps,\n AppIdentity {\n apiGatewayInstance: RestApi;\n}\n\n/**\n * Creates an alarm which is triggered whenever the percentage of requests with a 5xx response code exceeds\n * the specified threshold.\n */\nexport class GuApiGateway5xxPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuApiGateway5xxPercentageAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*m1/m2\",\n usingMetrics: {\n m1: props.apiGatewayInstance.metricServerError(),\n m2: props.apiGatewayInstance.metricCount(),\n },\n label: `% of 5XX responses served for ${props.app}`,\n period: Duration.minutes(1),\n });\n const defaultAlarmName = `High 5XX error percentage from ${props.app} (ApiGateway) in ${scope.stage}`;\n const defaultDescription = `${props.app} exceeded ${props.tolerated5xxPercentage}% error rate`;\n const alarmProps = {\n ...props,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.tolerated5xxPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n };\n super(scope, AppIdentity.suffixText(props, \"ApiGatewayHigh5xxPercentageAlarm\"), alarmProps);\n }\n}\n"]}
@@ -22,7 +22,7 @@ class GuAlb5xxPercentageAlarm extends alarm_1.GuAlarm {
22
22
  label: `% of 5XX responses served for ${props.app} (load balancer and instances combined)`,
23
23
  period: aws_cdk_lib_1.Duration.minutes(1),
24
24
  });
25
- const defaultAlarmName = `High 5XX error % from ${props.app} in ${scope.stage}`;
25
+ const defaultAlarmName = `High 5XX error percentage from ${props.app} in ${scope.stage}`;
26
26
  const defaultDescription = `${props.app} exceeded ${props.tolerated5xxPercentage}% error rate`;
27
27
  const alarmProps = {
28
28
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"ec2-alarms.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/ec2-alarms.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AACvC,+DAA6G;AAC7G,uFAAqF;AAErF,kCAAsC;AAEtC,mCAAkC;AAWlC;;;GAGG;AACH,MAAa,uBAAwB,SAAQ,eAAO;IAClD,YAAY,KAAc,EAAE,KAAmC;QAC7D,MAAM,cAAc,GAAG,IAAI,+BAAc,CAAC;YACxC,UAAU,EAAE,gBAAgB;YAC5B,YAAY,EAAE;gBACZ,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,wCAAW,CAAC,aAAa,CAAC;gBACrE,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,2CAAc,CAAC,gBAAgB,CAAC;gBAC9E,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,YAAY,EAAE;aAC9C;YACD,KAAK,EAAE,iCAAiC,KAAK,CAAC,GAAG,yCAAyC;YAC1F,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;SAC5B,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,yBAAyB,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC;QAChF,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,GAAG,aAAa,KAAK,CAAC,sBAAsB,cAAc,CAAC;QAC/F,MAAM,UAAU,GAAG;YACjB,GAAG,KAAK;YACR,MAAM,EAAE,cAAc;YACtB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,KAAK,CAAC,sBAAsB;YACvC,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,gBAAgB;YAC9C,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,kBAAkB;YAC9D,iBAAiB,EAAE,KAAK,CAAC,wCAAwC,IAAI,CAAC;SACvE,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAE,UAAU,CAAC,CAAC;IACpF,CAAC;CACF;AA1BD,0DA0BC;AAED;;GAEG;AACH,MAAa,yBAA0B,SAAQ,eAAO;IACpD,YAAY,KAAc,EAAE,KAAqC;QAC/D,MAAM,SAAS,GAAG,2BAA2B,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC;QAE3E,MAAM,MAAM,GAAG,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,iBAAiB,GAAG,EAAE,CAAC;QAC7B,MAAM,kBAAkB,GAAG,sBAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,iBAAiB,CAAC,CAAC,aAAa,EAAE,CAAC;QAEpG,MAAM,gBAAgB,GAAG,GAAG,KAAK,CAAC,GAAG,qEAAqE,kBAAkB;;;;cAIlH,KAAK,CAAC,GAAG,yFAAyF,CAAC;QAC7G,MAAM,UAAU,GAAiB;YAC/B,GAAG,KAAK;YACR,SAAS,EAAE,SAAS;YACpB,gBAAgB,EAAE,gBAAgB;YAClC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,0BAAS,CAAC,OAAO,EAAE,CAAC;YACrG,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,CAAC;YACZ,kBAAkB,EAAE,mCAAkB,CAAC,kCAAkC;YACzE,iBAAiB,EAAE,EAAE;YACrB,iBAAiB;SAClB,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,yBAAyB,CAAC,EAAE,UAAU,CAAC,CAAC;IACrF,CAAC;CACF;AA1BD,8DA0BC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport { ComparisonOperator, MathExpression, Statistic, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport { HttpCodeElb, HttpCodeTarget } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity } from \"../core\";\nimport type { GuApplicationLoadBalancer, GuApplicationTargetGroup } from \"../loadbalancing\";\nimport { GuAlarm } from \"./alarm\";\nimport type { GuAlarmProps, Http5xxAlarmProps } from \"./alarm\";\n\ninterface GuAlb5xxPercentageAlarmProps extends Pick<GuAlarmProps, \"snsTopicName\">, Http5xxAlarmProps, AppIdentity {\n loadBalancer: GuApplicationLoadBalancer;\n}\n\ninterface GuUnhealthyInstancesAlarmProps extends Pick<GuAlarmProps, \"snsTopicName\" | \"actionsEnabled\">, AppIdentity {\n targetGroup: GuApplicationTargetGroup;\n}\n\n/**\n * Creates an alarm which is triggered whenever the percentage of requests with a 5xx response code exceeds\n * the specified threshold.\n */\nexport class GuAlb5xxPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuAlb5xxPercentageAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*(m1+m2)/m3\",\n usingMetrics: {\n m1: props.loadBalancer.metrics.httpCodeElb(HttpCodeElb.ELB_5XX_COUNT),\n m2: props.loadBalancer.metrics.httpCodeTarget(HttpCodeTarget.TARGET_5XX_COUNT),\n m3: props.loadBalancer.metrics.requestCount(),\n },\n label: `% of 5XX responses served for ${props.app} (load balancer and instances combined)`,\n period: Duration.minutes(1),\n });\n const defaultAlarmName = `High 5XX error % from ${props.app} in ${scope.stage}`;\n const defaultDescription = `${props.app} exceeded ${props.tolerated5xxPercentage}% error rate`;\n const alarmProps = {\n ...props,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.tolerated5xxPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n };\n super(scope, AppIdentity.suffixText(props, \"High5xxPercentageAlarm\"), alarmProps);\n }\n}\n\n/**\n * Creates an alarm which is triggered whenever there have been several healthcheck failures within a single hour.\n */\nexport class GuUnhealthyInstancesAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuUnhealthyInstancesAlarmProps) {\n const alarmName = `Unhealthy instances for ${props.app} in ${scope.stage}`;\n\n const period = Duration.minutes(1);\n const evaluationPeriods = 60;\n const evaluationInterval = Duration.minutes(period.toMinutes() * evaluationPeriods).toHumanString();\n\n const alarmDescription = `${props.app}'s instances have failed healthchecks several times over the last ${evaluationInterval}.\n This typically results in the AutoScaling Group cycling instances and can lead to problems with deployment,\n scaling or handling traffic spikes.\n\n Check ${props.app}'s application logs or ssh onto an unhealthy instance in order to debug these problems.`;\n const alarmProps: GuAlarmProps = {\n ...props,\n alarmName: alarmName,\n alarmDescription: alarmDescription,\n metric: props.targetGroup.metrics.unhealthyHostCount().with({ period, statistic: Statistic.MAXIMUM }),\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: 1,\n comparisonOperator: ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,\n datapointsToAlarm: 30,\n evaluationPeriods,\n };\n super(scope, AppIdentity.suffixText(props, \"UnhealthyInstancesAlarm\"), alarmProps);\n }\n}\n"]}
1
+ {"version":3,"file":"ec2-alarms.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/ec2-alarms.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AACvC,+DAA6G;AAC7G,uFAAqF;AAErF,kCAAsC;AAEtC,mCAAkC;AAWlC;;;GAGG;AACH,MAAa,uBAAwB,SAAQ,eAAO;IAClD,YAAY,KAAc,EAAE,KAAmC;QAC7D,MAAM,cAAc,GAAG,IAAI,+BAAc,CAAC;YACxC,UAAU,EAAE,gBAAgB;YAC5B,YAAY,EAAE;gBACZ,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,wCAAW,CAAC,aAAa,CAAC;gBACrE,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,2CAAc,CAAC,gBAAgB,CAAC;gBAC9E,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,YAAY,EAAE;aAC9C;YACD,KAAK,EAAE,iCAAiC,KAAK,CAAC,GAAG,yCAAyC;YAC1F,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;SAC5B,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,kCAAkC,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC;QACzF,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,GAAG,aAAa,KAAK,CAAC,sBAAsB,cAAc,CAAC;QAC/F,MAAM,UAAU,GAAG;YACjB,GAAG,KAAK;YACR,MAAM,EAAE,cAAc;YACtB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,KAAK,CAAC,sBAAsB;YACvC,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,gBAAgB;YAC9C,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,kBAAkB;YAC9D,iBAAiB,EAAE,KAAK,CAAC,wCAAwC,IAAI,CAAC;SACvE,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAE,UAAU,CAAC,CAAC;IACpF,CAAC;CACF;AA1BD,0DA0BC;AAED;;GAEG;AACH,MAAa,yBAA0B,SAAQ,eAAO;IACpD,YAAY,KAAc,EAAE,KAAqC;QAC/D,MAAM,SAAS,GAAG,2BAA2B,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC;QAE3E,MAAM,MAAM,GAAG,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,iBAAiB,GAAG,EAAE,CAAC;QAC7B,MAAM,kBAAkB,GAAG,sBAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,iBAAiB,CAAC,CAAC,aAAa,EAAE,CAAC;QAEpG,MAAM,gBAAgB,GAAG,GAAG,KAAK,CAAC,GAAG,qEAAqE,kBAAkB;;;;cAIlH,KAAK,CAAC,GAAG,yFAAyF,CAAC;QAC7G,MAAM,UAAU,GAAiB;YAC/B,GAAG,KAAK;YACR,SAAS,EAAE,SAAS;YACpB,gBAAgB,EAAE,gBAAgB;YAClC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,0BAAS,CAAC,OAAO,EAAE,CAAC;YACrG,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,CAAC;YACZ,kBAAkB,EAAE,mCAAkB,CAAC,kCAAkC;YACzE,iBAAiB,EAAE,EAAE;YACrB,iBAAiB;SAClB,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,yBAAyB,CAAC,EAAE,UAAU,CAAC,CAAC;IACrF,CAAC;CACF;AA1BD,8DA0BC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport { ComparisonOperator, MathExpression, Statistic, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport { HttpCodeElb, HttpCodeTarget } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity } from \"../core\";\nimport type { GuApplicationLoadBalancer, GuApplicationTargetGroup } from \"../loadbalancing\";\nimport { GuAlarm } from \"./alarm\";\nimport type { GuAlarmProps, Http5xxAlarmProps } from \"./alarm\";\n\ninterface GuAlb5xxPercentageAlarmProps extends Pick<GuAlarmProps, \"snsTopicName\">, Http5xxAlarmProps, AppIdentity {\n loadBalancer: GuApplicationLoadBalancer;\n}\n\ninterface GuUnhealthyInstancesAlarmProps extends Pick<GuAlarmProps, \"snsTopicName\" | \"actionsEnabled\">, AppIdentity {\n targetGroup: GuApplicationTargetGroup;\n}\n\n/**\n * Creates an alarm which is triggered whenever the percentage of requests with a 5xx response code exceeds\n * the specified threshold.\n */\nexport class GuAlb5xxPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuAlb5xxPercentageAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*(m1+m2)/m3\",\n usingMetrics: {\n m1: props.loadBalancer.metrics.httpCodeElb(HttpCodeElb.ELB_5XX_COUNT),\n m2: props.loadBalancer.metrics.httpCodeTarget(HttpCodeTarget.TARGET_5XX_COUNT),\n m3: props.loadBalancer.metrics.requestCount(),\n },\n label: `% of 5XX responses served for ${props.app} (load balancer and instances combined)`,\n period: Duration.minutes(1),\n });\n const defaultAlarmName = `High 5XX error percentage from ${props.app} in ${scope.stage}`;\n const defaultDescription = `${props.app} exceeded ${props.tolerated5xxPercentage}% error rate`;\n const alarmProps = {\n ...props,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.tolerated5xxPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n };\n super(scope, AppIdentity.suffixText(props, \"High5xxPercentageAlarm\"), alarmProps);\n }\n}\n\n/**\n * Creates an alarm which is triggered whenever there have been several healthcheck failures within a single hour.\n */\nexport class GuUnhealthyInstancesAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuUnhealthyInstancesAlarmProps) {\n const alarmName = `Unhealthy instances for ${props.app} in ${scope.stage}`;\n\n const period = Duration.minutes(1);\n const evaluationPeriods = 60;\n const evaluationInterval = Duration.minutes(period.toMinutes() * evaluationPeriods).toHumanString();\n\n const alarmDescription = `${props.app}'s instances have failed healthchecks several times over the last ${evaluationInterval}.\n This typically results in the AutoScaling Group cycling instances and can lead to problems with deployment,\n scaling or handling traffic spikes.\n\n Check ${props.app}'s application logs or ssh onto an unhealthy instance in order to debug these problems.`;\n const alarmProps: GuAlarmProps = {\n ...props,\n alarmName: alarmName,\n alarmDescription: alarmDescription,\n metric: props.targetGroup.metrics.unhealthyHostCount().with({ period, statistic: Statistic.MAXIMUM }),\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: 1,\n comparisonOperator: ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,\n datapointsToAlarm: 30,\n evaluationPeriods,\n };\n super(scope, AppIdentity.suffixText(props, \"UnhealthyInstancesAlarm\"), alarmProps);\n }\n}\n"]}
@@ -15,7 +15,7 @@ class GuLambdaErrorPercentageAlarm extends alarm_1.GuAlarm {
15
15
  label: `Error % of ${props.lambda.functionName}`,
16
16
  period: props.lengthOfEvaluationPeriod ?? aws_cdk_lib_1.Duration.minutes(1),
17
17
  });
18
- const defaultAlarmName = `High error % from ${props.lambda.functionName} lambda in ${scope.stage}`;
18
+ const defaultAlarmName = `High error percentage from ${props.lambda.functionName} lambda in ${scope.stage}`;
19
19
  const defaultDescription = `${props.lambda.functionName} exceeded ${props.toleratedErrorPercentage}% error rate`;
20
20
  const alarmProps = {
21
21
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"lambda-alarms.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/lambda-alarms.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AACvC,+DAAkG;AAGlG,mCAAkC;AAkBlC;;GAEG;AACH,MAAa,4BAA6B,SAAQ,eAAO;IACvD,YAAY,KAAc,EAAE,EAAU,EAAE,KAAyB;QAC/D,MAAM,cAAc,GAAG,IAAI,+BAAc,CAAC;YACxC,UAAU,EAAE,WAAW;YACvB,YAAY,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE;YACvF,KAAK,EAAE,cAAc,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE;YAChD,MAAM,EAAE,KAAK,CAAC,wBAAwB,IAAI,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;SAC9D,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,qBAAqB,KAAK,CAAC,MAAM,CAAC,YAAY,cAAc,KAAK,CAAC,KAAK,EAAE,CAAC;QACnG,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,aAAa,KAAK,CAAC,wBAAwB,cAAc,CAAC;QACjH,MAAM,UAAU,GAAiB;YAC/B,GAAG,KAAK;YACR,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;YACrB,MAAM,EAAE,cAAc;YACtB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,KAAK,CAAC,wBAAwB;YACzC,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,iBAAiB,EAAE,KAAK,CAAC,kDAAkD,IAAI,CAAC;YAChF,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,gBAAgB;YAC9C,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,kBAAkB;SAC/D,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;IAC/B,CAAC;CACF;AAvBD,oEAuBC;AA4BD,MAAa,uBAAwB,SAAQ,eAAO;IAClD,YAAY,KAAc,EAAE,EAAU,EAAE,KAAmC;QACzE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,GAAG,KAAK;YACR,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;YACrB,SAAS,EACP,KAAK,CAAC,SAAS,IAAI,+BAA+B,KAAK,CAAC,MAAM,CAAC,YAAY,cAAc,KAAK,CAAC,KAAK,GAAG;YACzG,gBAAgB,EACd,KAAK,CAAC,gBAAgB,IAAI,4EAA4E;YACxG,SAAS,EAAE,KAAK,CAAC,wBAAwB,IAAI,CAAC;YAC9C,iBAAiB,EAAE,KAAK,CAAC,wCAAwC,IAAI,CAAC;YACtE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC;gBACnC,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,SAAS,EAAE,KAAK;aACjB,CAAC;YACF,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;SAC9D,CAAC,CAAC;IACL,CAAC;CACF;AAnBD,0DAmBC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport { ComparisonOperator, MathExpression, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport type { GuLambdaFunction } from \"../lambda\";\nimport { GuAlarm } from \"./alarm\";\nimport type { GuAlarmProps } from \"./alarm\";\n\nexport interface GuLambdaErrorPercentageMonitoringProps\n extends Omit<\n GuAlarmProps,\n \"metric\" | \"threshold\" | \"comparisonOperator\" | \"evaluationPeriods\" | \"treatMissingData\" | \"app\"\n > {\n toleratedErrorPercentage: number;\n lengthOfEvaluationPeriod?: Duration;\n numberOfEvaluationPeriodsAboveThresholdBeforeAlarm?: number;\n noMonitoring?: false;\n}\n\ninterface GuLambdaAlarmProps extends GuLambdaErrorPercentageMonitoringProps {\n lambda: GuLambdaFunction;\n}\n\n/**\n * Creates an alarm which is triggered whenever the error percentage specified is exceeded.\n */\nexport class GuLambdaErrorPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, id: string, props: GuLambdaAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*m1/m2\",\n usingMetrics: { m1: props.lambda.metricErrors(), m2: props.lambda.metricInvocations() },\n label: `Error % of ${props.lambda.functionName}`,\n period: props.lengthOfEvaluationPeriod ?? Duration.minutes(1),\n });\n const defaultAlarmName = `High error % from ${props.lambda.functionName} lambda in ${scope.stage}`;\n const defaultDescription = `${props.lambda.functionName} exceeded ${props.toleratedErrorPercentage}% error rate`;\n const alarmProps: GuAlarmProps = {\n ...props,\n app: props.lambda.app,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.toleratedErrorPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n evaluationPeriods: props.numberOfEvaluationPeriodsAboveThresholdBeforeAlarm ?? 1,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n };\n super(scope, id, alarmProps);\n }\n}\n\nexport interface GuLambdaThrottlingMonitoringProps\n extends Omit<\n GuAlarmProps,\n \"metric\" | \"threshold\" | \"comparisonOperator\" | \"evaluationPeriods\" | \"treatMissingData\" | \"app\"\n > {\n /**\n * Sum of thottled invocations above which to alarm.\n *\n * @defaultValue 0\n */\n toleratedThrottlingCount?: number;\n\n /**\n * Evaluation period in minutes for alarm.\n *\n * @defaultValue 1\n */\n numberOfMinutesAboveThresholdBeforeAlarm?: number;\n\n noMonitoring?: false;\n}\n\ninterface GuLambdaThrottlingAlarmProps extends GuLambdaThrottlingMonitoringProps {\n lambda: GuLambdaFunction;\n}\n\nexport class GuLambdaThrottlingAlarm extends GuAlarm {\n constructor(scope: GuStack, id: string, props: GuLambdaThrottlingAlarmProps) {\n super(scope, id, {\n ...props,\n app: props.lambda.app,\n alarmName:\n props.alarmName ?? `Lambda throttling alarm for ${props.lambda.functionName} lambda in ${scope.stage}.`,\n alarmDescription:\n props.alarmDescription ?? \"Alarm when lambda is throttled (which causes requests to fail with a 429).\",\n threshold: props.toleratedThrottlingCount ?? 0,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n metric: props.lambda.metricThrottles({\n period: Duration.seconds(60),\n statistic: \"sum\",\n }),\n treatMissingData: TreatMissingData.NOT_BREACHING,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n });\n }\n}\n"]}
1
+ {"version":3,"file":"lambda-alarms.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/lambda-alarms.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AACvC,+DAAkG;AAGlG,mCAAkC;AAkBlC;;GAEG;AACH,MAAa,4BAA6B,SAAQ,eAAO;IACvD,YAAY,KAAc,EAAE,EAAU,EAAE,KAAyB;QAC/D,MAAM,cAAc,GAAG,IAAI,+BAAc,CAAC;YACxC,UAAU,EAAE,WAAW;YACvB,YAAY,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE;YACvF,KAAK,EAAE,cAAc,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE;YAChD,MAAM,EAAE,KAAK,CAAC,wBAAwB,IAAI,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;SAC9D,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,8BAA8B,KAAK,CAAC,MAAM,CAAC,YAAY,cAAc,KAAK,CAAC,KAAK,EAAE,CAAC;QAC5G,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,aAAa,KAAK,CAAC,wBAAwB,cAAc,CAAC;QACjH,MAAM,UAAU,GAAiB;YAC/B,GAAG,KAAK;YACR,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;YACrB,MAAM,EAAE,cAAc;YACtB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,KAAK,CAAC,wBAAwB;YACzC,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,iBAAiB,EAAE,KAAK,CAAC,kDAAkD,IAAI,CAAC;YAChF,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,gBAAgB;YAC9C,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,kBAAkB;SAC/D,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;IAC/B,CAAC;CACF;AAvBD,oEAuBC;AA4BD,MAAa,uBAAwB,SAAQ,eAAO;IAClD,YAAY,KAAc,EAAE,EAAU,EAAE,KAAmC;QACzE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,GAAG,KAAK;YACR,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;YACrB,SAAS,EACP,KAAK,CAAC,SAAS,IAAI,+BAA+B,KAAK,CAAC,MAAM,CAAC,YAAY,cAAc,KAAK,CAAC,KAAK,GAAG;YACzG,gBAAgB,EACd,KAAK,CAAC,gBAAgB,IAAI,4EAA4E;YACxG,SAAS,EAAE,KAAK,CAAC,wBAAwB,IAAI,CAAC;YAC9C,iBAAiB,EAAE,KAAK,CAAC,wCAAwC,IAAI,CAAC;YACtE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC;gBACnC,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,SAAS,EAAE,KAAK;aACjB,CAAC;YACF,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;SAC9D,CAAC,CAAC;IACL,CAAC;CACF;AAnBD,0DAmBC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport { ComparisonOperator, MathExpression, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport type { GuLambdaFunction } from \"../lambda\";\nimport { GuAlarm } from \"./alarm\";\nimport type { GuAlarmProps } from \"./alarm\";\n\nexport interface GuLambdaErrorPercentageMonitoringProps\n extends Omit<\n GuAlarmProps,\n \"metric\" | \"threshold\" | \"comparisonOperator\" | \"evaluationPeriods\" | \"treatMissingData\" | \"app\"\n > {\n toleratedErrorPercentage: number;\n lengthOfEvaluationPeriod?: Duration;\n numberOfEvaluationPeriodsAboveThresholdBeforeAlarm?: number;\n noMonitoring?: false;\n}\n\ninterface GuLambdaAlarmProps extends GuLambdaErrorPercentageMonitoringProps {\n lambda: GuLambdaFunction;\n}\n\n/**\n * Creates an alarm which is triggered whenever the error percentage specified is exceeded.\n */\nexport class GuLambdaErrorPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, id: string, props: GuLambdaAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*m1/m2\",\n usingMetrics: { m1: props.lambda.metricErrors(), m2: props.lambda.metricInvocations() },\n label: `Error % of ${props.lambda.functionName}`,\n period: props.lengthOfEvaluationPeriod ?? Duration.minutes(1),\n });\n const defaultAlarmName = `High error percentage from ${props.lambda.functionName} lambda in ${scope.stage}`;\n const defaultDescription = `${props.lambda.functionName} exceeded ${props.toleratedErrorPercentage}% error rate`;\n const alarmProps: GuAlarmProps = {\n ...props,\n app: props.lambda.app,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.toleratedErrorPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n evaluationPeriods: props.numberOfEvaluationPeriodsAboveThresholdBeforeAlarm ?? 1,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n };\n super(scope, id, alarmProps);\n }\n}\n\nexport interface GuLambdaThrottlingMonitoringProps\n extends Omit<\n GuAlarmProps,\n \"metric\" | \"threshold\" | \"comparisonOperator\" | \"evaluationPeriods\" | \"treatMissingData\" | \"app\"\n > {\n /**\n * Sum of thottled invocations above which to alarm.\n *\n * @defaultValue 0\n */\n toleratedThrottlingCount?: number;\n\n /**\n * Evaluation period in minutes for alarm.\n *\n * @defaultValue 1\n */\n numberOfMinutesAboveThresholdBeforeAlarm?: number;\n\n noMonitoring?: false;\n}\n\ninterface GuLambdaThrottlingAlarmProps extends GuLambdaThrottlingMonitoringProps {\n lambda: GuLambdaFunction;\n}\n\nexport class GuLambdaThrottlingAlarm extends GuAlarm {\n constructor(scope: GuStack, id: string, props: GuLambdaThrottlingAlarmProps) {\n super(scope, id, {\n ...props,\n app: props.lambda.app,\n alarmName:\n props.alarmName ?? `Lambda throttling alarm for ${props.lambda.functionName} lambda in ${scope.stage}.`,\n alarmDescription:\n props.alarmDescription ?? \"Alarm when lambda is throttled (which causes requests to fail with a 429).\",\n threshold: props.toleratedThrottlingCount ?? 0,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n metric: props.lambda.metricThrottles({\n period: Duration.seconds(60),\n statistic: \"sum\",\n }),\n treatMissingData: TreatMissingData.NOT_BREACHING,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n });\n }\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@guardian/cdk",
3
3
  "description": "Generic Guardian flavoured AWS CDK components",
4
- "version": "50.11.0",
4
+ "version": "50.11.2",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [
@@ -31,12 +31,12 @@
31
31
  "@guardian/eslint-config-typescript": "7.0.0",
32
32
  "@guardian/eslint-plugin-tsdoc-required": "^0.1.3",
33
33
  "@types/git-url-parse": "^9.0.1",
34
- "@types/jest": "^29.5.4",
35
- "@types/js-yaml": "^4.0.5",
34
+ "@types/jest": "^29.5.5",
35
+ "@types/js-yaml": "^4.0.6",
36
36
  "@types/lodash.camelcase": "^4.3.7",
37
37
  "@types/lodash.kebabcase": "^4.1.7",
38
38
  "@types/lodash.upperfirst": "^4.3.7",
39
- "@types/node": "20.6.0",
39
+ "@types/node": "20.6.3",
40
40
  "@types/yargs": "^17.0.19",
41
41
  "aws-cdk": "2.95.1",
42
42
  "cz-conventional-changelog": "^3.3.0",
@@ -45,7 +45,7 @@
45
45
  "gh-pages": "^6.0.0",
46
46
  "jest": "^29.7.0",
47
47
  "prettier": "^3.0.3",
48
- "semantic-release": "^21.1.1",
48
+ "semantic-release": "^22.0.0",
49
49
  "serve": "^14.2.1",
50
50
  "ts-jest": "^29.1.1",
51
51
  "ts-node": "^10.9.1",
@@ -55,7 +55,7 @@
55
55
  "dependencies": {
56
56
  "@oclif/core": "2.15.0",
57
57
  "aws-cdk-lib": "2.95.1",
58
- "aws-sdk": "^2.1457.0",
58
+ "aws-sdk": "^2.1461.0",
59
59
  "chalk": "^4.1.2",
60
60
  "codemaker": "^1.88.0",
61
61
  "constructs": "10.2.70",