Node.js Cloudwatch putMetricData挂在Lambda内

Node.js Cloudwatch putMetricData挂在Lambda内,node.js,aws-lambda,serverless-framework,Node.js,Aws Lambda,Serverless Framework,我正在尝试设置一个lambda来定期查询我们的队列服务,并向Cloudwatch报告消息计数,以便我们可以监视队列大小 当使用无服务器框架在本地调用时,这些代码都可以工作。但是,当Lambda本身触发时,对AWS Cloudwatch的请求永远不会完成,Lambda超时 import {Callback, Context, Handler} from 'aws-lambda'; import {CloudWatch} from 'aws-sdk'; const queueReporter: H

我正在尝试设置一个lambda来定期查询我们的队列服务,并向Cloudwatch报告消息计数,以便我们可以监视队列大小

当使用无服务器框架在本地调用时,这些代码都可以工作。但是,当Lambda本身触发时,对AWS Cloudwatch的请求永远不会完成,Lambda超时

import {Callback, Context, Handler} from 'aws-lambda';
import {CloudWatch} from 'aws-sdk';

const queueReporter: Handler = async (event: any, context: Context, callback: Callback) => {
    // TRUNCATED - GET Queue counts

    const cloudwatch = new CloudWatch({region: 'eu-west-1'})
    const date = new Date();

    // convert queue data into cloudwatch metrics
    const metricData: CloudWatch.Types.MetricData = queues.map((queue): CloudWatch.Types.MetricDatum => ({
        MetricName: queue.name,
        Timestamp: date,
        Unit: 'Count',
        Value: queue.messages,
    }));

    console.log('add metrics'); // This prints out

    return await cloudwatch.putMetricData(
        {
            MetricData: metricData,
            Namespace: 'Queue_Messages'
        }).promise().then((response) => {
            const result = JSON.stringify(response);

            console.log(result); // this does not print out

            callback(null, result);

            return result;
        }
    );
};
我怀疑这是某种权限问题,因为我在本地看到了类似的问题,当时我没有在笔记本电脑上配置访问密钥。
但政策包括了这一声明,我认为这应该足够了

{
    "Action": [
        "cloudwatch:PutMetricData"
    ],
    "Resource": "*",
    "Effect": "Allow"
}
为了访问队列的api,已将此lambda添加到VPC和安全组中。但是,此安全组没有传出限制,只有传入限制


任何帮助都将不胜感激

我要看的第一件事是简化异步处理的不匹配。您正在等待调用lambda回调的承诺,但lambda函数定义为异步,因此AWS希望返回承诺。您应该将lambda定义为异步并忽略回调,或者在不使用异步的情况下定义lambda并使用回调

试试这个:

const queueReporter: Handler = async (event: any, context: Context) => {
    // TRUNCATED - GET Queue counts

    const cloudwatch = new CloudWatch({region: 'eu-west-1'})
    const date = new Date();

    // convert queue data into cloudwatch metrics
    const metricData: CloudWatch.Types.MetricData = queues.map((queue): CloudWatch.Types.MetricDatum => ({
        MetricName: queue.name,
        Timestamp: date,
        Unit: 'Count',
        Value: queue.messages,
    }));

    const response = await cloudwatch.putMetricData({
            MetricData: metricData,
            Namespace: 'Queue_Messages'
    }).promise();

    const result = JSON.stringify(response);
    console.log(result); 
    return result;
};

您需要向监控服务添加VPC端点,以避免超时并连接到CloudWatch

然后,您可以在SDK配置中提及端点的私有DNS名称

var cloudwatch = new AWS.CloudWatch({
    apiVersion: '2010-08-01',
    endpoint: `https://monitoring.${process.env.REGION}.amazonaws.com`,
    region: process.env.REGION
});

谢谢你的建议。我已经厌倦了这两种形式(只是异步/等待,只是回调),没有任何乐趣。每次尝试6秒后,lambda就超时了。lambda超时是多少?可能会增加吗?