Skip to content

Instantly share code, notes, and snippets.

@reneoelke
Last active November 15, 2017 18:08
Show Gist options
  • Select an option

  • Save reneoelke/23abaecc467313f1c0f27fc907b68e69 to your computer and use it in GitHub Desktop.

Select an option

Save reneoelke/23abaecc467313f1c0f27fc907b68e69 to your computer and use it in GitHub Desktop.
An Amazon Web Services SNS trigger that sends CloudWatch alarm notifications to Slack.
var url = require("url");
var https = require("https");
var hookUrl = "HOOK_URL";
var slackChannel = "SLACK_CHANNEL";
var postMessage = function(message, callback) {
var body = JSON.stringify(message);
var options = url.parse(hookUrl);
options.method = "POST";
options.headers = {
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(body),
};
var postReq = https.request(options, function(res) {
var chunks = [];
res.setEncoding("utf8");
res.on("data", function(chunk) {
return chunks.push(chunk);
});
res.on("end", function() {
var body = chunks.join("");
if (callback) {
callback({
body: body,
statusCode: res.statusCode,
statusMessage: res.statusMessage
});
}
});
return res;
});
postReq.write(body);
postReq.end();
};
var processEvent = function(event, context) {
var message = JSON.parse(event.Records[0].Sns.Message);
var text = message.NewStateValue + ": \"" + message.AlarmName + "\". View this alarm in the <https://console.aws.amazon.com/cloudwatch/home?region=eu-central-1#s=Alarms&alarm=" + encodeURIComponent(message.AlarmName) + "|AWS Management Console>";
var color = (message.NewStateValue === "ALARM") ? "danger" : "good";
var attachment = {
"fallback": message.NewStateReason,
"color": color,
"fields": [
{
"title": "Name",
"value": message.AlarmName,
"short": true
},
{
"title": "State Change",
"value": message.OldStateValue + " >> " + message.NewStateValue,
"short": true
},
{
"title": "Reason",
"value": message.NewStateReason,
"short": false
},
],
"ts": Math.floor(Date.parse("2016-07-06T08:02:44.673+0000") / 1000)
};
var slackMessage = {
channel: slackChannel,
text: text,
attachments: [attachment],
};
postMessage(slackMessage, function(response) {
if (response.statusCode < 400) {
console.info("Message posted successfully");
context.succeed();
} else if (response.statusCode < 500) {
console.error("Error posting message to Slack API: " + response.statusCode + " - " + response.statusMessage);
context.succeed(); // Don't retry because the error is due to a problem with the request
} else {
// Let Lambda retry
context.fail("Server error when processing message: " + response.statusCode + " - " + response.statusMessage);
}
});
};
exports.handler = function(event, context) {
if (hookUrl) {
// Container reuse, simply process the event with the key in memory
processEvent(event, context);
} else {
context.fail("Hook URL has not been set.");
}
};
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
"Sns": {
"Type": "Notification",
"MessageId": "xxxxx-xxx-xxx-xxxxxxxx",
"TopicArn": "arn:aws:sns:EXAMPLE",
"Subject": "ALARM: 'foo-bar' in APAC - Tokyo",
"Message": " {\"AlarmName\": \"foo-bar\",\"AlarmDescription\": null,\"AWSAccountId\": \"1234567890\",\"NewStateValue\": \"ALARM\",\"NewStateReason\": \"Threshold Crossed: 1 datapoint (38.3000817350394) was greater than or equal to the threshold (10.0).\",\"StateChangeTime\": \"1970-01-01T00:020:00.001+0000\",\"Region\": \"EU - Frankfurt\",\"OldStateValue\": \"OK\",\"Trigger\": {\"MetricName\": \"MemoryUtilization\",\"Namespace\": \"System/Linux\",\"Statistic\": \"AVERAGE\",\"Unit\": null,\"Dimensions\": [{\"name\": \"InstanceId\",\"value\": \"i-e7wuqzw7\"}],\"Period\": 3600,\"EvaluationPeriods\": 1,\"ComparisonOperator\": \"GreaterThanOrEqualToThreshold\",\"Threshold\": 10}}",
"Timestamp": "1970-01-01T00:00:00.001Z",
"SignatureVersion": "1",
"Signature": "EXAMPLE",
"SigningCertUrl": "EXAMPLE",
"UnsubscribeUrl": "EXAMPLE",
"MessageAttributes": {
"Test": {
"Type": "String",
"Value": "TestString"
},
"TestBinary": {
"Type": "Binary",
"Value": "TestBinary"
}
}
}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment