queryCtrl.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. define([
  2. 'angular',
  3. 'lodash',
  4. ],
  5. function (angular, _) {
  6. 'use strict';
  7. var module = angular.module('grafana.controllers');
  8. /* jshint -W101 */
  9. var supportedRegion = [
  10. 'us-east-1',
  11. 'us-west-2',
  12. 'us-west-1',
  13. 'eu-west-1',
  14. 'eu-central-1',
  15. 'ap-southeast-1',
  16. 'ap-southeast-2',
  17. 'ap-northeast-1',
  18. 'sa-east-1',
  19. ];
  20. var supportedMetrics = {
  21. "AWS/AutoScaling": [
  22. "GroupMinSize", "GroupMaxSize", "GroupDesiredCapacity", "GroupInServiceInstances", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"
  23. ],
  24. "AWS/Billing": [
  25. "EstimatedCharges"
  26. ],
  27. "AWS/CloudFront": [
  28. "Requests", "BytesDownloaded", "BytesUploaded", "TotalErrorRate", "4xxErrorRate", "5xxErrorRate"
  29. ],
  30. "AWS/CloudSearch": [
  31. "SuccessfulRequests", "SearchableDocuments", "IndexUtilization", "Partitions"
  32. ],
  33. "AWS/DynamoDB": [
  34. "ConditionalCheckFailedRequests", "ConsumedReadCapacityUnits", "ConsumedWriteCapacityUnits", "OnlineIndexConsumedWriteCapacity", "OnlineIndexPercentageProgress", "OnlineIndexThrottleEvents", "ProvisionedReadCapacityUnits", "ProvisionedWriteCapacityUnits", "ReadThrottleEvents", "ReturnedItemCount", "SuccessfulRequestLatency", "SystemErrors", "ThrottledRequests", "UserErrors", "WriteThrottleEvents"
  35. ],
  36. "AWS/ElastiCache": [
  37. "CPUUtilization", "SwapUsage", "FreeableMemory", "NetworkBytesIn", "NetworkBytesOut",
  38. "BytesUsedForCacheItems", "BytesReadIntoMemcached", "BytesWrittenOutFromMemcached", "CasBadval", "CasHits", "CasMisses", "CmdFlush", "CmdGet", "CmdSet", "CurrConnections", "CurrItems", "DecrHits", "DecrMisses", "DeleteHits", "DeleteMisses", "Evictions", "GetHits", "GetMisses", "IncrHits", "IncrMisses", "Reclaimed",
  39. "CurrConnections", "Evictions", "Reclaimed", "NewConnections", "BytesUsedForCache", "CacheHits", "CacheMisses", "ReplicationLag", "GetTypeCmds", "SetTypeCmds", "KeyBasedCmds", "StringBasedCmds", "HashBasedCmds", "ListBasedCmds", "SetBasedCmds", "SortedSetBasedCmds", "CurrItems"
  40. ],
  41. "AWS/EBS": [
  42. "VolumeReadBytes", "VolumeWriteBytes", "VolumeReadOps", "VolumeWriteOps", "VolumeTotalReadTime", "VolumeTotalWriteTime", "VolumeIdleTime", "VolumeQueueLength", "VolumeThroughputPercentage", "VolumeConsumedReadWriteOps",
  43. ],
  44. "AWS/EC2": [
  45. "CPUCreditUsage", "CPUCreditBalance", "CPUUtilization", "DiskReadOps", "DiskWriteOps", "DiskReadBytes", "DiskWriteBytes", "NetworkIn", "NetworkOut", "StatusCheckFailed", "StatusCheckFailed_Instance", "StatusCheckFailed_System"
  46. ],
  47. "AWS/ELB": [
  48. "HealthyHostCount", "UnHealthyHostCount", "RequestCount", "Latency", "HTTPCode_ELB_4XX", "HTTPCode_ELB_5XX", "HTTPCode_Backend_2XX", "HTTPCode_Backend_3XX", "HTTPCode_Backend_4XX", "HTTPCode_Backend_5XX", "BackendConnectionErrors", "SurgeQueueLength", "SpilloverCount"
  49. ],
  50. "AWS/ElasticMapReduce": [
  51. "CoreNodesPending", "CoreNodesRunning", "HBaseBackupFailed", "HBaseMostRecentBackupDuration", "HBaseTimeSinceLastSuccessfulBackup", "HDFSBytesRead", "HDFSBytesWritten", "HDFSUtilization", "IsIdle", "JobsFailed", "JobsRunning", "LiveDataNodes", "LiveTaskTrackers", "MapSlotsOpen", "MissingBlocks", "ReduceSlotsOpen", "RemainingMapTasks", "RemainingMapTasksPerSlot", "RemainingReduceTasks", "RunningMapTasks", "RunningReduceTasks", "S3BytesRead", "S3BytesWritten", "TaskNodesPending", "TaskNodesRunning", "TotalLoad"
  52. ],
  53. "AWS/Kinesis": [
  54. "PutRecord.Bytes", "PutRecord.Latency", "PutRecord.Success", "PutRecords.Bytes", "PutRecords.Latency", "PutRecords.Records", "PutRecords.Success", "IncomingBytes", "IncomingRecords", "GetRecords.Bytes", "GetRecords.IteratorAgeMilliseconds", "GetRecords.Latency", "GetRecords.Success"
  55. ],
  56. "AWS/ML": [
  57. "PredictCount", "PredictFailureCount"
  58. ],
  59. "AWS/OpsWorks": [
  60. "cpu_idle", "cpu_nice", "cpu_system", "cpu_user", "cpu_waitio", "load_1", "load_5", "load_15", "memory_buffers", "memory_cached", "memory_free", "memory_swap", "memory_total", "memory_used", "procs"
  61. ],
  62. "AWS/Redshift": [
  63. "CPUUtilization", "DatabaseConnections", "HealthStatus", "MaintenanceMode", "NetworkReceiveThroughput", "NetworkTransmitThroughput", "PercentageDiskSpaceUsed", "ReadIOPS", "ReadLatency", "ReadThroughput", "WriteIOPS", "WriteLatency", "WriteThroughput"
  64. ],
  65. "AWS/RDS": [
  66. "BinLogDiskUsage", "CPUUtilization", "DatabaseConnections", "DiskQueueDepth", "FreeableMemory", "FreeStorageSpace", "ReplicaLag", "SwapUsage", "ReadIOPS", "WriteIOPS", "ReadLatency", "WriteLatency", "ReadThroughput", "WriteThroughput", "NetworkReceiveThroughput", "NetworkTransmitThroughput"
  67. ],
  68. "AWS/Route53": [
  69. "HealthCheckStatus", "HealthCheckPercentageHealthy"
  70. ],
  71. "AWS/SNS": [
  72. "NumberOfMessagesPublished", "PublishSize", "NumberOfNotificationsDelivered", "NumberOfNotificationsFailed"
  73. ],
  74. "AWS/SQS": [
  75. "NumberOfMessagesSent", "SentMessageSize", "NumberOfMessagesReceived", "NumberOfEmptyReceives", "NumberOfMessagesDeleted", "ApproximateNumberOfMessagesDelayed", "ApproximateNumberOfMessagesVisible", "ApproximateNumberOfMessagesNotVisible"
  76. ],
  77. "AWS/S3": [
  78. "BucketSizeBytes", "NumberOfObjects"
  79. ],
  80. "AWS/SWF": [
  81. "DecisionTaskScheduleToStartTime", "DecisionTaskStartToCloseTime", "DecisionTasksCompleted", "StartedDecisionTasksTimedOutOnClose", "WorkflowStartToCloseTime", "WorkflowsCanceled", "WorkflowsCompleted", "WorkflowsContinuedAsNew", "WorkflowsFailed", "WorkflowsTerminated", "WorkflowsTimedOut"
  82. ],
  83. "AWS/StorageGateway": [
  84. "CacheHitPercent", "CachePercentUsed", "CachePercentDirty", "CloudBytesDownloaded", "CloudDownloadLatency", "CloudBytesUploaded", "UploadBufferFree", "UploadBufferPercentUsed", "UploadBufferUsed", "QueuedWrites", "ReadBytes", "ReadTime", "TotalCacheSize", "WriteBytes", "WriteTime", "WorkingStorageFree", "WorkingStoragePercentUsed", "WorkingStorageUsed", "CacheHitPercent", "CachePercentUsed", "CachePercentDirty", "ReadBytes", "ReadTime", "WriteBytes", "WriteTime", "QueuedWrites"
  85. ],
  86. "AWS/WorkSpaces": [
  87. "Available", "Unhealthy", "ConnectionAttempt", "ConnectionSuccess", "ConnectionFailure", "SessionLaunchTime", "InSessionLatency", "SessionDisconnect"
  88. ],
  89. };
  90. /* jshint +W101 */
  91. var supportedDimensions = {
  92. "AWS/AutoScaling": [
  93. "AutoScalingGroupName"
  94. ],
  95. "AWS/Billing": [
  96. "ServiceName", "LinkedAccount", "Currency"
  97. ],
  98. "AWS/CloudFront": [
  99. "DistributionId", "Region"
  100. ],
  101. "AWS/CloudSearch": [
  102. ],
  103. "AWS/DynamoDB": [
  104. "TableName", "GlobalSecondaryIndexName", "Operation"
  105. ],
  106. "AWS/ElastiCache": [
  107. "CacheClusterId", "CacheNodeId"
  108. ],
  109. "AWS/EBS": [
  110. "VolumeId"
  111. ],
  112. "AWS/EC2": [
  113. "AutoScalingGroupName", "ImageId", "InstanceId", "InstanceType"
  114. ],
  115. "AWS/ELB": [
  116. "LoadBalancerName", "AvailabilityZone"
  117. ],
  118. "AWS/ElasticMapReduce": [
  119. "ClusterId", "JobId"
  120. ],
  121. "AWS/Kinesis": [
  122. "StreamName"
  123. ],
  124. "AWS/ML": [
  125. "MLModelId", "RequestMode"
  126. ],
  127. "AWS/OpsWorks": [
  128. "StackId", "LayerId", "InstanceId"
  129. ],
  130. "AWS/Redshift": [
  131. "NodeID", "ClusterIdentifier"
  132. ],
  133. "AWS/RDS": [
  134. "DBInstanceIdentifier", "DatabaseClass", "EngineName"
  135. ],
  136. "AWS/Route53": [
  137. "HealthCheckId"
  138. ],
  139. "AWS/SNS": [
  140. "Application", "Platform", "TopicName"
  141. ],
  142. "AWS/SQS": [
  143. "QueueName"
  144. ],
  145. "AWS/S3": [
  146. "BucketName", "StorageType"
  147. ],
  148. "AWS/SWF": [
  149. "Domain", "ActivityTypeName", "ActivityTypeVersion"
  150. ],
  151. "AWS/StorageGateway": [
  152. "GatewayId", "GatewayName", "VolumeId"
  153. ],
  154. "AWS/WorkSpaces": [
  155. "DirectoryId", "WorkspaceId"
  156. ],
  157. };
  158. module.controller('CloudWatchQueryCtrl', function($scope) {
  159. $scope.init = function() {
  160. $scope.target.namespace = $scope.target.namespace || '';
  161. $scope.target.metricName = $scope.target.metricName || '';
  162. $scope.target.dimensions = $scope.target.dimensions || {};
  163. $scope.target.statistics = $scope.target.statistics || {};
  164. $scope.target.period = $scope.target.period || 60;
  165. $scope.target.region = $scope.target.region || $scope.datasource.getDefaultRegion();
  166. $scope.target.errors = validateTarget();
  167. };
  168. $scope.refreshMetricData = function() {
  169. $scope.target.errors = validateTarget($scope.target);
  170. // this does not work so good
  171. if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
  172. $scope.oldTarget = angular.copy($scope.target);
  173. $scope.get_data();
  174. }
  175. };
  176. $scope.moveMetricQuery = function(fromIndex, toIndex) {
  177. _.move($scope.panel.targets, fromIndex, toIndex);
  178. };
  179. $scope.duplicate = function() {
  180. var clone = angular.copy($scope.target);
  181. $scope.panel.targets.push(clone);
  182. };
  183. $scope.suggestRegion = function(query, callback) { // jshint unused:false
  184. return supportedRegion;
  185. };
  186. $scope.suggestNamespace = function(query, callback) { // jshint unused:false
  187. return _.keys(supportedMetrics);
  188. };
  189. $scope.suggestMetrics = function(query, callback) { // jshint unused:false
  190. return supportedMetrics[$scope.target.namespace] || [];
  191. };
  192. $scope.suggestDimensionKeys = function(query, callback) { // jshint unused:false
  193. return supportedDimensions[$scope.target.namespace] || [];
  194. };
  195. $scope.suggestDimensionValues = function(query, callback) {
  196. if (!$scope.target.namespace || !$scope.target.metricName) {
  197. return callback([]);
  198. }
  199. var params = {
  200. Namespace: $scope.target.namespace,
  201. MetricName: $scope.target.metricName
  202. };
  203. if (!_.isEmpty($scope.target.dimensions)) {
  204. params.Dimensions = $scope.target.dimensions;
  205. }
  206. $scope.datasource
  207. .performSuggestQuery($scope.target.region, params)
  208. .then(function(result) {
  209. var suggestData = _.chain(result.Metrics)
  210. .map(function(metric) {
  211. return metric.Dimensions;
  212. })
  213. .flatten(true)
  214. .filter(function(dimension) {
  215. return dimension.Name === $scope.target.currentDimensionKey;
  216. })
  217. .map(function(metric) {
  218. return metric;
  219. })
  220. .pluck('Value')
  221. .uniq()
  222. .value();
  223. callback(suggestData);
  224. }, function() {
  225. callback([]);
  226. });
  227. };
  228. $scope.addDimension = function() {
  229. if (!$scope.addDimensionMode) {
  230. $scope.addDimensionMode = true;
  231. return;
  232. }
  233. if (!$scope.target.dimensions) {
  234. $scope.target.dimensions = {};
  235. }
  236. $scope.target.dimensions[$scope.target.currentDimensionKey] = $scope.target.currentDimensionValue;
  237. $scope.target.currentDimensionKey = '';
  238. $scope.target.currentDimensionValue = '';
  239. $scope.refreshMetricData();
  240. $scope.addDimensionMode = false;
  241. };
  242. $scope.removeDimension = function(key) {
  243. delete $scope.target.dimensions[key];
  244. $scope.refreshMetricData();
  245. };
  246. $scope.statisticsOptionChanged = function() {
  247. $scope.refreshMetricData();
  248. };
  249. // TODO: validate target
  250. function validateTarget() {
  251. var errs = {};
  252. if ($scope.target.period < 60 || ($scope.target.period % 60) !== 0) {
  253. errs.period = 'Period must be at least 60 seconds and must be a multiple of 60';
  254. }
  255. return errs;
  256. }
  257. });
  258. });