Cloudwatch Synthetic Canaries
What are canaries?
Canaries are designed to integrate in your cloudwatch infrastructure to continually verify customer experience even when your applications aren’t experiencing real traffic.
Canaries are Node.js scripts. They create Lambda functions in your account that use Node.js as a framework. Canaries can use the Puppeteer Node.js library to perform functions on your applications. Canaries work over HTTP and HTTPS protocols.
Dashboard and Canary setup
The following canary was created through the dashboard and the nodeJS script was generated by the AWS dashboard.
How difficult is this to build?
Generally, building the first user journey is easy with the GUI workflow wizard.
However, the synthetics library is quite simple as far as standard functions go. You can click, verify text, wait, navigate, input text and click-navigate. There are additional plugins for logging.
The API and the CLI
You can review the CLI documents here. https://docs.aws.amazon.com/cli/latest/reference/synthetics/index.html
The additional library functions can be accessed here. https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Function_Library.html
Template
var synthetics = require('Synthetics');
const log = require('SyntheticsLogger');
const flowBuilderBlueprint = async function () {
// INSERT URL here
let url = "https://yourdomainhere.com";
let page = await synthetics.getPage();
// Navigate to the initial url
await synthetics.executeStep('navigateToUrl', async function (timeoutInMillis = 15000) {
await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis});
});
// Execute customer steps
await synthetics.executeStep('customerActions', async function () {
await page.type("input[id='email-address']", "youremailaddress");
try {
await synthetics.takeScreenshot("input", 'result');
} catch(ex) {
synthetics.addExecutionError('Unable to capture screenshot.', ex);
}
await page.type("input[id='password']", "yourrealpassword");
try {
await synthetics.takeScreenshot("input", 'result');
} catch(ex) {
synthetics.addExecutionError('Unable to capture screenshot.', ex);
}
await page.waitForSelector("[id='some-sign-in-button']", { timeout: 15000 });
await page.click("[id='some-sign-in-button']");
try {
await synthetics.takeScreenshot("click", 'result');
} catch(ex) {
synthetics.addExecutionError('Unable to capture screenshot.', ex);
}
});
};
exports.handler = async () => {
return await flowBuilderBlueprint();
};