Last active
October 4, 2018 09:28
-
-
Save jeka-kiselyov/3f3801a165cab9e4a9fd to your computer and use it in GitHub Desktop.
CloudWatch to AWS Lambda to Slack Channel Alerts and Charts. Posts CloudWatch Alerts via SNS topic via Lambda function to Slack channel. And draws charts for CPUUtilization metrics(both for EC2 abd RDS).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////// Save as index.js and upload it to Lambda as zip archive with node_modules directory. After: | |
////// npm install aws-cloudwatch-chart | |
////// npm install request | |
////// no need to upload aws-sdk module | |
////// Don't forget to change API keys here. | |
////// License: MIT | |
////// Docs: | |
////// https://github.com/jeka-kiselyov/aws-cloudwatch-chart | |
////// http://docs.aws.amazon.com/sns/latest/dg/sns-lambda.html | |
////// http://docs.aws.amazon.com/lambda/latest/dg/walkthrough-s3-events-adminuser-create-test-function-create-function.html | |
////// | |
exports.handler = function(event, context) { | |
var request = require('request'); | |
var fs = require('fs'); | |
var AwsCloudWatchChart = require('aws-cloudwatch-chart'); | |
var config = {}; | |
config.slack = { | |
token: 'xoxp-4234234-234234-234234234-257abf', | |
channel: '#aws', | |
initialComment: "EC2 CPU Usage %from_time% to %to_time% UTC", | |
fileTitle: "EC2 CPU Usage %from_time% to %to_time% UTC" | |
}; | |
config.aws = { | |
accessKeyId: "ASDASDSADSADASD", | |
secretAccessKey: "dsfsdfsdf/REWR/fdsdf/DFDSf34", | |
region: "us-east-1" | |
}; | |
config.timeOffset = 1440; | |
config.timePeriod = 60; | |
config.graphSamples = 20; | |
config.width = 1000; | |
config.height = 250; | |
if (typeof(event.Records) === 'undefined' || typeof(event.Records[0]) === 'undefined' || typeof(event.Records[0].Sns) === 'undefined') | |
context.fail ('ERROR: requires SNS message'); | |
if (typeof(event.Records[0].Sns.Message) !== 'undefined' && typeof(event.Records[0].Sns.Message.Trigger) === 'undefined') | |
event.Records[0].Sns.Message = JSON.parse(event.Records[0].Sns.Message); | |
config.slack.initialComment = event.Records[0].Sns.Subject + "\n" + event.Records[0].Sns.Message.AlarmDescription; | |
config.metrics = []; | |
console.log('event.Records[0].Sns.Message:'); | |
console.log(event.Records[0].Sns.Message); | |
if (typeof(event.Records[0].Sns.Message.Trigger) !== 'undefined' && typeof(event.Records[0].Sns.Message.Trigger.Dimensions) !== 'undefined') | |
{ | |
if (event.Records[0].Sns.Message.Trigger.Namespace == 'AWS/EC2' && event.Records[0].Sns.Message.Trigger.MetricName == 'CPUUtilization') | |
{ | |
config.metrics.push({ | |
InstanceId: event.Records[0].Sns.Message.Trigger.Dimensions[0].value, | |
title: event.Records[0].Sns.Message.Trigger.Dimensions[0].value+" EC2 Max CPU Usage", | |
Namespace: event.Records[0].Sns.Message.Trigger.Namespace, | |
MetricName: event.Records[0].Sns.Message.Trigger.MetricName, | |
StatisticValues: "Maximum", | |
Unit: "Percent", | |
color: "af9cf4", | |
thickness: 2, | |
dashed: false | |
}); | |
} else if (event.Records[0].Sns.Message.Trigger.Namespace == 'AWS/RDS' && event.Records[0].Sns.Message.Trigger.MetricName == 'CPUUtilization') { | |
config.metrics.push({ | |
DBInstanceIdentifier: event.Records[0].Sns.Message.Trigger.Dimensions[0].value, | |
title: event.Records[0].Sns.Message.Trigger.Dimensions[0].value+" DB Max CPU Usage", | |
Namespace: event.Records[0].Sns.Message.Trigger.Namespace, | |
MetricName: event.Records[0].Sns.Message.Trigger.MetricName, | |
StatisticValues: "Maximum", | |
Unit: "Percent", | |
color: "9caff4", | |
thickness: 2, | |
dashed: false | |
}); | |
} else if (event.Records[0].Sns.Message.Trigger.Namespace == 'AWS/EC2' && event.Records[0].Sns.Message.Trigger.MetricName == 'CPUCreditBalance') { | |
config.metrics.push({ | |
InstanceId: event.Records[0].Sns.Message.Trigger.Dimensions[0].value, | |
title: event.Records[0].Sns.Message.Trigger.Dimensions[0].value+" CPU Credit Balance", | |
Namespace: event.Records[0].Sns.Message.Trigger.Namespace, | |
MetricName: event.Records[0].Sns.Message.Trigger.MetricName, | |
StatisticValues: "Maximum", | |
Unit: "Count", | |
color: "9caff4", | |
thickness: 2, | |
dashed: false | |
}); | |
} | |
} | |
var postSlackMessage = function(text, imageURL, callback) | |
{ | |
var apiURL = "https://slack.com/api/chat.postMessage?token=" + encodeURIComponent(config.slack.token) + | |
"&text=" + encodeURIComponent("ALERT\n"+imageURL) + | |
"&username=" + encodeURIComponent('AWS') + | |
"&as_user=" + encodeURIComponent('false') + | |
"&icon_emoji=" + encodeURIComponent(':bell:') + | |
"&attachments=" + encodeURIComponent('[{"fallback": '+JSON.stringify(text)+',"text": '+JSON.stringify(text)+', "color": "danger"}]') + | |
"&channel=" + encodeURIComponent(config.slack.channel); | |
var req = request.post(apiURL, callback); | |
} | |
if (config.metrics.length < 1) | |
{ | |
/// post | |
postSlackMessage(config.slack.initialComment, '', function() { | |
context.done(null, 'Not AWS/EC2 CPUUtilization metric'); | |
}); | |
} else { | |
var acs = new AwsCloudWatchChart(config); | |
console.log('Start'); | |
acs.getChart().then(function(chart){ | |
console.log('Got chart URL'); | |
console.log(chart.getURL()); | |
chart.get().then(function(image){ | |
console.log('Got chart image'); | |
var fileTitle = config.slack.fileTitle. | |
split('%from_time%').join(acs.getFromTimeString()). | |
split('%to_time%').join(acs.getToTimeString()); | |
var initialComment = config.slack.initialComment. | |
split('%from_time%').join(acs.getFromTimeString()). | |
split('%to_time%').join(acs.getToTimeString()); | |
var apiURL = "https://slack.com/api/files.upload?token=" + encodeURIComponent(config.slack.token) + | |
"&filename=" + encodeURIComponent("image.png") + | |
"&title=" + encodeURIComponent(fileTitle) + | |
"&initial_comment=" + encodeURIComponent(initialComment); | |
console.log('Sending file to Slack...'); | |
var callback = function (err, response, body) { | |
var data = JSON.parse(body); | |
var text = config.slack.initialComment; | |
postSlackMessage(text, data.file.url, function() { | |
context.done(null, "Done"); | |
}); | |
} | |
var req = request.post(apiURL, callback); | |
var form = req.form(); | |
form.append('file', new Buffer(image), {contentType: 'image/png', filename: 'x.png', name: 'x.png'}); | |
}); | |
}); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Whould be possible use IAM roles instead of Keys/secrets?