-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathlambda-alarms.ts
96 lines (88 loc) · 3.48 KB
/
lambda-alarms.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { Duration } from "aws-cdk-lib";
import { ComparisonOperator, MathExpression, TreatMissingData } from "aws-cdk-lib/aws-cloudwatch";
import type { GuStack } from "../core";
import type { GuLambdaFunction } from "../lambda";
import { GuAlarm } from "./alarm";
import type { GuAlarmProps } from "./alarm";
export interface GuLambdaErrorPercentageMonitoringProps
extends Omit<
GuAlarmProps,
"metric" | "threshold" | "comparisonOperator" | "evaluationPeriods" | "treatMissingData" | "app"
> {
toleratedErrorPercentage: number;
lengthOfEvaluationPeriod?: Duration;
numberOfEvaluationPeriodsAboveThresholdBeforeAlarm?: number;
noMonitoring?: false;
}
interface GuLambdaAlarmProps extends GuLambdaErrorPercentageMonitoringProps {
lambda: GuLambdaFunction;
}
/**
* Creates an alarm which is triggered whenever the error percentage specified is exceeded.
*/
export class GuLambdaErrorPercentageAlarm extends GuAlarm {
constructor(scope: GuStack, id: string, props: GuLambdaAlarmProps) {
const mathExpression = new MathExpression({
expression: "100*m1/m2",
usingMetrics: { m1: props.lambda.metricErrors(), m2: props.lambda.metricInvocations() },
label: `Error % of ${props.lambda.functionName}`,
period: props.lengthOfEvaluationPeriod ?? Duration.minutes(1),
});
const defaultAlarmName = `High error percentage from ${props.lambda.functionName} lambda in ${scope.stage}`;
const defaultDescription = `${props.lambda.functionName} exceeded ${props.toleratedErrorPercentage}% error rate`;
const alarmProps: GuAlarmProps = {
...props,
app: props.lambda.app,
metric: mathExpression,
treatMissingData: TreatMissingData.NOT_BREACHING,
threshold: props.toleratedErrorPercentage,
comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
evaluationPeriods: props.numberOfEvaluationPeriodsAboveThresholdBeforeAlarm ?? 1,
alarmName: props.alarmName ?? defaultAlarmName,
alarmDescription: props.alarmDescription ?? defaultDescription,
};
super(scope, id, alarmProps);
}
}
export interface GuLambdaThrottlingMonitoringProps
extends Omit<
GuAlarmProps,
"metric" | "threshold" | "comparisonOperator" | "evaluationPeriods" | "treatMissingData" | "app"
> {
/**
* Sum of thottled invocations above which to alarm.
*
* @defaultValue 0
*/
toleratedThrottlingCount?: number;
/**
* Evaluation period in minutes for alarm.
*
* @defaultValue 1
*/
numberOfMinutesAboveThresholdBeforeAlarm?: number;
noMonitoring?: false;
}
interface GuLambdaThrottlingAlarmProps extends GuLambdaThrottlingMonitoringProps {
lambda: GuLambdaFunction;
}
export class GuLambdaThrottlingAlarm extends GuAlarm {
constructor(scope: GuStack, id: string, props: GuLambdaThrottlingAlarmProps) {
super(scope, id, {
...props,
app: props.lambda.app,
alarmName:
props.alarmName ?? `Lambda throttling alarm for ${props.lambda.functionName} lambda in ${scope.stage}.`,
alarmDescription:
props.alarmDescription ?? "Alarm when lambda is throttled (which causes requests to fail with a 429).",
threshold: props.toleratedThrottlingCount ?? 0,
evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,
metric: props.lambda.metricThrottles({
period: Duration.seconds(60),
statistic: "sum",
}),
treatMissingData: TreatMissingData.NOT_BREACHING,
comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
});
}
}