编写 Canary 脚本 - Amazon CloudWatch
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

编写 Canary 脚本

以下部分介绍了如何编写 Canary 脚本以及如何将 Canary 与其他 AWS 服务集成。

从头开始创建 Synthetics Canary

这里是一个极简 Synthetics Canary 脚本示例。此脚本将成功通过一次运行,并返回一个字符串。要查看失败的 Canary 示例,请将 let fail = false; 更改为 let fail = true;

您必须为 Canary 脚本定义入口点函数。要查看如何将文件上传到指定作为 Canary ArtifactS3Location 的 Amazon S3 位置,请在 /tmp 文件夹下创建这些文件。脚本运行后,将“通过/失败”状态和持续时间指标发布到 CloudWatch,并将 /tmp 下的文件上传到 S3。

const basicCustomEntryPoint = async function () { // Insert your code here // Perform multi-step pass/fail check // Log decisions made and results to /tmp // Be sure to wait for all your code paths to complete // before returning control back to Synthetics. // In that way, your canary will not finish and report success // before your code has finished executing // Throw to fail, return to succeed let fail = false; if (fail) { throw "Failed basicCanary check."; } return "Successfully completed basicCanary checks."; }; exports.handler = async () => { return await basicCustomEntryPoint(); };

接下来,我们将扩展脚本以使用 Synthetics 日志记录并使用 AWS 开发工具包进行调用。出于演示目的,此脚本将创建 Amazon DynamoDB 客户端并调用 DynamoDB listTables API。它会记录对请求的响应,并根据请求是否成功来记录通过还是失败。

如果您有多个 .js 文件,或者您的脚本依赖于某个依赖项,则您可以将它们打包到包含文件夹结构 nodejs/node_modules/myCanaryFilename.js file and other folders and files 的单个 ZIP 文件中。

请务必将您的 Canary 脚本入口点设置为 myCanaryFilename.handler,以匹配脚本入口点的文件名。

const log = require('SyntheticsLogger'); const AWS = require('aws-sdk'); // Require any dependencies that your script needs // Bundle additional files and dependencies into a .zip file with folder structure // nodejs/node_modules/additional files and folders const basicCustomEntryPoint = async function () { log.info("Starting DynamoDB:listTables canary."); let dynamodb = new AWS.DynamoDB(); var params = {}; let request = await dynamodb.listTables(params); try { let response = await request.promise(); log.info("listTables response: " + JSON.stringify(response)); } catch (err) { log.error("listTables error: " + JSON.stringify(err), err.stack); throw err; } return "Successfully completed DynamoDB:listTables canary."; }; exports.handler = async () => { return await basicCustomEntryPoint(); };

更改现有 Puppeteer 脚本以将其用作 Synthetics Canary

本节介绍如何对 Puppeteer 脚本进行修改,以将其作为 Synthetics Canary 脚本运行。有关 Puppeteer 的更多信息,请参阅 Puppeteer API v1.14.0

我们从这个示例 Puppeteer 开始:

const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://example.com'); await page.screenshot({path: 'example.png'}); await browser.close(); })();

转换步骤如下:

  • 创建和导出 handler 函数。处理程序是脚本的入口点函数。

    const basicPuppeteerExample = async function () {}; exports.handler = async () => { return await basicPuppeteerExample(); };
  • 使用 Synthetics 依赖项。

    var synthetics = require('Synthetics');
  • 使用 Synthetics.getPage 函数获取 Puppeteer Page 对象。

    const page = await synthetics.getPage();

    Synthetics.getPage 函数返回的页面对象指示需要记录 page.on requestresponserequestfailed 事件。Synthetics 还为页面上的请求和响应设置 HAR 文件生成,并将 Canary ARN 添加到页面上的传出请求的 user-agent 标头。

该脚本现已准备好作为 Synthetics Canary 运行。更新的脚本如下:

var synthetics = require('Synthetics'); // Synthetics dependency const basicPuppeteerExample = async function () { const page = await synthetics.getPage(); // Get instrumented page from Synthetics await page.goto('https://example.com'); await page.screenshot({path: '/tmp/example.png'}); // Write screenshot to /tmp folder }; exports.handler = async () => { // Exported handler function return await basicPuppeteerExample(); };

将您的 Canary 与其他 AWS 服务集成

所有 Canary 都可以使用 AWS 开发工具包库。在编写 Canary 时,您可以使用此库将 Canary 与其他 AWS 服务集成。

为此,您需要将以下代码添加到 Canary 中。 AWS Secrets Manager 用作集成的服务示例。

  • 导入 AWS 开发工具包。

    const AWS = require('aws-sdk');
  • 为要集成的 AWS 服务创建客户端。

    const secretsManager = new AWS.SecretsManager();
  • 使用客户端对该服务进行 API 调用。

    var params = { SecretId: secretName }; return await secretsManager.getSecretValue(params).promise();

以下 Canary 脚本代码段详细演示了与 Secrets Manager 的集成。

var synthetics = require('Synthetics'); const log = require('SyntheticsLogger'); const AWS = require('aws-sdk'); const secretsManager = new AWS.SecretsManager(); const getSecrets = async (secretName) => { var params = { SecretId: secretName }; return await secretsManager.getSecretValue(params).promise(); } const secretsExample = async function () { // Fetch secrets var secrets = await getSecrets("secretname") // Use secrets log.info("SECRETS: " + JSON.stringify(secrets)); }; exports.handler = async () => { return await secretsExample(); };