Commit 1626982a by Mitsuhiro Tanda

add CloudWatch Annotation

parent 6beb9be4
......@@ -209,6 +209,74 @@ function (angular, _) {
return $q.when([]);
};
CloudWatchDatasource.prototype.performDescribeAlarmsForMetric = function(region, namespace, metricName, dimensions, statistic, period) {
return this.awsRequest({
region: region,
action: 'DescribeAlarmsForMetric',
parameters: { namespace: namespace, metricName: metricName, dimensions: dimensions, statistic: statistic, period: period }
});
};
CloudWatchDatasource.prototype.performDescribeAlarmHistory = function(region, alarmName, startDate, endDate) {
return this.awsRequest({
region: region,
action: 'DescribeAlarmHistory',
parameters: { alarmName: alarmName, startDate: startDate, endDate: endDate }
});
};
CloudWatchDatasource.prototype.annotationQuery = function(annotation, range) {
var region = templateSrv.replace(annotation.region);
var namespace = templateSrv.replace(annotation.namespace);
var metricName = templateSrv.replace(annotation.metricName);
var dimensionPart = templateSrv.replace(annotation.dimensions);
var statistic = templateSrv.replace(annotation.statistic) || '';
var period = annotation.period || '300';
if (!region || !namespace || !metricName) { return $q.when([]); }
var dimensions = {};
if (!_.isEmpty(dimensionPart)) {
_.each(dimensionPart.split(','), function(v) {
var t = v.split('=');
if (t.length !== 2) {
throw new Error('Invalid query format');
}
dimensions[t[0]] = t[1];
});
dimensions = convertDimensionFormat(dimensions);
}
period = parseInt(period, 10);
var d = $q.defer();
var self = this;
this.performDescribeAlarmsForMetric(region, namespace, metricName, dimensions, statistic, period).then(function(alarms) {
var eventList = [];
var start = convertToCloudWatchTime(range.from);
var end = convertToCloudWatchTime(range.to);
_.each(alarms.MetricAlarms, function(alarm) {
self.performDescribeAlarmHistory(region, alarm.AlarmName, start, end).then(function(history) {
_.each(history.AlarmHistoryItems, function(h) {
var event = {
annotation: annotation,
time: Date.parse(h.Timestamp),
title: h.AlarmName,
tags: [h.HistoryItemType],
text: h.HistorySummary
};
eventList.push(event);
});
d.resolve(eventList);
});
});
});
return d.promise;
};
CloudWatchDatasource.prototype.testDatasource = function() {
/* use billing metrics for test */
var region = this.defaultRegion;
......
......@@ -10,4 +10,8 @@ function (angular) {
return {controller: 'CloudWatchQueryCtrl', templateUrl: 'app/plugins/datasource/cloudwatch/partials/query.editor.html'};
});
module.directive('annotationsQueryEditorCloudwatch', function() {
return {templateUrl: 'app/plugins/datasource/cloudwatch/partials/annotations.editor.html'};
});
});
<div class="editor-row">
<div class="section">
<h5>Metric name</h5>
<div class="editor-option">
<input type="text" class="span6" ng-model='currentAnnotation.metricName' placeholder="CPUUtilization"></input>
</div>
</div>
</div>
<div class="editor-row">
<div class="section">
<h5>Field mappings</h5>
<div class="editor-option">
<label class="small">Region</label>
<input type="text" class="input-small" ng-model='currentAnnotation.region' placeholder="us-east-1"></input>
</div>
<div class="editor-option">
<label class="small">Namespace</label>
<input type="text" class="input-small" ng-model='currentAnnotation.namespace' placeholder="AWS/EC2"></input>
</div>
<div class="editor-option">
<label class="small">Dimensions</label>
<input type="text" class="input-small" ng-model='currentAnnotation.dimensions' placeholder="InstanceId=i-12345678"></input>
</div>
<div class="editor-option">
<label class="small">Statistic</label>
<input type="text" class="input-small" ng-model='currentAnnotation.statistic' placeholder="Average"></input>
</div>
<div class="editor-option">
<label class="small">Period</label>
<input type="text" class="input-small" ng-model='currentAnnotation.period' placeholder="300"></input>
</div>
</div>
</div>
......@@ -12,5 +12,6 @@
"query": "app/plugins/datasource/cloudwatch/partials/query.editor.html"
},
"metrics": true
"metrics": true,
"annotations": true
}
......@@ -2,6 +2,7 @@
///<amd-dependency path="test/specs/helpers" name="helpers" />
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
import moment = require('moment');
declare var helpers: any;
......@@ -189,4 +190,50 @@ describe('CloudWatchDatasource', function() {
});
});
describe('When performing annotationQuery', function() {
var annotation = {
region: 'us-east-1',
namespace: 'AWS/EC2',
metricName: 'CPUUtilization',
dimensions: 'InstanceId=i-12345678'
};
var alarmResponse = {
MetricAlarms: [
{
AlarmName: 'test_alarm_name'
}
]
};
var historyResponse = {
AlarmHistoryItems: [
{
Timestamp: '2015-01-01T00:00:00.000Z',
HistoryItemType: 'StateUpdate',
AlarmName: 'test_alarm_name',
HistoryData: '{}',
HistorySummary: 'test_history_summary'
}
]
};
beforeEach(function() {
ctx.backendSrv.datasourceRequest = function(params) {
switch (params.data.action) {
case 'DescribeAlarmsForMetric':
return ctx.$q.when({data: alarmResponse});
break;
case 'DescribeAlarmHistory':
return ctx.$q.when({data: historyResponse});
break;
}
};
});
it('should return annotation list', function(done) {
ctx.ds.annotationQuery(annotation, {from: moment(1443438674760), to: moment(1443460274760)}).then(function(result) {
expect(result[0].title).to.be('test_alarm_name');
expect(result[0].text).to.be('test_history_summary');
done();
});
ctx.$rootScope.$apply();
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment