Commit 61e2554a authored by Paweł Barszcz's avatar Paweł Barszcz

Code for the second post of the series

parent a92a127f
......@@ -9,5 +9,7 @@ Structure
-----------
* [step-1]( step-1/ ) – scripts helpful while reading
[Lambda + Slack = health-check #1 — konfiguracja]( http://timbercode.pl/blog/2017/03/25/lambda-slack-health-check-1/ )
[Lambda + Slack = health-check #1 — konfiguracja]( http://timbercode.pl/blog/2017/03/25/lambda-slack-health-check-1/ )
* [step-2]( step-2/ ) – scripts helpful while reading
[Lambda + Slack = health-check #2 — periodyczna funkcja]( http://timbercode.pl/blog/2017/04/03/lambda-slack-health-check-2/ )
\ No newline at end of file
lambda-slack-example / step-2
=============================
In this directory you can find scripts helpful while reading
[Lambda + Slack = health-check #2 — periodyczna funkcja]( http://timbercode.pl/blog/2017/04/03/lambda-slack-health-check-2/ )
blog post (polish language).
AWS Lambda function
-------------------
You can find code of the function in
file [simple-heatlh-check.lambda.js]( simple-health-check.lambda.js ).
Copy it's all content and paste on AWS Lambda as function body.
Remember to define environment variables:
* `SLACK_WEBHOOK` - your Slack webhook URL
* `SLACK_CHANNEL` - name of the Slack channel you want to post to
* `HEALTH_CHECK_URL` - URL of the health-check of your system;
preferably `GET` endpoint which responds with `200 OK` and
it's body has a JSON format
* `SYSTEM_NAME` - "label" for you system to be used in messages
post to Slack
\ No newline at end of file
'use strict';
const systemName = process.env.SYSTEM_NAME;
const healthCheckUrl = process.env.HEALTH_CHECK_URL;
const slackWebhook = process.env.SLACK_WEBHOOK;
const slackChannel = process.env.SLACK_CHANNEL;
exports.handler = (event, context, callback) => {
checkSystemHealth()
.then(({ error, isHealthy, healthDetails }) => {
if (error) {
return sendMessageToSlackChannel({
message : healthCheckFailureSlackMessage({ error : error })
}).then(() => ({
lambdaFailure : error
}));
}
if (!isHealthy) {
return sendMessageToSlackChannel({
message : systemIsUnhealthySlackMessage({ details : healthDetails })
}).then(() => ({
lambdaSuccess : 'system is NOT healthy'
}));
}
return {
lambdaSuccess : 'system is healthy'
};
})
.catch(error => ({
lambdaFailure : error
}))
.then(({ lambdaSuccess, lambdaFailure }) => {
if (lambdaFailure) callback(lambdaFailure, null);
else callback(null, lambdaSuccess)
});
};
function checkSystemHealth() {
return makeHttpsRequest({
method : 'GET',
url : healthCheckUrl
}).then(response => ({
isHealthy : response.status === 200,
healthDetails : {
status : response.status,
body : prettified(response.body)
}
})).catch(error => ({
error : error
}));
}
function prettified(text) {
let asJson;
try {
asJson = JSON.parse(text)
} catch (error) {
return text;
}
const indentationSpaces = 2;
return JSON.stringify(asJson, null, indentationSpaces);
}
function sendMessageToSlackChannel({ message }) {
const requestData = JSON.stringify({
channel : slackChannel,
text : message
});
return makeHttpsRequest({
method : 'POST',
url : slackWebhook,
data : requestData,
headers : {
'Content-Type' : 'application/json',
'Content-Length' : requestData.length
}
}).then(response => {
if (response.status < 200 || response.status >= 300) {
return Promise.reject(
`Slack notification request returned ${response.status} ` +
`instead of 2xx with body: ${response.body}`);
}
});
}
function healthCheckFailureSlackMessage({ error }) {
return `:interrobang: failed to check health of ${systemName} :interrobang:\n` +
`\`\`\`\n` +
`${error}` +
`\`\`\``
}
function systemIsUnhealthySlackMessage({ details }) {
details = details || {};
return `:fire: ${systemName} is *<${healthCheckUrl}|unhealthy>* :fire:\n` +
`\`\`\`\n` +
`status : ${details.status}\n` +
`body :\n` +
`${details.body}` +
`\`\`\``;
}
function makeHttpsRequest({ method, url, headers = {}, data }) {
return new Promise((resolve, reject) => {
const parsedUrl = require('url').parse(url);
const nativeHttpLibrary = parsedUrl.protocol === 'https:'
? require('https')
: require('http');
const request = nativeHttpLibrary.request({
hostname : parsedUrl.hostname,
port : parsedUrl.protocol === 'https:' ? 443 : 80,
path : parsedUrl.path,
method : method,
headers : headers
}, response => {
response.setEncoding('utf8');
let responseBody = '';
response.on('error', (error) => reject(error));
response.on('data', (chunk) => responseBody = responseBody + chunk);
response.on('end', () => resolve({
status : response.statusCode,
body : responseBody
}));
});
request.on('error', (error) => reject(error));
if (data) {
request.write(data);
}
request.end();
});
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment