AWS cloudwatch API canary statuscode 出现失败,即使记录(记录在 cloudwatch 日志中)statusCode 是 200

AWS cloudwatch API canary statuscode comes as failed even the logged(logged in cloudwatch logs) statusCode is 200

我有一个 API 金丝雀设置来测试 API 的可用性。 API 的 statusCode 在 cloudwatch 日志中被跟踪。我正在从 S3 获取文件。这些请求带有 200 statusCode,与 cloudwatch Logs 中的相同。但是在我的 API 测试中,在 cloudwatch 日志中,状态码打印为 200。但在 Canary 页面中,它显示为失败。 请找到随附的金丝雀页面图片

前两个请求是S3请求,其他是我的API请求。

我还附上了 cloudwatch 日志截图

我的 API 金丝雀脚本是,

var synthetics = require('Synthetics');
const log = require('SyntheticsLogger');
const https = require('https');
const http = require('http');
const syntheticsConfiguration = synthetics.getConfiguration();

const AWS = require('aws-sdk');
const s3 = new AWS.S3();

const apiCanaryBlueprint = async function () {
    const verifyRequest = async function (res) {
    return new Promise((resolve, reject) => {
        log.info("status: " + res.statusCode + ' ' + res);
        if (res.statusCode !== 200 && res.statusCode !== 201) {
            log.info("Failed: " + res.statusCode + ' ' + res.statusMessage);
            throw res.statusCode + ' ' + res.statusMessage;
        }
        let responseBody = '';
        res.on('data', (d) => {
            responseBody = d;
            responseBody += d; // tried in this way as well
            log.info("Response2: " + responseBody);
            resolve();
        });
        res.on('end', () => {
            resolve();
        });
    });
}

const getS3Certificate = async function (){
    const certificate = {
        Bucket : 'bucket',
        Key    : 'key',
    };
    const certificates3 = await s3.getObject(certificate).promise()
    return certificates3.Body;
}
const getS3Key = async function(){
    const key = {
        Bucket : 'bucket',
        Key    : 'key',
    };
    const keys3 = await s3.getObject(key).promise()
    return keys3.Body;
}
const S3Certificate = await getS3Certificate()
const S3Key = await getS3Key()
let projectId = Math.floor(Math.random()*1E16);
let applicationID = Math.floor(Math.random()*1E16);
projectId = projectId.toString().match(/.{1,4}/g).join('-');
let subscribedCount = Math.round(Math.random()*1E4);

let requestData = [
    {
        hostname: 'hostname.com',
        method: 'get',
        path: `/api/v1.0/project/123`,
        port: 443,
        protocol: 'https:',
        key:S3Key,
        cert:S3Certificate,
        headers:{"header1":"a"}
    },
    {
        hostname: 'hostname.com',
        method: 'POST',
        path: `/api/v1.0/project/${projectId}`,
        port: 443,
        key:S3Key,
        cert:S3Certificate,
        headers:{"header1":"a"},
        body:JSON.stringify({ "isActive": true, "licenseItems": [...licenseItemsDetails] })
    },
    {
        hostname: 'hostname.com',
        method: 'PUT',
        path: '/api/v1.0/project/canary/licenses',
        port: 443,
        key:S3Key,
        cert:S3Certificate,
        headers:{"header1":"a"},
        body:JSON.stringify({"licenseItems": [...licenseItemsDetails]})
    },
    {
        hostname: 'hostname.com',
        method: 'DELETE',
        path: '/api/v1.0/project/canary/canaryapp_001',
        port: 443,
        key:S3Key,
        cert:S3Certificate,
        headers:{"header1":"a"}
    },
    {
        hostname: 'hostname.com',
        method: 'PUT',
        path: '/api/v1.0/project/canary/state',
        port: 443,
        key:S3Key,
        cert:S3Certificate,
        headers:{"header1":"a"},
        body:JSON.stringify({"isActive": true})
    },
    {
        hostname: 'hostname.com',
        method: 'DELETE',
        path: `/api/v1.0/project/${projectId}`,
        port: 443,
        key:S3key,
        cert:S3Cert,
        headers:{"header1":"a"}
    },
]
requestData.forEach(async (request) => {
    request['headers']['User-Agent'] = [synthetics.getCanaryUserAgentString(), request['headers']['User-Agent']].join(' ');
    // await verifyRequest(request);
    let stepConfig = {
        includeRequestHeaders: true,
        includeResponseHeaders: true,
        restrictedHeaders: ['X-Amz-Security-Token', 'Authorization'],
        includeRequestBody: true,
        includeResponseBody: true
    };
    await synthetics.executeHttpStep('Verify LMS APIs', request, verifyRequest, stepConfig);
})
};
exports.handler = async () => {
    return await apiCanaryBlueprint();
};

在 verifyRequest 方法中,请求数据以数组的形式发送到该方法。 这导致了一个问题。即使我在每次调用时都等待,但我没有在 res.on('end' => {callback})

上获得预期的数据(responseBody 变为空字符串)

所以我用单独的请求和单独的 await 函数更改了我的代码,这解决了问题。

let requestOptionsStep8 = {
    hostname: 'hostname.com',
    method: 'DELETE',
    path: `/api/v1.0/project/projectId`,
    port: 443,
    key:key,
    cert:cert,
    headers:{'Content-Type':'application/json','ALE-LMS-Operation-Id':'a','Accept':'*/*'}
}
let requestOptionsStep9 = {
    hostname: 'hostname.com',
    method: 'PATCH',
    path: `/api/v1.0/project/canary3/canary1`,
    port: 443,
    key:key,
    cert:cert,
    headers:{'Content-Type':'application/json','ALE-LMS-Operation-Id':'a','Accept':'*/*'},
    body:JSON.stringify({JSON body})
}
requestOptionsStep['headers']['User-Agent'] = 
[synthetics.getCanaryUserAgentString(), requestOptionsStep['headers']['User-Agent']].join(' ');    
requestOptionsStep1['headers']['User-Agent'] = 
[synthetics.getCanaryUserAgentString(), requestOptionsStep1['headers']['User-Agent']].join(' ');
let stepConfig1 = {
    includeRequestHeaders: true,
    includeResponseHeaders: true,
    includeRequestBody: true,
    includeResponseBody: true,
    continueOnHttpStepFailure: true
};

await synthetics.executeHttpStep('Verify hostname.com', requestOptionsStep, validateSuccessful, stepConfig1);
await synthetics.executeHttpStep('Verify hostname.com', requestOptionsStep1, validateSuccessful, stepConfig1);