Search code examples
node.jsamazon-web-servicesaws-lambdametrics

Node.JS in AWS Lambda does not put custom metric data in Cloudwatch


I have the following code snippet

const AWS = require('aws-sdk');
exports.handler = async (event, context) => {
  // Set the region 
  console.log('line1');
  AWS.config.update({region: 'cn-north-1'});
  console.log('line2');

  // Create CloudWatch service object
  var cw = new AWS.CloudWatch({apiVersion: '2010-08-01'});
  console.log('line3');

  //Create parameters JSON for putMetricData
  var params = {
    MetricData: [
      {
        MetricName: 'PAGES_VISITED',
        Dimensions: [
          {
            Name: 'UNIQUE_PAGES',
            Value: 'URLS'
          },
        ],
        Unit: 'None',
        Value: 1.0
      },
    ],
    Namespace: 'SITE/TRAFFIC'
  };
  console.log('line4');

  if (cw){
    console.log('cw is not null');
  }else{
    console.log('cw is null');
  }

  cw.putMetricData(params, function(err, data) {
    console.log('callback function');
    if (err) {
      console.log("Error", err);
    } else {
      console.log("Success", JSON.stringify(data));
    }
  });
  console.log('line5');

  return "the result";
};

After I tested it in the Lambda console. I can see those Cloudwatch logs being created. However I cannot see the Cloudwatch Metric being created.

I've set the role of the Lambda to have the policy Cloudwatch:PutMetricData


Solution

  • The reason it doesnt work is because you have no callback but have declared the function async.

    Option 1: Remove the 'async' on line 2 and it will work.

    exports.handler = (event,context) => {...
    

    Option 2: Leave it async, add callback as parameter, and call the callback at end of your lambda function. Line 2 needs a callback as a parameter:

    exports.handler = async (event,context,callback) => {...
    

    Then add this at bottom:

    callback(null, true);