datasource.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* global AWS */
  2. define([
  3. 'angular',
  4. 'lodash',
  5. 'kbn',
  6. 'moment',
  7. './queryCtrl',
  8. 'aws-sdk',
  9. ],
  10. function (angular, _, kbn) {
  11. 'use strict';
  12. var module = angular.module('grafana.services');
  13. module.factory('CloudWatchDatasource', function($q, $http, templateSrv) {
  14. function CloudWatchDatasource(datasource) {
  15. this.type = 'cloudwatch';
  16. this.name = datasource.name;
  17. this.supportMetrics = true;
  18. AWS.config.update({ region: datasource.jsonData.region });
  19. this.cloudwatch = new AWS.CloudWatch({
  20. accessKeyId: datasource.jsonData.accessKeyId,
  21. secretAccessKey: datasource.jsonData.secretAccessKey,
  22. });
  23. }
  24. // Called once per panel (graph)
  25. CloudWatchDatasource.prototype.query = function(options) {
  26. var start = convertToCloudWatchTime(options.range.from);
  27. var end = convertToCloudWatchTime(options.range.to);
  28. var queries = [];
  29. _.each(options.targets, _.bind(function(target) {
  30. if (!target.namespace || !target.metricName || _.isEmpty(target.dimensions) || _.isEmpty(target.statistics)) {
  31. return;
  32. }
  33. var query = {};
  34. query.namespace = templateSrv.replace(target.namespace, options.scopedVars);
  35. query.metricName = templateSrv.replace(target.metricName, options.scopedVars);
  36. query.dimensions = _.map(_.keys(target.dimensions), function(key) {
  37. return {
  38. Name: key,
  39. Value: target.dimensions[key]
  40. };
  41. });
  42. query.statistics = _.keys(target.statistics);
  43. query.period = target.period;
  44. var range = (end.getTime() - start.getTime()) / 1000;
  45. // CloudWatch limit datapoints up to 1440
  46. if (range / query.period >= 1440) {
  47. query.period = Math.floor(range / 1440 / 60) * 60;
  48. }
  49. queries.push(query);
  50. }, this));
  51. // No valid targets, return the empty result to save a round trip.
  52. if (_.isEmpty(queries)) {
  53. var d = $q.defer();
  54. d.resolve({ data: [] });
  55. return d.promise;
  56. }
  57. var allQueryPromise = _.map(queries, _.bind(function(query) {
  58. return this.performTimeSeriesQuery(query, start, end);
  59. }, this));
  60. return $q.all(allQueryPromise)
  61. .then(function(allResponse) {
  62. var result = [];
  63. _.each(allResponse, function(response, index) {
  64. var metrics = transformMetricData(response, options.targets[index]);
  65. _.each(metrics, function(m) {
  66. result.push(m);
  67. });
  68. });
  69. return { data: result };
  70. });
  71. };
  72. CloudWatchDatasource.prototype.performTimeSeriesQuery = function(query, start, end) {
  73. var params = {
  74. Namespace: query.namespace,
  75. MetricName: query.metricName,
  76. Dimensions: query.dimensions,
  77. Statistics: query.statistics,
  78. StartTime: start,
  79. EndTime: end,
  80. Period: query.period
  81. };
  82. var d = $q.defer();
  83. this.cloudwatch.getMetricStatistics(params, function(err, data) {
  84. if (err) {
  85. return d.reject(err);
  86. }
  87. return d.resolve(data);
  88. });
  89. return d.promise;
  90. };
  91. CloudWatchDatasource.prototype.performSuggestQuery = function(params) {
  92. var d = $q.defer();
  93. this.cloudwatch.listMetrics(params, function(err, data) {
  94. if (err) {
  95. return d.reject(err);
  96. }
  97. return d.resolve(data);
  98. });
  99. return d.promise;
  100. };
  101. CloudWatchDatasource.prototype.testDatasource = function() {
  102. return this.performSuggestQuery({}).then(function () {
  103. return { status: 'success', message: 'Data source is working', title: 'Success' };
  104. });
  105. };
  106. function transformMetricData(md, options) {
  107. var result = [];
  108. var dimensionPart = JSON.stringify(options.dimensions);
  109. _.each(_.keys(options.statistics), function(s) {
  110. var metricLabel = md.Label + '_' + s + dimensionPart;
  111. var dps = _.map(md.Datapoints, function(value) {
  112. return [value[s], new Date(value.Timestamp).getTime()];
  113. });
  114. dps = _.sortBy(dps, function(dp) { return dp[1]; });
  115. result.push({ target: metricLabel, datapoints: dps });
  116. });
  117. return result;
  118. }
  119. function convertToCloudWatchTime(date) {
  120. return kbn.parseDate(date);
  121. }
  122. return CloudWatchDatasource;
  123. });
  124. });