如何使CloudWatch代理和指标筛选器报告维度

时间:2015-10-15 18:08:40

标签: javascript amazon-web-services logging amazon-cloudwatch

设置

在EC2实例上运行的CloudWatch代理将审核日志报告给CloudWatch。 CloudWatch中的度量标准筛选器会在报告日志时创建成功登录,登录失败等指标。

问题

通过指标筛选器创建的指标不会分配维度,因此我无法通过InstanceId查询CloudWatch获取一组指标统计信息。这非常有用,因为我想知道每台机器的审核指标而不是每个日志组。

评论

使用put-metric-data命令轻松附加维度。我可以使用InstanceId的维度标记指标,然后使用get-metric-statistics仅检索这些指标。使用度量标准过滤器+ CloudWatch代理设置无法实现此类功能吗?什么是可能的解决方法?

1 个答案:

答案 0 :(得分:2)

所以你需要做的是创建一个lambda,它将事件源设置为你想要为其创建指标的日志组。我创建了度量对象,可以检查每个日志中的某些模式。下面的代码是您需要做的事情的要点。我不得不撕掉一些不适用的东西。如果有人试过,请告诉我它是否有问题。

我创建了一个lambda(注意metrics数组):

var zlib = require('zlib');
var Q = require('q');
var cloudwatchAgent = require('cloudwatchAgent');

var metrics = [
{
    "name": "SuccessfulLogins",
    "patterns": ["session opened for user", "successful logon"],
    "dimensionName":"HostName",
    "namespace":"UserStats"
}];

exports.handler = function (event, context) {
var payload = new Buffer(event.awslogs.data, 'base64');

zlib.gunzip(payload, function (e, result) {
if (e) {
  context.fail(e);
} else {
  result = JSON.parse(result.toString('utf-8'));
  console.log('Decoded payload: ', JSON.stringify(result));

metrics.forEach(function (metric) {
        promises.push(cloudwatchAgent.processMetric(metric, result.logStream, result.logEvents));
  });

Q.all(promises).fail(function (error) {
        context.fail('Error processing log events: ' + error);
  }).done(function () {
        context.succeed('Successfully processed log events.');
  });
  }
 });
};

lambda调用此函数:

var sdk = require('aws-sdk');
var Q = require('q');
var cloudwatch = new sdk.CloudWatch();

function processMetric(metric, streamName, logs) {
console.log('Checking metric ' + metric.name + ' against these patterns:' + metric.patterns.toString());
var deferred = Q.defer();
var value = 0;

logs.forEach(function (logEvent) {
metric.patterns.forEach(function(pattern) {
    if(logEvent.message.toLowerCase().indexOf(pattern) > -1) {
    value++;
    }
});
});

var params = {
  MetricData: [{
      MetricName: metric.name,
      Dimensions: [{
          Name: metric.dimensionName,
          Value: streamName
        }],
      Timestamp: new Date(),
      Value: value
    }],
  Namespace: metric.namespace
};

cloudwatch.putMetricData(params, function (err, data) {
  if (err) {
    console.log(err, err.stack);
    deferred.reject(err);
  } else {
    console.log('Successfully created metric for ' + metric.name + ' with value ' + value);
    deferred.resolve(data);
  }
});

return deferred.promise;
}

module.exports.processMetric = processMetric;