Skip to content

Commit

Permalink
feat: add lambda invocation failure alarm
Browse files Browse the repository at this point in the history
  • Loading branch information
krissrex committed May 10, 2024
1 parent 565f57f commit e0e4da0
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/alarms/__tests__/__snapshots__/lambda-alarms.test.ts.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions src/alarms/__tests__/lambda-alarms.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import "@aws-cdk/assert/jest"
import { App, Stack } from "aws-cdk-lib"
import * as cloudwatchActions from "aws-cdk-lib/aws-cloudwatch-actions"
import * as sns from "aws-cdk-lib/aws-sns"
import "jest-cdk-snapshot"
import { LambdaAlarms } from "../lambda-alarms"

test("create alarms", () => {
const app = new App()
const supportStack = new Stack(app, "SupportStack")
const stack = new Stack(app, "Stack")

const topic = new sns.Topic(supportStack, "Topic")
const action = new cloudwatchActions.SnsAction(topic)

const alarms = new LambdaAlarms(stack, "LambdaAlarms", {
actions: [action],
lambdaFunctionName: "lambda-function-name",
})

alarms.addInvocationErrorAlarm({
appendToAlarmDescription: "Runbook at https://liflig.no",
})

expect(stack).toMatchCdkSnapshot()
})
62 changes: 62 additions & 0 deletions src/alarms/lambda-alarms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import * as constructs from "constructs"
import * as cdk from "aws-cdk-lib"
import * as cloudwatch from "aws-cdk-lib/aws-cloudwatch"

export interface LambdaAlarmsProps {
actions: cloudwatch.IAlarmAction[]
lambdaFunctionName: string
}

export class LambdaAlarms extends constructs.Construct {
private readonly actions: cloudwatch.IAlarmAction[]
private readonly lambdaFunctionName: string

constructor(
scope: constructs.Construct,
id: string,
props: LambdaAlarmsProps,
) {
super(scope, id)

this.actions = props.actions
this.lambdaFunctionName = props.lambdaFunctionName
}

/**
* Sets up a CloudWatch Alarm that triggers if the Lambda fails invocations.
* This usually happens from uncaught exceptions in the lambda.
*/
addInvocationErrorAlarm(
/**
* Configuration for an alarm.
*/
props?: {
/**
* Add extra information to the alarm description, like Runbook URL or steps to triage.
*/
appendToAlarmDescription?: string
},
): void {
const alarm = new cloudwatch.Metric({
metricName: "Errors",
namespace: "AWS/Lambda",
statistic: "Sum",
period: cdk.Duration.seconds(60), // Standard resolution metric has a minimum of 60s period
dimensionsMap: {
FunctionName: this.lambdaFunctionName,
},
}).createAlarm(this, "FailedInvocationAlarm", {
alarmDescription: `Invocation for '${this.lambdaFunctionName}' failed. ${props?.appendToAlarmDescription ?? ""}`,
comparisonOperator:
cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
evaluationPeriods: 1,
threshold: 1,
treatMissingData: cloudwatch.TreatMissingData.IGNORE,
})

this.actions.forEach((action) => {
alarm.addAlarmAction(action)
alarm.addOkAction(action)
})
}
}

0 comments on commit e0e4da0

Please sign in to comment.