From 34a5684a40c046c5f6a169bd4a0e060101e516d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Hord=C4=9Bj=C4=8Duk?= Date: Wed, 23 Mar 2022 18:45:27 +0100 Subject: [PATCH] feat(apigateway): support trimmed stats and latency graph configuration (#81) Introduces latency factory methods with latency type parameter in Api Gateway. It will be useful for creating trimmed-mean alarms, etc. Closes #65 Closes #47 --- _By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license_ --- API.md | 886 +++++++++++++++- .../monitoring/alarms/LatencyAlarmFactory.ts | 27 + .../aws-apigateway/ApiGatewayMetricFactory.ts | 39 +- .../aws-apigateway/ApiGatewayMonitoring.ts | 125 ++- .../ApiGatewayV2HttpApiMetricFactory.ts | 79 +- .../ApiGatewayV2HttpApiMonitoring.ts | 237 +++-- .../MonitoringAspect.test.ts.snap | 28 +- .../ApiGatewayMonitoring.test.ts | 102 +- .../ApiGatewayMonitoring.test.ts.snap | 491 ++++----- .../ApiGatewayV2HttpApiMonitoring.test.ts | 164 ++- ...ApiGatewayV2HttpApiMonitoring.test.ts.snap | 958 +++++++++++++++++- 11 files changed, 2495 insertions(+), 641 deletions(-) diff --git a/API.md b/API.md index df5582e7..8b2e067d 100644 --- a/API.md +++ b/API.md @@ -3774,10 +3774,22 @@ const apiGatewayMonitoringOptions: ApiGatewayMonitoringOptions = { ... } | add5XXFaultCountAlarm | {[ key: string ]: ErrorCountThreshold} | *No description.* | | add5XXFaultRateAlarm | {[ key: string ]: ErrorRateThreshold} | *No description.* | | addHighTpsAlarm | {[ key: string ]: HighTpsThreshold} | *No description.* | +| addLatencyAverageAlarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP100Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLowTpsAlarm | {[ key: string ]: LowTpsThreshold} | *No description.* | +| latencyTypesToRender | LatencyType[] | You can specify what latency types you want to be rendered in the dashboards. | --- @@ -3928,6 +3940,26 @@ public readonly addHighTpsAlarm: {[ key: string ]: HighTpsThreshold}; --- +##### `addLatencyAverageAlarm`Optional + +```typescript +public readonly addLatencyAverageAlarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyP100Alarm`Optional + +```typescript +public readonly addLatencyP100Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP50Alarm`Optional ```typescript @@ -3938,6 +3970,16 @@ public readonly addLatencyP50Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyP70Alarm`Optional + +```typescript +public readonly addLatencyP70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP90Alarm`Optional ```typescript @@ -3948,6 +3990,26 @@ public readonly addLatencyP90Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyP9999Alarm`Optional + +```typescript +public readonly addLatencyP9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyP999Alarm`Optional + +```typescript +public readonly addLatencyP999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP99Alarm`Optional ```typescript @@ -3958,6 +4020,66 @@ public readonly addLatencyP99Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyTM50Alarm`Optional + +```typescript +public readonly addLatencyTM50Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM70Alarm`Optional + +```typescript +public readonly addLatencyTM70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM90Alarm`Optional + +```typescript +public readonly addLatencyTM90Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM9999Alarm`Optional + +```typescript +public readonly addLatencyTM9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM999Alarm`Optional + +```typescript +public readonly addLatencyTM999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM99Alarm`Optional + +```typescript +public readonly addLatencyTM99Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLowTpsAlarm`Optional ```typescript @@ -3968,6 +4090,23 @@ public readonly addLowTpsAlarm: {[ key: string ]: LowTpsThreshold}; --- +##### `latencyTypesToRender`Optional + +```typescript +public readonly latencyTypesToRender: LatencyType[]; +``` + +- *Type:* LatencyType[] +- *Default:* p50, p90, p99 ( + +You can specify what latency types you want to be rendered in the dashboards. + +Note: any latency type with an alarm will be also added automatically. If the list is undefined, default values will be shown. If the list is empty, only the latency types with an alarm will be shown (if any). + +> [DefaultLatencyTypesToRender)](DefaultLatencyTypesToRender)) + +--- + ### ApiGatewayMonitoringProps #### Initializer @@ -4000,10 +4139,22 @@ const apiGatewayMonitoringProps: ApiGatewayMonitoringProps = { ... } | add5XXFaultCountAlarm | {[ key: string ]: ErrorCountThreshold} | *No description.* | | add5XXFaultRateAlarm | {[ key: string ]: ErrorRateThreshold} | *No description.* | | addHighTpsAlarm | {[ key: string ]: HighTpsThreshold} | *No description.* | +| addLatencyAverageAlarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP100Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLowTpsAlarm | {[ key: string ]: LowTpsThreshold} | *No description.* | +| latencyTypesToRender | LatencyType[] | You can specify what latency types you want to be rendered in the dashboards. | --- @@ -4223,6 +4374,26 @@ public readonly addHighTpsAlarm: {[ key: string ]: HighTpsThreshold}; --- +##### `addLatencyAverageAlarm`Optional + +```typescript +public readonly addLatencyAverageAlarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyP100Alarm`Optional + +```typescript +public readonly addLatencyP100Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP50Alarm`Optional ```typescript @@ -4233,6 +4404,16 @@ public readonly addLatencyP50Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyP70Alarm`Optional + +```typescript +public readonly addLatencyP70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP90Alarm`Optional ```typescript @@ -4243,6 +4424,26 @@ public readonly addLatencyP90Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyP9999Alarm`Optional + +```typescript +public readonly addLatencyP9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyP999Alarm`Optional + +```typescript +public readonly addLatencyP999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP99Alarm`Optional ```typescript @@ -4253,6 +4454,66 @@ public readonly addLatencyP99Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyTM50Alarm`Optional + +```typescript +public readonly addLatencyTM50Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM70Alarm`Optional + +```typescript +public readonly addLatencyTM70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM90Alarm`Optional + +```typescript +public readonly addLatencyTM90Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM9999Alarm`Optional + +```typescript +public readonly addLatencyTM9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM999Alarm`Optional + +```typescript +public readonly addLatencyTM999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM99Alarm`Optional + +```typescript +public readonly addLatencyTM99Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLowTpsAlarm`Optional ```typescript @@ -4263,6 +4524,23 @@ public readonly addLowTpsAlarm: {[ key: string ]: LowTpsThreshold}; --- +##### `latencyTypesToRender`Optional + +```typescript +public readonly latencyTypesToRender: LatencyType[]; +``` + +- *Type:* LatencyType[] +- *Default:* p50, p90, p99 ( + +You can specify what latency types you want to be rendered in the dashboards. + +Note: any latency type with an alarm will be also added automatically. If the list is undefined, default values will be shown. If the list is empty, only the latency types with an alarm will be shown (if any). + +> [DefaultLatencyTypesToRender)](DefaultLatencyTypesToRender)) + +--- + ### ApiGatewayV2HttpApiMetricFactoryProps #### Initializer @@ -4385,13 +4663,36 @@ const apiGatewayV2HttpApiMonitoringProps: ApiGatewayV2HttpApiMonitoringProps = { | add5xxCountAlarm | {[ key: string ]: ErrorCountThreshold} | *No description.* | | add5xxRateAlarm | {[ key: string ]: ErrorRateThreshold} | *No description.* | | addHighTpsAlarm | {[ key: string ]: HighTpsThreshold} | *No description.* | +| addIntegrationLatencyAverageAlarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyP100Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addIntegrationLatencyP50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyP70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addIntegrationLatencyP90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyP9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyP999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addIntegrationLatencyP99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyAverageAlarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP100Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLowTpsAlarm | {[ key: string ]: LowTpsThreshold} | *No description.* | +| latencyTypesToRender | LatencyType[] | You can specify what latency types you want to be rendered in the dashboards. | --- @@ -4609,6 +4910,26 @@ public readonly addHighTpsAlarm: {[ key: string ]: HighTpsThreshold}; --- +##### `addIntegrationLatencyAverageAlarm`Optional + +```typescript +public readonly addIntegrationLatencyAverageAlarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyP100Alarm`Optional + +```typescript +public readonly addIntegrationLatencyP100Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addIntegrationLatencyP50Alarm`Optional ```typescript @@ -4619,6 +4940,16 @@ public readonly addIntegrationLatencyP50Alarm: {[ key: string ]: LatencyThreshol --- +##### `addIntegrationLatencyP70Alarm`Optional + +```typescript +public readonly addIntegrationLatencyP70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addIntegrationLatencyP90Alarm`Optional ```typescript @@ -4629,6 +4960,26 @@ public readonly addIntegrationLatencyP90Alarm: {[ key: string ]: LatencyThreshol --- +##### `addIntegrationLatencyP9999Alarm`Optional + +```typescript +public readonly addIntegrationLatencyP9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyP999Alarm`Optional + +```typescript +public readonly addIntegrationLatencyP999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addIntegrationLatencyP99Alarm`Optional ```typescript @@ -4639,6 +4990,86 @@ public readonly addIntegrationLatencyP99Alarm: {[ key: string ]: LatencyThreshol --- +##### `addIntegrationLatencyTM50Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM50Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyTM70Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyTM90Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM90Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyTM9999Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyTM999Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyTM99Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM99Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyAverageAlarm`Optional + +```typescript +public readonly addLatencyAverageAlarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyP100Alarm`Optional + +```typescript +public readonly addLatencyP100Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP50Alarm`Optional ```typescript @@ -4649,6 +5080,16 @@ public readonly addLatencyP50Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyP70Alarm`Optional + +```typescript +public readonly addLatencyP70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP90Alarm`Optional ```typescript @@ -4659,6 +5100,26 @@ public readonly addLatencyP90Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyP9999Alarm`Optional + +```typescript +public readonly addLatencyP9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyP999Alarm`Optional + +```typescript +public readonly addLatencyP999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP99Alarm`Optional ```typescript @@ -4669,6 +5130,66 @@ public readonly addLatencyP99Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyTM50Alarm`Optional + +```typescript +public readonly addLatencyTM50Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM70Alarm`Optional + +```typescript +public readonly addLatencyTM70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM90Alarm`Optional + +```typescript +public readonly addLatencyTM90Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM9999Alarm`Optional + +```typescript +public readonly addLatencyTM9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM999Alarm`Optional + +```typescript +public readonly addLatencyTM999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM99Alarm`Optional + +```typescript +public readonly addLatencyTM99Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLowTpsAlarm`Optional ```typescript @@ -4679,6 +5200,23 @@ public readonly addLowTpsAlarm: {[ key: string ]: LowTpsThreshold}; --- +##### `latencyTypesToRender`Optional + +```typescript +public readonly latencyTypesToRender: LatencyType[]; +``` + +- *Type:* LatencyType[] +- *Default:* p50, p90, p99 ( + +You can specify what latency types you want to be rendered in the dashboards. + +Note: any latency type with an alarm will be also added automatically. If the list is undefined, default values will be shown. If the list is empty, only the latency types with an alarm will be shown (if any). + +> [DefaultLatencyTypesShown)](DefaultLatencyTypesShown)) + +--- + ### ApiGatewayV2MonitoringOptions #### Initializer @@ -4705,13 +5243,36 @@ const apiGatewayV2MonitoringOptions: ApiGatewayV2MonitoringOptions = { ... } | add5xxCountAlarm | {[ key: string ]: ErrorCountThreshold} | *No description.* | | add5xxRateAlarm | {[ key: string ]: ErrorRateThreshold} | *No description.* | | addHighTpsAlarm | {[ key: string ]: HighTpsThreshold} | *No description.* | +| addIntegrationLatencyAverageAlarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyP100Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addIntegrationLatencyP50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyP70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addIntegrationLatencyP90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyP9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyP999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addIntegrationLatencyP99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addIntegrationLatencyTM99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyAverageAlarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP100Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyP999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLatencyP99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM50Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM70Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM90Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM9999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM999Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | +| addLatencyTM99Alarm | {[ key: string ]: LatencyThreshold} | *No description.* | | addLowTpsAlarm | {[ key: string ]: LowTpsThreshold} | *No description.* | +| latencyTypesToRender | LatencyType[] | You can specify what latency types you want to be rendered in the dashboards. | --- @@ -4862,6 +5423,26 @@ public readonly addHighTpsAlarm: {[ key: string ]: HighTpsThreshold}; --- +##### `addIntegrationLatencyAverageAlarm`Optional + +```typescript +public readonly addIntegrationLatencyAverageAlarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyP100Alarm`Optional + +```typescript +public readonly addIntegrationLatencyP100Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addIntegrationLatencyP50Alarm`Optional ```typescript @@ -4872,6 +5453,16 @@ public readonly addIntegrationLatencyP50Alarm: {[ key: string ]: LatencyThreshol --- +##### `addIntegrationLatencyP70Alarm`Optional + +```typescript +public readonly addIntegrationLatencyP70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addIntegrationLatencyP90Alarm`Optional ```typescript @@ -4882,6 +5473,26 @@ public readonly addIntegrationLatencyP90Alarm: {[ key: string ]: LatencyThreshol --- +##### `addIntegrationLatencyP9999Alarm`Optional + +```typescript +public readonly addIntegrationLatencyP9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyP999Alarm`Optional + +```typescript +public readonly addIntegrationLatencyP999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addIntegrationLatencyP99Alarm`Optional ```typescript @@ -4892,6 +5503,86 @@ public readonly addIntegrationLatencyP99Alarm: {[ key: string ]: LatencyThreshol --- +##### `addIntegrationLatencyTM50Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM50Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyTM70Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyTM90Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM90Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyTM9999Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyTM999Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addIntegrationLatencyTM99Alarm`Optional + +```typescript +public readonly addIntegrationLatencyTM99Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyAverageAlarm`Optional + +```typescript +public readonly addLatencyAverageAlarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyP100Alarm`Optional + +```typescript +public readonly addLatencyP100Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP50Alarm`Optional ```typescript @@ -4902,6 +5593,16 @@ public readonly addLatencyP50Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyP70Alarm`Optional + +```typescript +public readonly addLatencyP70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP90Alarm`Optional ```typescript @@ -4912,6 +5613,26 @@ public readonly addLatencyP90Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyP9999Alarm`Optional + +```typescript +public readonly addLatencyP9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyP999Alarm`Optional + +```typescript +public readonly addLatencyP999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLatencyP99Alarm`Optional ```typescript @@ -4922,6 +5643,66 @@ public readonly addLatencyP99Alarm: {[ key: string ]: LatencyThreshold}; --- +##### `addLatencyTM50Alarm`Optional + +```typescript +public readonly addLatencyTM50Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM70Alarm`Optional + +```typescript +public readonly addLatencyTM70Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM90Alarm`Optional + +```typescript +public readonly addLatencyTM90Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM9999Alarm`Optional + +```typescript +public readonly addLatencyTM9999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM999Alarm`Optional + +```typescript +public readonly addLatencyTM999Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + +##### `addLatencyTM99Alarm`Optional + +```typescript +public readonly addLatencyTM99Alarm: {[ key: string ]: LatencyThreshold}; +``` + +- *Type:* {[ key: string ]: LatencyThreshold} + +--- + ##### `addLowTpsAlarm`Optional ```typescript @@ -4932,6 +5713,23 @@ public readonly addLowTpsAlarm: {[ key: string ]: LowTpsThreshold}; --- +##### `latencyTypesToRender`Optional + +```typescript +public readonly latencyTypesToRender: LatencyType[]; +``` + +- *Type:* LatencyType[] +- *Default:* p50, p90, p99 ( + +You can specify what latency types you want to be rendered in the dashboards. + +Note: any latency type with an alarm will be also added automatically. If the list is undefined, default values will be shown. If the list is empty, only the latency types with an alarm will be shown (if any). + +> [DefaultLatencyTypesShown)](DefaultLatencyTypesShown)) + +--- + ### ApplicationLoadBalancerMetricFactoryProps Props to create ApplicationLoadBalancerMetricFactory. @@ -33578,6 +34376,7 @@ new ApiGatewayMetricFactory(metricFactory: MetricFactory, props: ApiGatewayMetri | metric5XXFaultCount | *No description.* | | metric5XXFaultRate | *No description.* | | metricInvocationCount | *No description.* | +| metricLatencyInMillis | *No description.* | | metricLatencyP50InMillis | *No description.* | | metricLatencyP90InMillis | *No description.* | | metricLatencyP99InMillis | *No description.* | @@ -33615,19 +34414,31 @@ public metric5XXFaultRate(): Metric | MathExpression public metricInvocationCount(): Metric | MathExpression ``` -##### `metricLatencyP50InMillis` +##### `metricLatencyInMillis` + +```typescript +public metricLatencyInMillis(latencyType: LatencyType): Metric | MathExpression +``` + +###### `latencyType`Required + +- *Type:* LatencyType + +--- + +##### ~~`metricLatencyP50InMillis`~~ ```typescript public metricLatencyP50InMillis(): Metric | MathExpression ``` -##### `metricLatencyP90InMillis` +##### ~~`metricLatencyP90InMillis`~~ ```typescript public metricLatencyP90InMillis(): Metric | MathExpression ``` -##### `metricLatencyP99InMillis` +##### ~~`metricLatencyP99InMillis`~~ ```typescript public metricLatencyP99InMillis(): Metric | MathExpression @@ -33810,10 +34621,12 @@ new ApiGatewayV2HttpApiMetricFactory(metricFactory: MetricFactory, props: ApiGat | metric4xxRate | *No description.* | | metric5xxCount | *No description.* | | metric5xxRate | *No description.* | +| metricIntegrationLatencyInMillis | *No description.* | | metricIntegrationLatencyP50InMillis | *No description.* | | metricIntegrationLatencyP90InMillis | *No description.* | | metricIntegrationLatencyP99InMillis | *No description.* | | metricInvocationCount | *No description.* | +| metricLatencyInMillis | *No description.* | | metricLatencyP50InMillis | *No description.* | | metricLatencyP90InMillis | *No description.* | | metricLatencyP99InMillis | *No description.* | @@ -33845,19 +34658,31 @@ public metric5xxCount(): Metric | MathExpression public metric5xxRate(): Metric | MathExpression ``` -##### `metricIntegrationLatencyP50InMillis` +##### `metricIntegrationLatencyInMillis` + +```typescript +public metricIntegrationLatencyInMillis(latencyType: LatencyType): Metric | MathExpression +``` + +###### `latencyType`Required + +- *Type:* LatencyType + +--- + +##### ~~`metricIntegrationLatencyP50InMillis`~~ ```typescript public metricIntegrationLatencyP50InMillis(): Metric | MathExpression ``` -##### `metricIntegrationLatencyP90InMillis` +##### ~~`metricIntegrationLatencyP90InMillis`~~ ```typescript public metricIntegrationLatencyP90InMillis(): Metric | MathExpression ``` -##### `metricIntegrationLatencyP99InMillis` +##### ~~`metricIntegrationLatencyP99InMillis`~~ ```typescript public metricIntegrationLatencyP99InMillis(): Metric | MathExpression @@ -33869,19 +34694,31 @@ public metricIntegrationLatencyP99InMillis(): Metric | MathExpression public metricInvocationCount(): Metric | MathExpression ``` -##### `metricLatencyP50InMillis` +##### `metricLatencyInMillis` + +```typescript +public metricLatencyInMillis(latencyType: LatencyType): Metric | MathExpression +``` + +###### `latencyType`Required + +- *Type:* LatencyType + +--- + +##### ~~`metricLatencyP50InMillis`~~ ```typescript public metricLatencyP50InMillis(): Metric | MathExpression ``` -##### `metricLatencyP90InMillis` +##### ~~`metricLatencyP90InMillis`~~ ```typescript public metricLatencyP90InMillis(): Metric | MathExpression ``` -##### `metricLatencyP99InMillis` +##### ~~`metricLatencyP99InMillis`~~ ```typescript public metricLatencyP99InMillis(): Metric | MathExpression @@ -39597,6 +40434,7 @@ new LatencyAlarmFactory(alarmFactory: AlarmFactory) | **Name** | **Description** | | --- | --- | | addDurationAlarm | *No description.* | +| addIntegrationLatencyAlarm | *No description.* | | addJvmGarbageCollectionDurationAlarm | *No description.* | | addLatencyAlarm | *No description.* | @@ -39632,6 +40470,36 @@ public addDurationAlarm(metric: Metric | MathExpression, latencyType: LatencyTyp --- +##### `addIntegrationLatencyAlarm` + +```typescript +public addIntegrationLatencyAlarm(metric: Metric | MathExpression, latencyType: LatencyType, props: LatencyThreshold, disambiguator?: string): AlarmWithAnnotation +``` + +###### `metric`Required + +- *Type:* monocdk.aws_cloudwatch.Metric | monocdk.aws_cloudwatch.MathExpression + +--- + +###### `latencyType`Required + +- *Type:* LatencyType + +--- + +###### `props`Required + +- *Type:* LatencyThreshold + +--- + +###### `disambiguator`Optional + +- *Type:* string + +--- + ##### `addJvmGarbageCollectionDurationAlarm` ```typescript diff --git a/lib/common/monitoring/alarms/LatencyAlarmFactory.ts b/lib/common/monitoring/alarms/LatencyAlarmFactory.ts index 835357be..88a97fde 100644 --- a/lib/common/monitoring/alarms/LatencyAlarmFactory.ts +++ b/lib/common/monitoring/alarms/LatencyAlarmFactory.ts @@ -148,6 +148,33 @@ export class LatencyAlarmFactory { }); } + addIntegrationLatencyAlarm( + metric: MetricWithAlarmSupport, + latencyType: LatencyType, + props: LatencyThreshold, + disambiguator?: string + ) { + const alarmNameSuffix = `IntegrationLatency-${latencyType}`; + + return this.alarmFactory.addAlarm(metric, { + treatMissingData: + props.treatMissingDataOverride ?? TreatMissingData.NOT_BREACHING, + comparisonOperator: + props.comparisonOperatorOverride ?? + ComparisonOperator.GREATER_THAN_THRESHOLD, + ...props, + disambiguator, + threshold: props.maxLatency.toMilliseconds(), + alarmNameSuffix, + // we will dedupe any kind of latency issue to the same alarm + alarmDedupeStringSuffix: this.alarmFactory + .shouldUseDefaultDedupeForLatency + ? "AnyLatency" + : alarmNameSuffix, + alarmDescription: `${latencyType} integration latency is too high.`, + }); + } + addDurationAlarm( metric: MetricWithAlarmSupport, latencyType: LatencyType, diff --git a/lib/monitoring/aws-apigateway/ApiGatewayMetricFactory.ts b/lib/monitoring/aws-apigateway/ApiGatewayMetricFactory.ts index 48eebeb6..3c3a48fd 100644 --- a/lib/monitoring/aws-apigateway/ApiGatewayMetricFactory.ts +++ b/lib/monitoring/aws-apigateway/ApiGatewayMetricFactory.ts @@ -2,6 +2,9 @@ import { RestApiBase } from "monocdk/aws-apigateway"; import { DimensionHash } from "monocdk/aws-cloudwatch"; import { + getLatencyTypeLabel, + getLatencyTypeStatistic, + LatencyType, MetricFactory, MetricStatistic, RateComputationMethod, @@ -122,33 +125,33 @@ export class ApiGatewayMetricFactory { ); } + /** + * @deprecated use metricLatencyInMillis instead + */ metricLatencyP99InMillis() { - return this.metricFactory.createMetric( - "Latency", - MetricStatistic.P99, - "P99", - this.dimensions, - undefined, - ApiGatewayNamespace - ); + return this.metricLatencyInMillis(LatencyType.P99); } + /** + * @deprecated use metricLatencyInMillis instead + */ metricLatencyP90InMillis() { - return this.metricFactory.createMetric( - "Latency", - MetricStatistic.P90, - "P90", - this.dimensions, - undefined, - ApiGatewayNamespace - ); + return this.metricLatencyInMillis(LatencyType.P90); } + /** + * @deprecated use metricLatencyInMillis instead + */ metricLatencyP50InMillis() { + return this.metricLatencyInMillis(LatencyType.P50); + } + + metricLatencyInMillis(latencyType: LatencyType) { + const label = getLatencyTypeLabel(latencyType); return this.metricFactory.createMetric( "Latency", - MetricStatistic.P50, - "P50", + getLatencyTypeStatistic(latencyType), + label, this.dimensions, undefined, ApiGatewayNamespace diff --git a/lib/monitoring/aws-apigateway/ApiGatewayMonitoring.ts b/lib/monitoring/aws-apigateway/ApiGatewayMonitoring.ts index ae32514f..61b2f7a5 100644 --- a/lib/monitoring/aws-apigateway/ApiGatewayMonitoring.ts +++ b/lib/monitoring/aws-apigateway/ApiGatewayMonitoring.ts @@ -37,16 +37,42 @@ import { ApiGatewayMetricFactoryProps, } from "./ApiGatewayMetricFactory"; +const DefaultLatencyTypesToRender = [ + LatencyType.P50, + LatencyType.P90, + LatencyType.P99, +]; + export interface ApiGatewayMonitoringOptions extends BaseMonitoringProps { readonly addLatencyP50Alarm?: Record; + readonly addLatencyP70Alarm?: Record; readonly addLatencyP90Alarm?: Record; readonly addLatencyP99Alarm?: Record; + readonly addLatencyP999Alarm?: Record; + readonly addLatencyP9999Alarm?: Record; + readonly addLatencyP100Alarm?: Record; + readonly addLatencyTM50Alarm?: Record; + readonly addLatencyTM70Alarm?: Record; + readonly addLatencyTM90Alarm?: Record; + readonly addLatencyTM99Alarm?: Record; + readonly addLatencyTM999Alarm?: Record; + readonly addLatencyTM9999Alarm?: Record; + readonly addLatencyAverageAlarm?: Record; readonly add4XXErrorCountAlarm?: Record; readonly add4XXErrorRateAlarm?: Record; readonly add5XXFaultCountAlarm?: Record; readonly add5XXFaultRateAlarm?: Record; readonly addLowTpsAlarm?: Record; readonly addHighTpsAlarm?: Record; + + /** + * You can specify what latency types you want to be rendered in the dashboards. + * Note: any latency type with an alarm will be also added automatically. + * If the list is undefined, default values will be shown. + * If the list is empty, only the latency types with an alarm will be shown (if any). + * @default p50, p90, p99 (@see DefaultLatencyTypesToRender) + */ + readonly latencyTypesToRender?: LatencyType[]; } export interface ApiGatewayMonitoringProps @@ -67,14 +93,15 @@ export class ApiGatewayMonitoring extends Monitoring { protected readonly errorRateAnnotations: HorizontalAnnotation[]; protected readonly tpsMetric: MetricWithAlarmSupport; - protected readonly p50LatencyMetric: MetricWithAlarmSupport; - protected readonly p90LatencyMetric: MetricWithAlarmSupport; - protected readonly p99LatencyMetric: MetricWithAlarmSupport; protected readonly error4XXCountMetric: MetricWithAlarmSupport; protected readonly error4XXRateMetric: MetricWithAlarmSupport; protected readonly fault5XXCountMetric: MetricWithAlarmSupport; protected readonly fault5XXRateMetric: MetricWithAlarmSupport; + // keys are LatencyType, but JSII doesn't like non-string types + protected readonly latencyMetrics: Record; + protected readonly latencyTypesToRender: string[]; + constructor(scope: MonitoringScope, props: ApiGatewayMonitoringProps) { super(scope, props); @@ -115,48 +142,60 @@ export class ApiGatewayMonitoring extends Monitoring { scope.createMetricFactory(), props ); + this.tpsMetric = metricFactory.metricTps(); - this.p50LatencyMetric = metricFactory.metricLatencyP50InMillis(); - this.p90LatencyMetric = metricFactory.metricLatencyP90InMillis(); - this.p99LatencyMetric = metricFactory.metricLatencyP99InMillis(); + + this.latencyMetrics = {}; + this.latencyTypesToRender = [ + ...(props.latencyTypesToRender ?? DefaultLatencyTypesToRender), + ]; + this.error4XXCountMetric = metricFactory.metric4XXErrorCount(); this.error4XXRateMetric = metricFactory.metric4XXErrorRate(); this.fault5XXCountMetric = metricFactory.metric5XXFaultCount(); this.fault5XXRateMetric = metricFactory.metric5XXFaultRate(); - for (const disambiguator in props.addLatencyP50Alarm) { - const alarmProps = props.addLatencyP50Alarm[disambiguator]; - const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( - this.p50LatencyMetric, - LatencyType.P50, - alarmProps, - disambiguator - ); - this.latencyAnnotations.push(createdAlarm.annotation); - this.addAlarm(createdAlarm); - } - for (const disambiguator in props.addLatencyP90Alarm) { - const alarmProps = props.addLatencyP90Alarm[disambiguator]; - const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( - this.p90LatencyMetric, - LatencyType.P90, - alarmProps, - disambiguator - ); - this.latencyAnnotations.push(createdAlarm.annotation); - this.addAlarm(createdAlarm); - } - for (const disambiguator in props.addLatencyP99Alarm) { - const alarmProps = props.addLatencyP99Alarm[disambiguator]; - const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( - this.p99LatencyMetric, - LatencyType.P99, - alarmProps, - disambiguator - ); - this.latencyAnnotations.push(createdAlarm.annotation); - this.addAlarm(createdAlarm); + const latencyAlarmDefinitions = { + [LatencyType.P50]: props.addLatencyP50Alarm, + [LatencyType.P70]: props.addLatencyP70Alarm, + [LatencyType.P90]: props.addLatencyP90Alarm, + [LatencyType.P99]: props.addLatencyP99Alarm, + [LatencyType.P999]: props.addLatencyP999Alarm, + [LatencyType.P9999]: props.addLatencyP9999Alarm, + [LatencyType.P100]: props.addLatencyP100Alarm, + [LatencyType.TM50]: props.addLatencyTM50Alarm, + [LatencyType.TM70]: props.addLatencyTM70Alarm, + [LatencyType.TM90]: props.addLatencyTM90Alarm, + [LatencyType.TM99]: props.addLatencyTM99Alarm, + [LatencyType.TM999]: props.addLatencyTM999Alarm, + [LatencyType.TM9999]: props.addLatencyTM9999Alarm, + [LatencyType.AVERAGE]: props.addLatencyAverageAlarm, + }; + + Object.values(LatencyType).forEach((latencyType) => { + this.latencyMetrics[latencyType] = + metricFactory.metricLatencyInMillis(latencyType); + }); + + for (const [latencyType, alarmDefinition] of Object.entries( + latencyAlarmDefinitions + )) { + for (const disambiguator in alarmDefinition) { + const alarmProps = alarmDefinition[disambiguator]; + const latencyTypeEnum = latencyType as LatencyType; + const metric = this.latencyMetrics[latencyTypeEnum]; + const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( + metric, + latencyTypeEnum, + alarmProps, + disambiguator + ); + this.latencyAnnotations.push(createdAlarm.annotation); + this.latencyTypesToRender.push(latencyTypeEnum); + this.addAlarm(createdAlarm); + } } + for (const disambiguator in props.add5XXFaultCountAlarm) { const alarmProps = props.add5XXFaultCountAlarm[disambiguator]; const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm( @@ -262,15 +301,15 @@ export class ApiGatewayMonitoring extends Monitoring { } protected createLatencyWidget(width: number, height: number) { + const left = Array.from(new Set(this.latencyTypesToRender)) + .sort() + .map((type) => this.latencyMetrics[type]); + return new GraphWidget({ width, height, title: "Latency", - left: [ - this.p50LatencyMetric, - this.p90LatencyMetric, - this.p99LatencyMetric, - ], + left, leftYAxis: TimeAxisMillisFromZero, leftAnnotations: this.latencyAnnotations, }); diff --git a/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMetricFactory.ts b/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMetricFactory.ts index 41f1aa68..5f5349a4 100644 --- a/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMetricFactory.ts +++ b/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMetricFactory.ts @@ -2,6 +2,9 @@ import { IHttpApi } from "monocdk/aws-apigatewayv2"; import { DimensionHash } from "monocdk/aws-cloudwatch"; import { + getLatencyTypeLabel, + getLatencyTypeStatistic, + LatencyType, MetricFactory, MetricStatistic, RateComputationMethod, @@ -118,66 +121,66 @@ export class ApiGatewayV2HttpApiMetricFactory { ); } + /** + * @deprecated use metricLatencyInMillis instead + */ metricLatencyP50InMillis() { - return this.metricFactory.createMetric( - "Latency", - MetricStatistic.P50, - "P50 Latency", - this.dimensions, - undefined, - ApiGatewayNamespace - ); + return this.metricLatencyInMillis(LatencyType.P50); } + /** + * @deprecated use metricLatencyInMillis instead + */ metricLatencyP90InMillis() { - return this.metricFactory.createMetric( - "Latency", - MetricStatistic.P90, - "P90 Latency", - this.dimensions, - undefined, - ApiGatewayNamespace - ); + return this.metricLatencyInMillis(LatencyType.P90); } + /** + * @deprecated use metricLatencyInMillis instead + */ metricLatencyP99InMillis() { - return this.metricFactory.createMetric( - "Latency", - MetricStatistic.P99, - "P99 Latency", - this.dimensions, - undefined, - ApiGatewayNamespace - ); + return this.metricLatencyInMillis(LatencyType.P99); } + /** + * @deprecated use metricIntegrationLatencyInMillis instead + */ metricIntegrationLatencyP50InMillis() { - return this.metricFactory.createMetric( - "IntegrationLatency", - MetricStatistic.P50, - "P50 Integration Latency", - this.dimensions, - undefined, - ApiGatewayNamespace - ); + return this.metricIntegrationLatencyInMillis(LatencyType.P50); } + /** + * @deprecated use metricIntegrationLatencyInMillis instead + */ metricIntegrationLatencyP90InMillis() { + return this.metricIntegrationLatencyInMillis(LatencyType.P90); + } + + /** + * @deprecated use metricIntegrationLatencyInMillis instead + */ + metricIntegrationLatencyP99InMillis() { + return this.metricIntegrationLatencyInMillis(LatencyType.P99); + } + + metricIntegrationLatencyInMillis(latencyType: LatencyType) { + const label = getLatencyTypeLabel(latencyType); return this.metricFactory.createMetric( "IntegrationLatency", - MetricStatistic.P90, - "P90 Integration Latency", + getLatencyTypeStatistic(latencyType), + label, this.dimensions, undefined, ApiGatewayNamespace ); } - metricIntegrationLatencyP99InMillis() { + metricLatencyInMillis(latencyType: LatencyType) { + const label = getLatencyTypeLabel(latencyType); return this.metricFactory.createMetric( - "IntegrationLatency", - MetricStatistic.P99, - "P99 Integration Latency", + "Latency", + getLatencyTypeStatistic(latencyType), + label, this.dimensions, undefined, ApiGatewayNamespace diff --git a/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.ts b/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.ts index 1fe44571..a3cc68d8 100644 --- a/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.ts +++ b/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.ts @@ -1,6 +1,7 @@ import { GraphWidget, HorizontalAnnotation, + IMetric, IWidget, } from "monocdk/aws-cloudwatch"; @@ -37,6 +38,12 @@ import { ApiGatewayV2HttpApiMetricFactoryProps, } from "./ApiGatewayV2HttpApiMetricFactory"; +const DefaultLatencyTypesToRender = [ + LatencyType.P50, + LatencyType.P90, + LatencyType.P99, +]; + export interface ApiGatewayV2MonitoringOptions extends BaseMonitoringProps { readonly add4xxCountAlarm?: Record; readonly add4xxRateAlarm?: Record; @@ -45,15 +52,46 @@ export interface ApiGatewayV2MonitoringOptions extends BaseMonitoringProps { readonly add5xxRateAlarm?: Record; readonly addLatencyP50Alarm?: Record; + readonly addLatencyP70Alarm?: Record; readonly addLatencyP90Alarm?: Record; readonly addLatencyP99Alarm?: Record; + readonly addLatencyP999Alarm?: Record; + readonly addLatencyP9999Alarm?: Record; + readonly addLatencyP100Alarm?: Record; + readonly addLatencyTM50Alarm?: Record; + readonly addLatencyTM70Alarm?: Record; + readonly addLatencyTM90Alarm?: Record; + readonly addLatencyTM99Alarm?: Record; + readonly addLatencyTM999Alarm?: Record; + readonly addLatencyTM9999Alarm?: Record; + readonly addLatencyAverageAlarm?: Record; readonly addIntegrationLatencyP50Alarm?: Record; + readonly addIntegrationLatencyP70Alarm?: Record; readonly addIntegrationLatencyP90Alarm?: Record; readonly addIntegrationLatencyP99Alarm?: Record; + readonly addIntegrationLatencyP999Alarm?: Record; + readonly addIntegrationLatencyP9999Alarm?: Record; + readonly addIntegrationLatencyP100Alarm?: Record; + readonly addIntegrationLatencyTM50Alarm?: Record; + readonly addIntegrationLatencyTM70Alarm?: Record; + readonly addIntegrationLatencyTM90Alarm?: Record; + readonly addIntegrationLatencyTM99Alarm?: Record; + readonly addIntegrationLatencyTM999Alarm?: Record; + readonly addIntegrationLatencyTM9999Alarm?: Record; + readonly addIntegrationLatencyAverageAlarm?: Record; readonly addLowTpsAlarm?: Record; readonly addHighTpsAlarm?: Record; + + /** + * You can specify what latency types you want to be rendered in the dashboards. + * Note: any latency type with an alarm will be also added automatically. + * If the list is undefined, default values will be shown. + * If the list is empty, only the latency types with an alarm will be shown (if any). + * @default p50, p90, p99 (@see DefaultLatencyTypesShown) + */ + readonly latencyTypesToRender?: LatencyType[]; } export interface ApiGatewayV2HttpApiMonitoringProps @@ -81,13 +119,13 @@ export class ApiGatewayV2HttpApiMonitoring extends Monitoring { protected readonly error5xxCountMetric: MetricWithAlarmSupport; protected readonly error5xxRateMetric: MetricWithAlarmSupport; - protected readonly p50LatencyMetric: MetricWithAlarmSupport; - protected readonly p90LatencyMetric: MetricWithAlarmSupport; - protected readonly p99LatencyMetric: MetricWithAlarmSupport; - - protected readonly p50IntegrationLatencyMetric: MetricWithAlarmSupport; - protected readonly p90IntegrationLatencyMetric: MetricWithAlarmSupport; - protected readonly p99IntegrationLatencyMetric: MetricWithAlarmSupport; + // keys are LatencyType, but JSII doesn't like non-string types + protected readonly latencyMetrics: Record; + protected readonly integrationLatencyMetrics: Record< + string, + MetricWithAlarmSupport + >; + protected readonly latencyTypesToRender: string[]; constructor( scope: MonitoringScope, @@ -98,10 +136,10 @@ export class ApiGatewayV2HttpApiMonitoring extends Monitoring { const namingStrategy = new MonitoringNamingStrategy({ ...props, namedConstruct: props.api, - fallbackConstructName: props.api.httpApiId, - humanReadableName: `${props.api.httpApiId} ${ - props.apiStage ?? "$default" - } ${props.apiMethod ?? ""} ${props.apiResource ?? ""}`, + fallbackConstructName: props.api.apiId, + humanReadableName: `${props.api.apiId} ${props.apiStage ?? "$default"} ${ + props.apiMethod ?? "" + } ${props.apiResource ?? ""}`, }); this.title = namingStrategy.resolveHumanReadableName(); @@ -126,93 +164,96 @@ export class ApiGatewayV2HttpApiMonitoring extends Monitoring { this.tpsMetric = metricFactory.metricTps(); + this.latencyMetrics = {}; + this.integrationLatencyMetrics = {}; + this.latencyTypesToRender = [ + ...(props.latencyTypesToRender ?? DefaultLatencyTypesToRender), + ]; + this.error4xxCountMetric = metricFactory.metric4xxCount(); this.error4xxRateMetric = metricFactory.metric4xxRate(); this.error5xxCountMetric = metricFactory.metric5xxCount(); this.error5xxRateMetric = metricFactory.metric5xxRate(); - this.p50LatencyMetric = metricFactory.metricLatencyP50InMillis(); - this.p90LatencyMetric = metricFactory.metricLatencyP90InMillis(); - this.p99LatencyMetric = metricFactory.metricLatencyP99InMillis(); - - this.p50IntegrationLatencyMetric = - metricFactory.metricIntegrationLatencyP50InMillis(); - this.p90IntegrationLatencyMetric = - metricFactory.metricIntegrationLatencyP90InMillis(); - this.p99IntegrationLatencyMetric = - metricFactory.metricIntegrationLatencyP99InMillis(); - - for (const disambiguator in props.addLatencyP50Alarm) { - const alarmProps = props.addLatencyP50Alarm[disambiguator]; - const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( - this.p50LatencyMetric, - LatencyType.P50, - alarmProps, - disambiguator - ); - this.latencyAnnotations.push(createdAlarm.annotation); - this.addAlarm(createdAlarm); - } - - for (const disambiguator in props.addLatencyP90Alarm) { - const alarmProps = props.addLatencyP90Alarm[disambiguator]; - const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( - this.p90LatencyMetric, - LatencyType.P90, - alarmProps, - disambiguator - ); - this.latencyAnnotations.push(createdAlarm.annotation); - this.addAlarm(createdAlarm); - } - - for (const disambiguator in props.addLatencyP99Alarm) { - const alarmProps = props.addLatencyP99Alarm[disambiguator]; - const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( - this.p99LatencyMetric, - LatencyType.P99, - alarmProps, - disambiguator - ); - this.latencyAnnotations.push(createdAlarm.annotation); - this.addAlarm(createdAlarm); - } + const latencyAlarmDefinitions = { + [LatencyType.P50]: props.addLatencyP50Alarm, + [LatencyType.P70]: props.addLatencyP70Alarm, + [LatencyType.P90]: props.addLatencyP90Alarm, + [LatencyType.P99]: props.addLatencyP99Alarm, + [LatencyType.P999]: props.addLatencyP999Alarm, + [LatencyType.P9999]: props.addLatencyP9999Alarm, + [LatencyType.P100]: props.addLatencyP100Alarm, + [LatencyType.TM50]: props.addLatencyTM50Alarm, + [LatencyType.TM70]: props.addLatencyTM70Alarm, + [LatencyType.TM90]: props.addLatencyTM90Alarm, + [LatencyType.TM99]: props.addLatencyTM99Alarm, + [LatencyType.TM999]: props.addLatencyTM999Alarm, + [LatencyType.TM9999]: props.addLatencyTM9999Alarm, + [LatencyType.AVERAGE]: props.addLatencyAverageAlarm, + }; + + const integrationLatencyAlarmDefinitions = { + [LatencyType.P50]: props.addIntegrationLatencyP50Alarm, + [LatencyType.P70]: props.addIntegrationLatencyP70Alarm, + [LatencyType.P90]: props.addIntegrationLatencyP90Alarm, + [LatencyType.P99]: props.addIntegrationLatencyP99Alarm, + [LatencyType.P999]: props.addIntegrationLatencyP999Alarm, + [LatencyType.P9999]: props.addIntegrationLatencyP9999Alarm, + [LatencyType.P100]: props.addIntegrationLatencyP100Alarm, + [LatencyType.TM50]: props.addIntegrationLatencyTM50Alarm, + [LatencyType.TM70]: props.addIntegrationLatencyTM70Alarm, + [LatencyType.TM90]: props.addIntegrationLatencyTM90Alarm, + [LatencyType.TM99]: props.addIntegrationLatencyTM99Alarm, + [LatencyType.TM999]: props.addIntegrationLatencyTM999Alarm, + [LatencyType.TM9999]: props.addIntegrationLatencyTM9999Alarm, + [LatencyType.AVERAGE]: props.addIntegrationLatencyAverageAlarm, + }; + + Object.values(LatencyType).forEach((latencyType) => { + this.latencyMetrics[latencyType] = + metricFactory.metricLatencyInMillis(latencyType); + this.integrationLatencyMetrics[latencyType] = + metricFactory.metricIntegrationLatencyInMillis(latencyType); + }); - for (const disambiguator in props.addIntegrationLatencyP50Alarm) { - const alarmProps = props.addIntegrationLatencyP50Alarm[disambiguator]; - const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( - this.p50IntegrationLatencyMetric, - LatencyType.P50, - alarmProps, - disambiguator - ); - this.latencyAnnotations.push(createdAlarm.annotation); - this.addAlarm(createdAlarm); + for (const [latencyType, alarmDefinition] of Object.entries( + latencyAlarmDefinitions + )) { + for (const disambiguator in alarmDefinition) { + const alarmProps = alarmDefinition[disambiguator]; + const latencyTypeEnum = latencyType as LatencyType; + const metric = this.latencyMetrics[latencyTypeEnum]; + const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( + metric, + latencyTypeEnum, + alarmProps, + disambiguator + ); + this.latencyAnnotations.push(createdAlarm.annotation); + this.latencyTypesToRender.push(latencyTypeEnum); + this.addAlarm(createdAlarm); + } } - for (const disambiguator in props.addIntegrationLatencyP90Alarm) { - const alarmProps = props.addIntegrationLatencyP90Alarm[disambiguator]; - const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( - this.p90IntegrationLatencyMetric, - LatencyType.P90, - alarmProps, - disambiguator - ); - this.latencyAnnotations.push(createdAlarm.annotation); - this.addAlarm(createdAlarm); - } - - for (const disambiguator in props.addIntegrationLatencyP99Alarm) { - const alarmProps = props.addIntegrationLatencyP99Alarm[disambiguator]; - const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm( - this.p99IntegrationLatencyMetric, - LatencyType.P99, - alarmProps, - disambiguator - ); - this.latencyAnnotations.push(createdAlarm.annotation); - this.addAlarm(createdAlarm); + for (const [latencyType, alarmDefinition] of Object.entries( + integrationLatencyAlarmDefinitions + )) { + for (const disambiguator in alarmDefinition) { + const alarmProps = alarmDefinition[disambiguator]; + const latencyTypeEnum = latencyType as LatencyType; + const metric = this.integrationLatencyMetrics[latencyTypeEnum]; + const createdAlarm = + this.latencyAlarmFactory.addIntegrationLatencyAlarm( + metric, + latencyTypeEnum, + alarmProps, + disambiguator + ); + this.latencyAnnotations.push(createdAlarm.annotation); + this.latencyTypesToRender.push(latencyTypeEnum); + this.addAlarm(createdAlarm); + } } for (const disambiguator in props.add4xxCountAlarm) { @@ -326,18 +367,20 @@ export class ApiGatewayV2HttpApiMonitoring extends Monitoring { } protected createLatencyWidget(width: number, height: number) { + const left: IMetric[] = []; + + Array.from(new Set(this.latencyTypesToRender)) + .sort() + .forEach((type) => { + left.push(this.latencyMetrics[type]); + left.push(this.integrationLatencyMetrics[type]); + }); + return new GraphWidget({ width, height, title: "Latency", - left: [ - this.p50LatencyMetric, - this.p50IntegrationLatencyMetric, - this.p90LatencyMetric, - this.p90IntegrationLatencyMetric, - this.p99LatencyMetric, - this.p99IntegrationLatencyMetric, - ], + left, leftYAxis: TimeAxisMillisFromZero, leftAnnotations: this.latencyAnnotations, }); diff --git a/test/facade/__snapshots__/MonitoringAspect.test.ts.snap b/test/facade/__snapshots__/MonitoringAspect.test.ts.snap index dd3a0fba..bc9c78c2 100644 --- a/test/facade/__snapshots__/MonitoringAspect.test.ts.snap +++ b/test/facade/__snapshots__/MonitoringAspect.test.ts.snap @@ -108,7 +108,7 @@ Object { Object { "Ref": "AWS::Region", }, - "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P50\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P90\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P99\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors\\",\\"region\\":\\"", + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors\\",\\"region\\":\\"", Object { "Ref": "AWS::Region", }, @@ -138,7 +138,7 @@ Object { Object { "Ref": "AWS::Region", }, - "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P50\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P90\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P99\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"", + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiName\\",\\"DummyRestApi\\",\\"Stage\\",\\"prod\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"", Object { "Ref": "AWS::Region", }, @@ -284,27 +284,27 @@ Object { Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 Latency\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 Integration Latency\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 Latency\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 Integration Latency\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 Latency\\",\\"stat\\":\\"p99\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 Integration Latency\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors\\",\\"region\\":\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors\\",\\"region\\":\\"", Object { "Ref": "AWS::Region", }, @@ -362,27 +362,27 @@ Object { Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 Latency\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 Integration Latency\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 Latency\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 Integration Latency\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 Latency\\",\\"stat\\":\\"p99\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", Object { "Ref": "DummyHttpApi8EEBCC85", }, - "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 Integration Latency\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"", + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"", Object { "Ref": "AWS::Region", }, diff --git a/test/monitoring/aws-apigateway/ApiGatewayMonitoring.test.ts b/test/monitoring/aws-apigateway/ApiGatewayMonitoring.test.ts index 16736178..cd4d3af9 100644 --- a/test/monitoring/aws-apigateway/ApiGatewayMonitoring.test.ts +++ b/test/monitoring/aws-apigateway/ApiGatewayMonitoring.test.ts @@ -60,92 +60,86 @@ test("snapshot test: all alarms", () => { }, addLatencyP50Alarm: { Warning: { - maxLatency: Duration.millis(110), - datapointsToAlarm: 11, + maxLatency: Duration.millis(150), + datapointsToAlarm: 150, + }, + }, + addLatencyP70Alarm: { + Warning: { + maxLatency: Duration.millis(170), + datapointsToAlarm: 170, }, }, addLatencyP90Alarm: { Warning: { - maxLatency: Duration.millis(220), - datapointsToAlarm: 22, + maxLatency: Duration.millis(190), + datapointsToAlarm: 190, }, }, addLatencyP99Alarm: { Warning: { - maxLatency: Duration.millis(330), - datapointsToAlarm: 33, + maxLatency: Duration.millis(199), + datapointsToAlarm: 199, }, }, - addLowTpsAlarm: { - Warning: { minTps: 1 }, + addLatencyP999Alarm: { + Warning: { + maxLatency: Duration.millis(1999), + datapointsToAlarm: 1999, + }, }, - addHighTpsAlarm: { - Warning: { maxTps: 10 }, + addLatencyP9999Alarm: { + Warning: { + maxLatency: Duration.millis(19999), + datapointsToAlarm: 19999, + }, }, - useCreatedAlarms: { - consume(alarms: AlarmWithAnnotation[]) { - numAlarmsCreated = alarms.length; + addLatencyP100Alarm: { + Warning: { + maxLatency: Duration.millis(1100), + datapointsToAlarm: 1100, }, }, - }); - - expect(numAlarmsCreated).toStrictEqual(9); - expect(Template.fromStack(stack)).toMatchSnapshot(); -}); - -test("snapshot test: all alarms without alarmFriendlyName", () => { - const stack = new Stack(); - const api = new RestApi(stack, "DummyApi"); - api.root.addMethod("ANY"); - - const scope = new TestMonitoringScope(stack, "Scope"); - - let numAlarmsCreated = 0; - - new ApiGatewayMonitoring(scope, { - api, - apiMethod: "GET", - apiResource: "dummy/resource", - add5XXFaultRateAlarm: { + addLatencyTM50Alarm: { Warning: { - maxErrorRate: 1, - datapointsToAlarm: 10, + maxLatency: Duration.millis(250), + datapointsToAlarm: 250, }, }, - add5XXFaultCountAlarm: { + addLatencyTM70Alarm: { Warning: { - maxErrorCount: 2, - datapointsToAlarm: 20, + maxLatency: Duration.millis(270), + datapointsToAlarm: 270, }, }, - add4XXErrorRateAlarm: { + addLatencyTM90Alarm: { Warning: { - maxErrorRate: 0.01, - datapointsToAlarm: 11, + maxLatency: Duration.millis(290), + datapointsToAlarm: 290, }, }, - add4XXErrorCountAlarm: { + addLatencyTM99Alarm: { Warning: { - maxErrorCount: 0.02, - datapointsToAlarm: 22, + maxLatency: Duration.millis(299), + datapointsToAlarm: 299, }, }, - addLatencyP50Alarm: { + addLatencyTM999Alarm: { Warning: { - maxLatency: Duration.millis(110), - datapointsToAlarm: 11, + maxLatency: Duration.millis(2999), + datapointsToAlarm: 2999, }, }, - addLatencyP90Alarm: { + addLatencyTM9999Alarm: { Warning: { - maxLatency: Duration.millis(220), - datapointsToAlarm: 22, + maxLatency: Duration.millis(29999), + datapointsToAlarm: 29999, }, }, - addLatencyP99Alarm: { + addLatencyAverageAlarm: { Warning: { - maxLatency: Duration.millis(330), - datapointsToAlarm: 33, + maxLatency: Duration.millis(20), + datapointsToAlarm: 20, }, }, addLowTpsAlarm: { @@ -161,6 +155,6 @@ test("snapshot test: all alarms without alarmFriendlyName", () => { }, }); - expect(numAlarmsCreated).toStrictEqual(9); + expect(numAlarmsCreated).toStrictEqual(20); expect(Template.fromStack(stack)).toMatchSnapshot(); }); diff --git a/test/monitoring/aws-apigateway/__snapshots__/ApiGatewayMonitoring.test.ts.snap b/test/monitoring/aws-apigateway/__snapshots__/ApiGatewayMonitoring.test.ts.snap index 21f26e1a..cea491d3 100644 --- a/test/monitoring/aws-apigateway/__snapshots__/ApiGatewayMonitoring.test.ts.snap +++ b/test/monitoring/aws-apigateway/__snapshots__/ApiGatewayMonitoring.test.ts.snap @@ -277,18 +277,18 @@ Object { }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiLatencyP50Warning7EEB3E57": Object { + "ScopeTestDummyApiLatencyAverageWarning27D59767": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "P50 latency is too high.", - "AlarmName": "Test-DummyApi-Latency-P50-Warning", + "AlarmDescription": "Average latency is too high.", + "AlarmName": "Test-DummyApi-Latency-Average-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 11, - "EvaluationPeriods": 11, + "DatapointsToAlarm": 20, + "EvaluationPeriods": 20, "Metrics": Array [ Object { "Id": "m1", - "Label": "P50", + "Label": "Average", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -305,28 +305,28 @@ Object { "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "p50", + "Stat": "Average", }, "ReturnData": true, }, ], - "Threshold": 110, + "Threshold": 20, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiLatencyP90Warning48639A66": Object { + "ScopeTestDummyApiLatencyP100WarningB48A5E64": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "P90 latency is too high.", - "AlarmName": "Test-DummyApi-Latency-P90-Warning", + "AlarmDescription": "P100 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P100-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 22, - "EvaluationPeriods": 22, + "DatapointsToAlarm": 1100, + "EvaluationPeriods": 1100, "Metrics": Array [ Object { "Id": "m1", - "Label": "P90", + "Label": "P100", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -343,28 +343,28 @@ Object { "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "p90", + "Stat": "p100", }, "ReturnData": true, }, ], - "Threshold": 220, + "Threshold": 1100, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiLatencyP99Warning254DA12C": Object { + "ScopeTestDummyApiLatencyP50Warning7EEB3E57": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "P99 latency is too high.", - "AlarmName": "Test-DummyApi-Latency-P99-Warning", + "AlarmDescription": "P50 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P50-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 33, - "EvaluationPeriods": 33, + "DatapointsToAlarm": 150, + "EvaluationPeriods": 150, "Metrics": Array [ Object { "Id": "m1", - "Label": "P99", + "Label": "P50", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -381,33 +381,28 @@ Object { "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "p99", + "Stat": "p50", }, "ReturnData": true, }, ], - "Threshold": 330, + "Threshold": 150, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiMaxTPSWarning62732F2B": Object { + "ScopeTestDummyApiLatencyP70Warning56ABF038": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "TPS is too high.", - "AlarmName": "Test-DummyApi-MaxTPS-Warning", + "AlarmDescription": "P70 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P70-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 3, - "EvaluationPeriods": 3, + "DatapointsToAlarm": 170, + "EvaluationPeriods": 170, "Metrics": Array [ Object { - "Expression": "FILL(requests,0) / PERIOD(requests)", - "Id": "expr_1", - "Label": "Count/s", - }, - Object { - "Id": "requests", - "Label": "Count", + "Id": "m1", + "Label": "P70", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -420,37 +415,32 @@ Object { "Value": "prod", }, ], - "MetricName": "Count", + "MetricName": "Latency", "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "Sum", + "Stat": "p70", }, - "ReturnData": false, + "ReturnData": true, }, ], - "Threshold": 10, - "TreatMissingData": "missing", + "Threshold": 170, + "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiMinTPSWarning4E8DB4D0": Object { + "ScopeTestDummyApiLatencyP90Warning48639A66": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "TPS is too low.", - "AlarmName": "Test-DummyApi-MinTPS-Warning", - "ComparisonOperator": "LessThanThreshold", - "DatapointsToAlarm": 3, - "EvaluationPeriods": 3, + "AlarmDescription": "P90 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P90-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 190, + "EvaluationPeriods": 190, "Metrics": Array [ Object { - "Expression": "FILL(requests,0) / PERIOD(requests)", - "Id": "expr_1", - "Label": "Count/s", - }, - Object { - "Id": "requests", - "Label": "Count", + "Id": "m1", + "Label": "P90", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -463,161 +453,70 @@ Object { "Value": "prod", }, ], - "MetricName": "Count", + "MetricName": "Latency", "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "Sum", + "Stat": "p90", }, - "ReturnData": false, + "ReturnData": true, }, ], - "Threshold": 1, - "TreatMissingData": "missing", + "Threshold": 190, + "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - }, -} -`; - -exports[`snapshot test: all alarms without alarmFriendlyName 1`] = ` -Object { - "Outputs": Object { - "DummyApiEndpoint2E6B19BE": Object { - "Value": Object { - "Fn::Join": Array [ - "", - Array [ - "https://", - Object { - "Ref": "DummyApi80F1E171", - }, - ".execute-api.", - Object { - "Ref": "AWS::Region", - }, - ".", - Object { - "Ref": "AWS::URLSuffix", - }, - "/", - Object { - "Ref": "DummyApiDeploymentStageprod9EB3D152", - }, - "/", - ], - ], - }, - }, - }, - "Resources": Object { - "DummyApi80F1E171": Object { + "ScopeTestDummyApiLatencyP9999Warning89E47C72": Object { "Properties": Object { - "Name": "DummyApi", - }, - "Type": "AWS::ApiGateway::RestApi", - }, - "DummyApiANYCEB66499": Object { - "Properties": Object { - "AuthorizationType": "NONE", - "HttpMethod": "ANY", - "Integration": Object { - "Type": "MOCK", - }, - "ResourceId": Object { - "Fn::GetAtt": Array [ - "DummyApi80F1E171", - "RootResourceId", - ], - }, - "RestApiId": Object { - "Ref": "DummyApi80F1E171", - }, - }, - "Type": "AWS::ApiGateway::Method", - }, - "DummyApiAccount7A4341D1": Object { - "DependsOn": Array [ - "DummyApi80F1E171", - ], - "Properties": Object { - "CloudWatchRoleArn": Object { - "Fn::GetAtt": Array [ - "DummyApiCloudWatchRole478A67A7", - "Arn", - ], - }, - }, - "Type": "AWS::ApiGateway::Account", - }, - "DummyApiCloudWatchRole478A67A7": Object { - "Properties": Object { - "AssumeRolePolicyDocument": Object { - "Statement": Array [ - Object { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": Object { - "Service": "apigateway.amazonaws.com", + "ActionsEnabled": true, + "AlarmDescription": "P9999 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P9999-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 19999, + "EvaluationPeriods": 19999, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "P99.99", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiName", + "Value": "DummyApi", + }, + Object { + "Name": "Stage", + "Value": "prod", + }, + ], + "MetricName": "Latency", + "Namespace": "AWS/ApiGateway", }, + "Period": 300, + "Stat": "p99.99", }, - ], - "Version": "2012-10-17", - }, - "ManagedPolicyArns": Array [ - Object { - "Fn::Join": Array [ - "", - Array [ - "arn:", - Object { - "Ref": "AWS::Partition", - }, - ":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs", - ], - ], + "ReturnData": true, }, ], + "Threshold": 19999, + "TreatMissingData": "notBreaching", }, - "Type": "AWS::IAM::Role", - }, - "DummyApiDeploymentD01F5018548e3dba60631e60c80c03977ce1f18a": Object { - "DependsOn": Array [ - "DummyApiANYCEB66499", - ], - "Properties": Object { - "Description": "Automatically created by the RestApi construct", - "RestApiId": Object { - "Ref": "DummyApi80F1E171", - }, - }, - "Type": "AWS::ApiGateway::Deployment", - }, - "DummyApiDeploymentStageprod9EB3D152": Object { - "Properties": Object { - "DeploymentId": Object { - "Ref": "DummyApiDeploymentD01F5018548e3dba60631e60c80c03977ce1f18a", - }, - "RestApiId": Object { - "Ref": "DummyApi80F1E171", - }, - "StageName": "prod", - }, - "Type": "AWS::ApiGateway::Stage", + "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiprodGETdummyresourceErrorCountWarningAF0226A6": Object { + "ScopeTestDummyApiLatencyP999Warning8CF0377D": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "Error count is too high.", - "AlarmName": "Test-DummyApi-prod-GET-dummyresource-Error-Count-Warning", + "AlarmDescription": "P999 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P999-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 22, - "EvaluationPeriods": 22, + "DatapointsToAlarm": 1999, + "EvaluationPeriods": 1999, "Metrics": Array [ Object { "Id": "m1", - "Label": "4XX Error", + "Label": "P99.9", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -625,45 +524,37 @@ Object { "Name": "ApiName", "Value": "DummyApi", }, - Object { - "Name": "Method", - "Value": "GET", - }, - Object { - "Name": "Resource", - "Value": "dummy/resource", - }, Object { "Name": "Stage", "Value": "prod", }, ], - "MetricName": "4XXError", + "MetricName": "Latency", "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "Sum", + "Stat": "p99.9", }, "ReturnData": true, }, ], - "Threshold": 0.02, + "Threshold": 1999, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiprodGETdummyresourceErrorRateWarning016C3EC5": Object { + "ScopeTestDummyApiLatencyP99Warning254DA12C": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "Error rate is too high.", - "AlarmName": "Test-DummyApi-prod-GET-dummyresource-Error-Rate-Warning", + "AlarmDescription": "P99 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P99-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 11, - "EvaluationPeriods": 11, + "DatapointsToAlarm": 199, + "EvaluationPeriods": 199, "Metrics": Array [ Object { "Id": "m1", - "Label": "4XX Error (avg)", + "Label": "P99", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -671,45 +562,37 @@ Object { "Name": "ApiName", "Value": "DummyApi", }, - Object { - "Name": "Method", - "Value": "GET", - }, - Object { - "Name": "Resource", - "Value": "dummy/resource", - }, Object { "Name": "Stage", "Value": "prod", }, ], - "MetricName": "4XXError", + "MetricName": "Latency", "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "Average", + "Stat": "p99", }, "ReturnData": true, }, ], - "Threshold": 0.01, + "Threshold": 199, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiprodGETdummyresourceFaultCountWarning17579B91": Object { + "ScopeTestDummyApiLatencyTM50Warning092E86BF": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "Fault count is too high.", - "AlarmName": "Test-DummyApi-prod-GET-dummyresource-Fault-Count-Warning", + "AlarmDescription": "TM50 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM50-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 20, - "EvaluationPeriods": 20, + "DatapointsToAlarm": 250, + "EvaluationPeriods": 250, "Metrics": Array [ Object { "Id": "m1", - "Label": "5XX Fault", + "Label": "TM50", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -717,45 +600,37 @@ Object { "Name": "ApiName", "Value": "DummyApi", }, - Object { - "Name": "Method", - "Value": "GET", - }, - Object { - "Name": "Resource", - "Value": "dummy/resource", - }, Object { "Name": "Stage", "Value": "prod", }, ], - "MetricName": "5XXError", + "MetricName": "Latency", "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "Sum", + "Stat": "tm50", }, "ReturnData": true, }, ], - "Threshold": 2, + "Threshold": 250, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiprodGETdummyresourceFaultRateWarning1991C1B6": Object { + "ScopeTestDummyApiLatencyTM70Warning8E657453": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "Fault rate is too high.", - "AlarmName": "Test-DummyApi-prod-GET-dummyresource-Fault-Rate-Warning", + "AlarmDescription": "TM70 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM70-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 10, - "EvaluationPeriods": 10, + "DatapointsToAlarm": 270, + "EvaluationPeriods": 270, "Metrics": Array [ Object { "Id": "m1", - "Label": "5XX Fault (avg)", + "Label": "TM70", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -763,45 +638,37 @@ Object { "Name": "ApiName", "Value": "DummyApi", }, - Object { - "Name": "Method", - "Value": "GET", - }, - Object { - "Name": "Resource", - "Value": "dummy/resource", - }, Object { "Name": "Stage", "Value": "prod", }, ], - "MetricName": "5XXError", + "MetricName": "Latency", "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "Average", + "Stat": "tm70", }, "ReturnData": true, }, ], - "Threshold": 1, + "Threshold": 270, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiprodGETdummyresourceLatencyP50Warning988CD8FE": Object { + "ScopeTestDummyApiLatencyTM90Warning0FDD3108": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "P50 latency is too high.", - "AlarmName": "Test-DummyApi-prod-GET-dummyresource-Latency-P50-Warning", + "AlarmDescription": "TM90 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM90-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 11, - "EvaluationPeriods": 11, + "DatapointsToAlarm": 290, + "EvaluationPeriods": 290, "Metrics": Array [ Object { "Id": "m1", - "Label": "P50", + "Label": "TM90", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -809,14 +676,6 @@ Object { "Name": "ApiName", "Value": "DummyApi", }, - Object { - "Name": "Method", - "Value": "GET", - }, - Object { - "Name": "Resource", - "Value": "dummy/resource", - }, Object { "Name": "Stage", "Value": "prod", @@ -826,28 +685,28 @@ Object { "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "p50", + "Stat": "tm90", }, "ReturnData": true, }, ], - "Threshold": 110, + "Threshold": 290, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiprodGETdummyresourceLatencyP90Warning7B53F4CE": Object { + "ScopeTestDummyApiLatencyTM9999Warning4181DE97": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "P90 latency is too high.", - "AlarmName": "Test-DummyApi-prod-GET-dummyresource-Latency-P90-Warning", + "AlarmDescription": "TM9999 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM9999-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 22, - "EvaluationPeriods": 22, + "DatapointsToAlarm": 29999, + "EvaluationPeriods": 29999, "Metrics": Array [ Object { "Id": "m1", - "Label": "P90", + "Label": "TM99.99", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -855,14 +714,6 @@ Object { "Name": "ApiName", "Value": "DummyApi", }, - Object { - "Name": "Method", - "Value": "GET", - }, - Object { - "Name": "Resource", - "Value": "dummy/resource", - }, Object { "Name": "Stage", "Value": "prod", @@ -872,28 +723,28 @@ Object { "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "p90", + "Stat": "tm99.99", }, "ReturnData": true, }, ], - "Threshold": 220, + "Threshold": 29999, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiprodGETdummyresourceLatencyP99Warning8EE55673": Object { + "ScopeTestDummyApiLatencyTM999WarningD73972C6": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "P99 latency is too high.", - "AlarmName": "Test-DummyApi-prod-GET-dummyresource-Latency-P99-Warning", + "AlarmDescription": "TM999 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM999-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 33, - "EvaluationPeriods": 33, + "DatapointsToAlarm": 2999, + "EvaluationPeriods": 2999, "Metrics": Array [ Object { "Id": "m1", - "Label": "P99", + "Label": "TM99.9", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -902,12 +753,42 @@ Object { "Value": "DummyApi", }, Object { - "Name": "Method", - "Value": "GET", + "Name": "Stage", + "Value": "prod", }, + ], + "MetricName": "Latency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm99.9", + }, + "ReturnData": true, + }, + ], + "Threshold": 2999, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiLatencyTM99WarningFF55C464": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM99 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM99-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 299, + "EvaluationPeriods": 299, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM99", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ Object { - "Name": "Resource", - "Value": "dummy/resource", + "Name": "ApiName", + "Value": "DummyApi", }, Object { "Name": "Stage", @@ -918,21 +799,21 @@ Object { "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "p99", + "Stat": "tm99", }, "ReturnData": true, }, ], - "Threshold": 330, + "Threshold": 299, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiprodGETdummyresourceMaxTPSWarning864CD950": Object { + "ScopeTestDummyApiMaxTPSWarning62732F2B": Object { "Properties": Object { "ActionsEnabled": true, "AlarmDescription": "TPS is too high.", - "AlarmName": "Test-DummyApi-prod-GET-dummyresource-MaxTPS-Warning", + "AlarmName": "Test-DummyApi-MaxTPS-Warning", "ComparisonOperator": "GreaterThanThreshold", "DatapointsToAlarm": 3, "EvaluationPeriods": 3, @@ -952,14 +833,6 @@ Object { "Name": "ApiName", "Value": "DummyApi", }, - Object { - "Name": "Method", - "Value": "GET", - }, - Object { - "Name": "Resource", - "Value": "dummy/resource", - }, Object { "Name": "Stage", "Value": "prod", @@ -979,11 +852,11 @@ Object { }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiprodGETdummyresourceMinTPSWarning8ED5EFE3": Object { + "ScopeTestDummyApiMinTPSWarning4E8DB4D0": Object { "Properties": Object { "ActionsEnabled": true, "AlarmDescription": "TPS is too low.", - "AlarmName": "Test-DummyApi-prod-GET-dummyresource-MinTPS-Warning", + "AlarmName": "Test-DummyApi-MinTPS-Warning", "ComparisonOperator": "LessThanThreshold", "DatapointsToAlarm": 3, "EvaluationPeriods": 3, @@ -1003,14 +876,6 @@ Object { "Name": "ApiName", "Value": "DummyApi", }, - Object { - "Name": "Method", - "Value": "GET", - }, - Object { - "Name": "Resource", - "Value": "dummy/resource", - }, Object { "Name": "Stage", "Value": "prod", diff --git a/test/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.test.ts b/test/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.test.ts index 270a709d..53ce8b8a 100644 --- a/test/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.test.ts +++ b/test/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.test.ts @@ -43,38 +43,170 @@ test("snapshot test: all alarms", () => { alarmFriendlyName: "DummyApi", addLatencyP50Alarm: { Warning: { - maxLatency: Duration.millis(110), - datapointsToAlarm: 11, + maxLatency: Duration.millis(150), + datapointsToAlarm: 150, + }, + }, + addLatencyP70Alarm: { + Warning: { + maxLatency: Duration.millis(170), + datapointsToAlarm: 170, }, }, addLatencyP90Alarm: { Warning: { - maxLatency: Duration.millis(220), - datapointsToAlarm: 22, + maxLatency: Duration.millis(190), + datapointsToAlarm: 190, }, }, addLatencyP99Alarm: { Warning: { - maxLatency: Duration.millis(330), - datapointsToAlarm: 33, + maxLatency: Duration.millis(199), + datapointsToAlarm: 199, + }, + }, + addLatencyP999Alarm: { + Warning: { + maxLatency: Duration.millis(1999), + datapointsToAlarm: 1999, + }, + }, + addLatencyP9999Alarm: { + Warning: { + maxLatency: Duration.millis(19999), + datapointsToAlarm: 19999, + }, + }, + addLatencyP100Alarm: { + Warning: { + maxLatency: Duration.millis(1100), + datapointsToAlarm: 1100, + }, + }, + addLatencyTM50Alarm: { + Warning: { + maxLatency: Duration.millis(250), + datapointsToAlarm: 250, + }, + }, + addLatencyTM70Alarm: { + Warning: { + maxLatency: Duration.millis(270), + datapointsToAlarm: 270, + }, + }, + addLatencyTM90Alarm: { + Warning: { + maxLatency: Duration.millis(290), + datapointsToAlarm: 290, + }, + }, + addLatencyTM99Alarm: { + Warning: { + maxLatency: Duration.millis(299), + datapointsToAlarm: 299, + }, + }, + addLatencyTM999Alarm: { + Warning: { + maxLatency: Duration.millis(2999), + datapointsToAlarm: 2999, + }, + }, + addLatencyTM9999Alarm: { + Warning: { + maxLatency: Duration.millis(29999), + datapointsToAlarm: 29999, + }, + }, + addLatencyAverageAlarm: { + Warning: { + maxLatency: Duration.millis(20), + datapointsToAlarm: 20, }, }, addIntegrationLatencyP50Alarm: { - Critical: { - maxLatency: Duration.millis(110), - datapointsToAlarm: 11, + Warning: { + maxLatency: Duration.millis(150), + datapointsToAlarm: 150, + }, + }, + addIntegrationLatencyP70Alarm: { + Warning: { + maxLatency: Duration.millis(170), + datapointsToAlarm: 170, }, }, addIntegrationLatencyP90Alarm: { - Critical: { - maxLatency: Duration.millis(220), - datapointsToAlarm: 22, + Warning: { + maxLatency: Duration.millis(190), + datapointsToAlarm: 190, }, }, addIntegrationLatencyP99Alarm: { - Critical: { - maxLatency: Duration.millis(330), - datapointsToAlarm: 33, + Warning: { + maxLatency: Duration.millis(199), + datapointsToAlarm: 199, + }, + }, + addIntegrationLatencyP999Alarm: { + Warning: { + maxLatency: Duration.millis(1999), + datapointsToAlarm: 1999, + }, + }, + addIntegrationLatencyP9999Alarm: { + Warning: { + maxLatency: Duration.millis(19999), + datapointsToAlarm: 19999, + }, + }, + addIntegrationLatencyP100Alarm: { + Warning: { + maxLatency: Duration.millis(1100), + datapointsToAlarm: 1100, + }, + }, + addIntegrationLatencyTM50Alarm: { + Warning: { + maxLatency: Duration.millis(250), + datapointsToAlarm: 250, + }, + }, + addIntegrationLatencyTM70Alarm: { + Warning: { + maxLatency: Duration.millis(270), + datapointsToAlarm: 270, + }, + }, + addIntegrationLatencyTM90Alarm: { + Warning: { + maxLatency: Duration.millis(290), + datapointsToAlarm: 290, + }, + }, + addIntegrationLatencyTM99Alarm: { + Warning: { + maxLatency: Duration.millis(299), + datapointsToAlarm: 299, + }, + }, + addIntegrationLatencyTM999Alarm: { + Warning: { + maxLatency: Duration.millis(2999), + datapointsToAlarm: 2999, + }, + }, + addIntegrationLatencyTM9999Alarm: { + Warning: { + maxLatency: Duration.millis(29999), + datapointsToAlarm: 29999, + }, + }, + addIntegrationLatencyAverageAlarm: { + Warning: { + maxLatency: Duration.millis(20), + datapointsToAlarm: 20, }, }, add4xxCountAlarm: { @@ -114,6 +246,6 @@ test("snapshot test: all alarms", () => { }, }); - expect(numAlarmsCreated).toStrictEqual(12); + expect(numAlarmsCreated).toStrictEqual(34); expect(Template.fromStack(stack)).toMatchSnapshot(); }); diff --git a/test/monitoring/aws-apigatewayv2/__snapshots__/ApiGatewayV2HttpApiMonitoring.test.ts.snap b/test/monitoring/aws-apigatewayv2/__snapshots__/ApiGatewayV2HttpApiMonitoring.test.ts.snap index 86f9086f..6fdf653e 100644 --- a/test/monitoring/aws-apigatewayv2/__snapshots__/ApiGatewayV2HttpApiMonitoring.test.ts.snap +++ b/test/monitoring/aws-apigatewayv2/__snapshots__/ApiGatewayV2HttpApiMonitoring.test.ts.snap @@ -163,18 +163,618 @@ Object { }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiLatencyP50Critical4E10CCCB": Object { + "ScopeTestDummyApiIntegrationLatencyAverageWarning1FB2E797": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "P50 latency is too high.", - "AlarmName": "Test-DummyApi-Latency-P50-Critical", + "AlarmDescription": "Average integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-Average-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 20, + "EvaluationPeriods": 20, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "Average", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "Average", + }, + "ReturnData": true, + }, + ], + "Threshold": 20, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyP100Warning347C1F98": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "P100 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-P100-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 1100, + "EvaluationPeriods": 1100, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "P100", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "p100", + }, + "ReturnData": true, + }, + ], + "Threshold": 1100, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyP50WarningB23B4040": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "P50 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-P50-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 150, + "EvaluationPeriods": 150, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "P50", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "p50", + }, + "ReturnData": true, + }, + ], + "Threshold": 150, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyP70Warning3CC3EBD5": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "P70 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-P70-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 170, + "EvaluationPeriods": 170, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "P70", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "p70", + }, + "ReturnData": true, + }, + ], + "Threshold": 170, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyP90WarningF259FC77": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "P90 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-P90-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 190, + "EvaluationPeriods": 190, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "P90", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "p90", + }, + "ReturnData": true, + }, + ], + "Threshold": 190, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyP9999WarningA7C40063": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "P9999 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-P9999-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 19999, + "EvaluationPeriods": 19999, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "P99.99", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "p99.99", + }, + "ReturnData": true, + }, + ], + "Threshold": 19999, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyP999Warning9F27E61C": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "P999 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-P999-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 1999, + "EvaluationPeriods": 1999, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "P99.9", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "p99.9", + }, + "ReturnData": true, + }, + ], + "Threshold": 1999, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyP99WarningC8929BAD": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "P99 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-P99-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 199, + "EvaluationPeriods": 199, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "P99", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "p99", + }, + "ReturnData": true, + }, + ], + "Threshold": 199, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyTM50Warning6B4229D0": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM50 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-TM50-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 250, + "EvaluationPeriods": 250, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM50", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm50", + }, + "ReturnData": true, + }, + ], + "Threshold": 250, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyTM70WarningB60BC024": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM70 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-TM70-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 270, + "EvaluationPeriods": 270, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM70", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm70", + }, + "ReturnData": true, + }, + ], + "Threshold": 270, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyTM90Warning2A0B535F": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM90 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-TM90-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 290, + "EvaluationPeriods": 290, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM90", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm90", + }, + "ReturnData": true, + }, + ], + "Threshold": 290, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyTM9999Warning26E553E4": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM9999 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-TM9999-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 29999, + "EvaluationPeriods": 29999, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM99.99", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm99.99", + }, + "ReturnData": true, + }, + ], + "Threshold": 29999, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyTM999Warning08B604B1": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM999 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-TM999-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 2999, + "EvaluationPeriods": 2999, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM99.9", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm99.9", + }, + "ReturnData": true, + }, + ], + "Threshold": 2999, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiIntegrationLatencyTM99WarningACB026E2": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM99 integration latency is too high.", + "AlarmName": "Test-DummyApi-IntegrationLatency-TM99-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 299, + "EvaluationPeriods": 299, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM99", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "IntegrationLatency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm99", + }, + "ReturnData": true, + }, + ], + "Threshold": 299, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiLatencyAverageWarning27D59767": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "Average latency is too high.", + "AlarmName": "Test-DummyApi-Latency-Average-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 20, + "EvaluationPeriods": 20, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "Average", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "Latency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "Average", + }, + "ReturnData": true, + }, + ], + "Threshold": 20, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiLatencyP100WarningB48A5E64": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "P100 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P100-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 11, - "EvaluationPeriods": 11, + "DatapointsToAlarm": 1100, + "EvaluationPeriods": 1100, "Metrics": Array [ Object { "Id": "m1", - "Label": "P50 Integration Latency", + "Label": "P100", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -189,16 +789,16 @@ Object { "Value": "$default", }, ], - "MetricName": "IntegrationLatency", + "MetricName": "Latency", "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "p50", + "Stat": "p100", }, "ReturnData": true, }, ], - "Threshold": 110, + "Threshold": 1100, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", @@ -209,12 +809,12 @@ Object { "AlarmDescription": "P50 latency is too high.", "AlarmName": "Test-DummyApi-Latency-P50-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 11, - "EvaluationPeriods": 11, + "DatapointsToAlarm": 150, + "EvaluationPeriods": 150, "Metrics": Array [ Object { "Id": "m1", - "Label": "P50 Latency", + "Label": "P50", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -238,23 +838,23 @@ Object { "ReturnData": true, }, ], - "Threshold": 110, + "Threshold": 150, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiLatencyP90Critical72F6910F": Object { + "ScopeTestDummyApiLatencyP70Warning56ABF038": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "P90 latency is too high.", - "AlarmName": "Test-DummyApi-Latency-P90-Critical", + "AlarmDescription": "P70 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P70-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 22, - "EvaluationPeriods": 22, + "DatapointsToAlarm": 170, + "EvaluationPeriods": 170, "Metrics": Array [ Object { "Id": "m1", - "Label": "P90 Integration Latency", + "Label": "P70", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -269,16 +869,16 @@ Object { "Value": "$default", }, ], - "MetricName": "IntegrationLatency", + "MetricName": "Latency", "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "p90", + "Stat": "p70", }, "ReturnData": true, }, ], - "Threshold": 220, + "Threshold": 170, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", @@ -289,12 +889,12 @@ Object { "AlarmDescription": "P90 latency is too high.", "AlarmName": "Test-DummyApi-Latency-P90-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 22, - "EvaluationPeriods": 22, + "DatapointsToAlarm": 190, + "EvaluationPeriods": 190, "Metrics": Array [ Object { "Id": "m1", - "Label": "P90 Latency", + "Label": "P90", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -318,23 +918,23 @@ Object { "ReturnData": true, }, ], - "Threshold": 220, + "Threshold": 190, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "ScopeTestDummyApiLatencyP99Critical6A9D549F": Object { + "ScopeTestDummyApiLatencyP9999Warning89E47C72": Object { "Properties": Object { "ActionsEnabled": true, - "AlarmDescription": "P99 latency is too high.", - "AlarmName": "Test-DummyApi-Latency-P99-Critical", + "AlarmDescription": "P9999 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P9999-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 33, - "EvaluationPeriods": 33, + "DatapointsToAlarm": 19999, + "EvaluationPeriods": 19999, "Metrics": Array [ Object { "Id": "m1", - "Label": "P99 Integration Latency", + "Label": "P99.99", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -349,16 +949,56 @@ Object { "Value": "$default", }, ], - "MetricName": "IntegrationLatency", + "MetricName": "Latency", "Namespace": "AWS/ApiGateway", }, "Period": 300, - "Stat": "p99", + "Stat": "p99.99", + }, + "ReturnData": true, + }, + ], + "Threshold": 19999, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiLatencyP999Warning8CF0377D": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "P999 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-P999-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 1999, + "EvaluationPeriods": 1999, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "P99.9", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "Latency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "p99.9", }, "ReturnData": true, }, ], - "Threshold": 330, + "Threshold": 1999, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", @@ -369,12 +1009,12 @@ Object { "AlarmDescription": "P99 latency is too high.", "AlarmName": "Test-DummyApi-Latency-P99-Warning", "ComparisonOperator": "GreaterThanThreshold", - "DatapointsToAlarm": 33, - "EvaluationPeriods": 33, + "DatapointsToAlarm": 199, + "EvaluationPeriods": 199, "Metrics": Array [ Object { "Id": "m1", - "Label": "P99 Latency", + "Label": "P99", "MetricStat": Object { "Metric": Object { "Dimensions": Array [ @@ -398,7 +1038,247 @@ Object { "ReturnData": true, }, ], - "Threshold": 330, + "Threshold": 199, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiLatencyTM50Warning092E86BF": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM50 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM50-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 250, + "EvaluationPeriods": 250, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM50", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "Latency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm50", + }, + "ReturnData": true, + }, + ], + "Threshold": 250, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiLatencyTM70Warning8E657453": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM70 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM70-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 270, + "EvaluationPeriods": 270, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM70", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "Latency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm70", + }, + "ReturnData": true, + }, + ], + "Threshold": 270, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiLatencyTM90Warning0FDD3108": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM90 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM90-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 290, + "EvaluationPeriods": 290, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM90", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "Latency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm90", + }, + "ReturnData": true, + }, + ], + "Threshold": 290, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiLatencyTM9999Warning4181DE97": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM9999 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM9999-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 29999, + "EvaluationPeriods": 29999, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM99.99", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "Latency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm99.99", + }, + "ReturnData": true, + }, + ], + "Threshold": 29999, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiLatencyTM999WarningD73972C6": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM999 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM999-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 2999, + "EvaluationPeriods": 2999, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM99.9", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "Latency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm99.9", + }, + "ReturnData": true, + }, + ], + "Threshold": 2999, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "ScopeTestDummyApiLatencyTM99WarningFF55C464": Object { + "Properties": Object { + "ActionsEnabled": true, + "AlarmDescription": "TM99 latency is too high.", + "AlarmName": "Test-DummyApi-Latency-TM99-Warning", + "ComparisonOperator": "GreaterThanThreshold", + "DatapointsToAlarm": 299, + "EvaluationPeriods": 299, + "Metrics": Array [ + Object { + "Id": "m1", + "Label": "TM99", + "MetricStat": Object { + "Metric": Object { + "Dimensions": Array [ + Object { + "Name": "ApiId", + "Value": Object { + "Ref": "testHttpApiC57B300F", + }, + }, + Object { + "Name": "Stage", + "Value": "$default", + }, + ], + "MetricName": "Latency", + "Namespace": "AWS/ApiGateway", + }, + "Period": 300, + "Stat": "tm99", + }, + "ReturnData": true, + }, + ], + "Threshold": 299, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm",