如何获取 CloudWatch 代理和指标过滤器以报告维度
How to get the CloudWatch Agent and Metric Filters to Report Dimensions
设置
EC2 实例上的 CloudWatch 代理 运行 向 CloudWatch 报告审计日志。 CloudWatch 中的指标筛选器会在报告日志时为成功登录、失败登录等创建指标。
问题
通过指标筛选器创建的指标不会分配维度,因此我无法通过 InstanceId 查询 CloudWatch 来获取一组指标统计信息。这将非常有用,因为我想知道每台机器而不是每个日志组的审计指标。
评论
使用 put-metric-data
命令附加尺寸非常容易。我能够使用 InstanceId 的维度标记指标,然后使用 get-metric-statistics
仅检索这些指标。使用指标过滤器 + CloudWatch 代理设置是否无法实现这种功能?可能的解决方法是什么?
因此,您需要做的是创建一个 lambda,将事件源设置为您要为其创建指标的日志组。我创建了度量对象来检查每个日志的特定模式。下面的代码是您需要做的事情的要点。我不得不撕掉一些不适用的东西。如果有人尝试过,请告诉我它是否有问题。
我创建了一个 lambda(注意指标数组):
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;
设置
EC2 实例上的 CloudWatch 代理 运行 向 CloudWatch 报告审计日志。 CloudWatch 中的指标筛选器会在报告日志时为成功登录、失败登录等创建指标。
问题
通过指标筛选器创建的指标不会分配维度,因此我无法通过 InstanceId 查询 CloudWatch 来获取一组指标统计信息。这将非常有用,因为我想知道每台机器而不是每个日志组的审计指标。
评论
使用 put-metric-data
命令附加尺寸非常容易。我能够使用 InstanceId 的维度标记指标,然后使用 get-metric-statistics
仅检索这些指标。使用指标过滤器 + CloudWatch 代理设置是否无法实现这种功能?可能的解决方法是什么?
因此,您需要做的是创建一个 lambda,将事件源设置为您要为其创建指标的日志组。我创建了度量对象来检查每个日志的特定模式。下面的代码是您需要做的事情的要点。我不得不撕掉一些不适用的东西。如果有人尝试过,请告诉我它是否有问题。
我创建了一个 lambda(注意指标数组):
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;