Skip to content

Commit

Permalink
Tidy up the branch
Browse files Browse the repository at this point in the history
- Integration test passed
- EventBridge section added to the README
- Alarms disabled at eventsRule level
  • Loading branch information
direnakkoc committed Jul 12, 2022
1 parent bb23c5e commit 69e6d6c
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 41 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,18 @@ SNS Topic dashboard widgets show:
|--|--|
|![Invalid Attributes](https://raw.githubusercontent.com/fourtheorem/slic-watch/main/docs/snsInvalidAttributes.png)|![Notifications Failed](https://raw.githubusercontent.com/fourtheorem/slic-watch/main/docs/snsNotificationsFailed.png) |

### EventBridge

EventBridge alarms are created for:
1. Failed Invocations
2. ThrottledRules

EventBridge Rule dashboard widgets show:

|FailedInvocations|Invocations|ThrottledRules|
|--|--|
|![FailedInvocations](https://raw.githubusercontent.com/fourtheorem/slic-watch/main/docs/eventBridgeFailedInvocations.png)|![Invocations](https://raw.githubusercontent.com/fourtheorem/slic-watch/main/docs/eventBridgeInvocations.png)|

## Configuration

Configuration is entirely optional - SLIC Watch provides defaults that work out of the box.
Expand Down Expand Up @@ -286,6 +298,14 @@ custom:
NumberOfNotificationsFailed:
Statistic: Sum
Threshold: 1
Events:
#EventBridge
FailedInvocations:
Statistic: Sum
Threshold: 1
ThrottledRules:
Statistic: Sum
Threshold: 1

dashboard:
enabled: true
Expand Down Expand Up @@ -371,6 +391,14 @@ custom:
Statistic: ["Sum"]
NumberOfNotificationsFailed:
Statistic: ["Sum"]
Events:
#EventBridge
FailedInvocations:
Statistic: ["Sum"]
ThrottledRules:
Statistic: ["Sum"]
Invocations:
Statistic: ["Sum"]
```
An example project is provided for reference: [serverless-test-project](./serverless-test-project)
Expand Down
Binary file added docs/eventBridgeFailedInvocations.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/eventBridgeInvocations.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 6 additions & 6 deletions serverless-plugin/alarms-eventbridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
*/
module.exports = function eventsAlarms (eventsAlarmsConfig, context) {
return {
createEventsAlarms
createRuleAlarms
}

/**
* Add all required Events alarms to the provided CloudFormation template
* based on the Events resources found within
* based on the EventBridge Rule found within
*
* @param {CloudFormationTemplate} cfTemplate A CloudFormation template object
*/
function createEventsAlarms (cfTemplate) {
function createRuleAlarms (cfTemplate) {
const ruleResources = cfTemplate.getResourcesByType(
'AWS::Events::Rule'
)
Expand All @@ -40,7 +40,7 @@ module.exports = function eventsAlarms (eventsAlarmsConfig, context) {
}
}

function createEventsAlarm (
function createRuleAlarm (
alarmName,
alarmDescription,
ruleName,
Expand Down Expand Up @@ -82,7 +82,7 @@ module.exports = function eventsAlarms (eventsAlarmsConfig, context) {

return {
resourceName: `slicWatchEventsFailedInvocationsAlarm${ruleResourceName}`,
resource: createEventsAlarm(
resource: createRuleAlarm(
`EventsFailedInvocationsAlarm_${ruleName}`, // alarmName
`Failed Invocations for ${ruleName} breaches ${threshold}`, // alarmDescription
ruleName,
Expand All @@ -102,7 +102,7 @@ module.exports = function eventsAlarms (eventsAlarmsConfig, context) {
const threshold = config.Threshold
return {
resourceName: `slicWatchEventsThrottledRulesAlarm${ruleResourceName}`,
resource: createEventsAlarm(
resource: createRuleAlarm(
`EventsThrottledRulesAlarm_${ruleName}`, // alarmName
`Throttled RulesAlarm for ${ruleName} breaches ${threshold}`, // alarmDescription
ruleName,
Expand Down
8 changes: 4 additions & 4 deletions serverless-plugin/alarms.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const kinesisAlarms = require('./alarms-kinesis')
const sqsAlarms = require('./alarms-sqs')
const ecsAlarms = require('./alarms-ecs')
const snsAlarms = require('./alarms-sns')
const eventsAlarms = require('./alarms-eventbridge')
const ruleAlarms = require('./alarms-eventbridge')

module.exports = function alarms (serverless, alarmConfig, functionAlarmConfigs, context) {
const {
Expand All @@ -23,7 +23,7 @@ module.exports = function alarms (serverless, alarmConfig, functionAlarmConfigs,
Lambda: lambdaConfig,
ECS: ecsConfig,
SNS: snsConfig,
Events: eventsConfig
Events: ruleConfig
} = cascade(alarmConfig)

const cascadedFunctionAlarmConfigs = applyAlarmConfig(lambdaConfig, functionAlarmConfigs)
Expand All @@ -35,7 +35,7 @@ module.exports = function alarms (serverless, alarmConfig, functionAlarmConfigs,
const { createSQSAlarms } = sqsAlarms(sqsConfig, context, serverless)
const { createECSAlarms } = ecsAlarms(ecsConfig, context, serverless)
const { createSNSAlarms } = snsAlarms(snsConfig, context, serverless)
const { createEventsAlarms } = eventsAlarms(eventsConfig, context, serverless)
const { createRuleAlarms } = ruleAlarms(ruleConfig, context, serverless)

return {
addAlarms
Expand All @@ -57,7 +57,7 @@ module.exports = function alarms (serverless, alarmConfig, functionAlarmConfigs,
sqsConfig.enabled && createSQSAlarms(cfTemplate)
ecsConfig.enabled && createECSAlarms(cfTemplate)
snsConfig.enabled && createSNSAlarms(cfTemplate)
eventsConfig.enabled && createEventsAlarms(cfTemplate)
ruleConfig.enabled && createRuleAlarms(cfTemplate)
}
}
}
6 changes: 3 additions & 3 deletions serverless-plugin/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports = function dashboard (serverless, dashboardConfig, functionDashbo
SQS: sqsDashConfig,
ECS: ecsDashConfig,
SNS: snsDashConfig,
Events: eventsDashConfig
Events: ruleDashConfig
}
} = cascade(dashboardConfig)

Expand Down Expand Up @@ -518,7 +518,7 @@ module.exports = function dashboard (serverless, dashboardConfig, functionDashbo
const ruleName = res.Properties.Name

const widgetMetrics = []
for (const [metric, metricConfig] of Object.entries(getConfiguredMetrics(eventsDashConfig))) {
for (const [metric, metricConfig] of Object.entries(getConfiguredMetrics(ruleDashConfig))) {
if (metricConfig.enabled) {
for (const stat of metricConfig.Statistic) {
widgetMetrics.push({
Expand All @@ -536,7 +536,7 @@ module.exports = function dashboard (serverless, dashboardConfig, functionDashbo
const metricStatWidget = createMetricWidget(
`Events rule ${ruleName}`,
widgetMetrics,
eventsDashConfig
ruleDashConfig
)
ruleWidgets.push(metricStatWidget)
}
Expand Down
2 changes: 1 addition & 1 deletion serverless-plugin/default-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ dashboard:
NumberOfNotificationsFailed:
Statistic: ["Sum"]
Events:
#EventBridge
#EventBridge
FailedInvocations:
Statistic: ["Sum"]
ThrottledRules:
Expand Down
16 changes: 8 additions & 8 deletions serverless-plugin/tests/alarms-eventbridge.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict'

const eventsAlarms = require('../alarms-eventbridge')
const ruleAlarms = require('../alarms-eventbridge')
const { test } = require('tap')
const defaultConfig = require('../default-config')
const {
Expand Down Expand Up @@ -30,11 +30,11 @@ test('Events alarms are created', (t) => {
}
)

const eventsAlarmConfig = alarmConfig.Events
const ruleAlarmConfig = alarmConfig.Events

const { createEventsAlarms } = eventsAlarms(eventsAlarmConfig, testContext)
const { createRuleAlarms } = ruleAlarms(ruleAlarmConfig, testContext)
const cfTemplate = createTestCloudFormationTemplate()
createEventsAlarms(cfTemplate)
createRuleAlarms(cfTemplate)

const alarmResources = cfTemplate.getResourcesByType('AWS::CloudWatch::Alarm')

Expand All @@ -51,7 +51,7 @@ test('Events alarms are created', (t) => {
const expectedMetric = expectedTypes[alarmType]
t.equal(al.MetricName, expectedMetric)
t.ok(al.Statistic)
t.equal(al.Threshold, eventsAlarmConfig[expectedMetric].Threshold)
t.equal(al.Threshold, ruleAlarmConfig[expectedMetric].Threshold)
t.equal(al.EvaluationPeriods, 2)
t.equal(al.TreatMissingData, 'breaching')
t.equal(al.ComparisonOperator, 'GreaterThanOrEqualToThreshold')
Expand Down Expand Up @@ -85,12 +85,12 @@ test('Events alarms are not created when disabled globally', (t) => {
}
)

const eventsAlarmConfig = alarmConfig.Events
const ruleAlarmConfig = alarmConfig.Events

const { createEventsAlarms } = eventsAlarms(eventsAlarmConfig, testContext)
const { createRuleAlarms } = ruleAlarms(ruleAlarmConfig, testContext)

const cfTemplate = createTestCloudFormationTemplate()
createEventsAlarms(cfTemplate)
createRuleAlarms(cfTemplate)

const alarmResources = cfTemplate.getResourcesByType('AWS::CloudWatch::Alarm')

Expand Down
14 changes: 5 additions & 9 deletions serverless-test-project/rule-handler.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
'use strict'

module.exports.handleRule = (event, context, callback) => {
module.exports.handleRule = async (event) => {
console.log(event)
if (event.sleepSeconds) {
return new Promise((resolve) => {
setTimeout(resolve, event.sleepSeconds * 1000)
})
}
if (event.triggerError) {
const e = Boolean(event.detail.triggerError)
if (e) {
throw new Error('Error triggered')
} else {
console.log('Successful event delivery')
}
console.log('Error occured')
return Error
}
19 changes: 9 additions & 10 deletions serverless-test-project/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,9 @@ custom:
alarms:
Lambda:
Invocations:
enabled: false
Threshold: 10
DurationPc:
enabled: false
Threshold: 10
ThrottlesPc:
enabled: false
Threshold: 10
Errors:
enabled: false
enabled: true
Threshold: 10

SQS:
AgeOfOldestMessage:
Statistic: Maximum
Expand Down Expand Up @@ -97,11 +89,18 @@ functions:

eventsRule:
handler: rule-handler.handleRule
slicWatch:
alarms:
Lambda:
enabled: false
events:
- eventBridge:
pattern:
detail-type:
- Invoke Lambda Function
retryPolicy:
maximumEventAge: 60
maximumRetryAttempts: 2

resources: ${file(./sls-resources.yml)}

Expand Down
Loading

0 comments on commit 69e6d6c

Please sign in to comment.