Cloudwatch metrics

Send metrics sent from Cloudwatch to your Coralogix index

Amnon Shahar avatar
Written by Amnon Shahar
Updated over a week ago

This tutorial describes how to import Cloudwatch metrics into Coralogix by namespace and metrics name. The metric can then be uses in Kibana or Elastic Timelion for visualization and correlation with your logs.

  1. Author a nodejs 10.x from scratch

2. Add the following policy to you lambda:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "cloudwatch:GetMetricStatistics",
                "cloudwatch:ListMetrics",
                "cloudwatch:DescribeAlarms"
            ],
            "Resource": "*"
        }
    ]
}

3. Edit the following code inline, make sure you add the 2 files, index.js, and params.js

index.js:

// Load the AWS SDK for Node.js

var AWS = require('aws-sdk');
var cw = new AWS.CloudWatch({apiVersion: '2010-08-01'});
var params = require('./params').params
const https = require('https');
const assert = require('assert');
const appName = process.env.app_name ? process.env.app_name : 'NO_APPLICATION';

assert(process.env.private_key, 'No private key')

exports.handler = async function (event, context,callback) {
AWS.config.update({region: event.region});
var EndTime = new Date;var StartTime = new Date(EndTime - 2*60*1000);
  var getMetricStatistics = function getMetricStatistics(param)
{
  param.StartTime = StartTime;
  param.EndTime = EndTime;
   return new Promise(function(resolve, reject){
        cw.getMetricStatistics(param,function(err,data){
            if(err){
                  console.log(err);
                  reject(err);
            }
            else{
                  resolve(data)
            }
        })
  })
}

var postToCoralogix = function postToCoralogix(parsedEvents) {
   return new Promise(function(resolve, reject){
        try {
            var options = {
                hostname: 'api.coralogix.com',
                port: 443,
                path: '/api/v1/logs',
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                        }
                    };
            var req = https.request(options, function (res) {
                res.setEncoding('utf8');
                res.on('data', function (body) {
                    resolve(null)
                });
            });
            req.on('error', function (e) {
                console.log('problem with request: ' + e.message);
                reject(e.message);
            });
            // write data to request body
            req.write(JSON.stringify(parsedEvents));
            req.end();
        } catch (ex) {
            console.log(ex);
            reject(ex);
        }
  })

    }

for (var i = 0; i < params.length; i++) {
  try{
    var result = await getMetricStatistics(params[i])
    var logEntries = []
    console.log(result)
    for (var j = 0; j < result.Datapoints.length; j++) {
      logEntries.push({
            "timestamp": new Date(result.Datapoints[j].Timestamp).getTime(),
            "severity": 3,
            "text": {Datapoints:result.Datapoints[j],MetricName:params[i].MetricName,Period:params[i].Period,Dimension:params[i].Dimensions[0]}
        })
    }
    if(logEntries.length > 0)
    {
        const events = {
        "privateKey": process.env.private_key,
        "applicationName": appName,
        "subsystemName": params[i].Namespace,
        "logEntries": logEntries}
        console.log(events)
        var error = await  postToCoralogix(events)
        error == null ? console.log('logs sent to coralogix') : console.log('error while sending events to coralogix',error)
    }
  }
  catch(err){
   console.log(err)
  }
 }
};

params.js:

const statistics = ['SampleCount', 'Average', 'Sum', 'Minimum', 'Maximum']
const period = 60
exports.params = [{
  Dimensions: [
        {
      Name: 'FunctionName',
      Value: 's3ToCoralogix'
    }
  ],
  Period: period,
  Statistics: statistics,
  MetricName: 'Invocations',
  Namespace: 'AWS/Lambda'
},{
  Dimensions: [
        {
      Name: 'FunctionName',
      Value: 's3ToCoralogix'
    }
  ],
  Period: period,
  Statistics: statistics,
  MetricName: 'Duration',
  Namespace: 'AWS/Lambda'
},{
  Dimensions: [
        {
      Name: 'FunctionName',
      Value: 'CWevents'
    }
  ],
  Period: period,
  Statistics: statistics,
  MetricName: 'Duration',
  Namespace: 'AWS/Lambda'
}];

4. Configure the params.js

params is an array of parameters that define a call to Cloudwatch, each param needs to have: Namespace, MetricName, Statistics, and Dimensions.

Namespace:

is a container for metrics like AWS/ApiGateway, AWS/Lambda etc... a list of all AWS namespaces can be found here:

MetricName:

each Namespace has it's own available metrics, for example, AWS/Lambda has Duration, Invocation, Error etc...

Dimensions:

Each namespace has it's own dimensions, for example, AWS/Lambda has FunctionName

Period:

Is the bin size to aggregate the metrics, the default and the minimum is 60 seconds

Statistics:

Which kind of statistics to query, the default is: 'SampleCount', 'Average', 'Sum', 'Minimum', 'Maximum'

Here is an example to get metrics from AWS/Lambda with name CW events:

{
  Dimensions: [
        {
      Name: 'FunctionName',
      Value: 'CWevents'
    }
  ],
  Period: period,
  Statistics: statistics,
  MetricName: 'Duration',
  Namespace: 'AWS/Lambda'
}

5. Add Coralogix's mandatory environment variables, private_key and applicationName (e.g test, dev, prod) 

6. *Important* Increase the runtime timeout and memory to 2 min, and 1024mb

7. Add Cloudwatch events trigger: 

8.  Configure the trigger, please choose Schedule expression with rate(2 minutes)

That’s all! you should have your CW metrics streaming to Coralogix now. Not seeing events yet? ping us on our in-app chat or send an email to [email protected]. 

Did this answer your question?