metric_find_query.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. define([
  2. 'lodash'
  3. ],
  4. function (_) {
  5. 'use strict';
  6. function PrometheusMetricFindQuery(datasource, query, timeSrv) {
  7. this.datasource = datasource;
  8. this.query = query;
  9. this.range = timeSrv.timeRange();
  10. }
  11. PrometheusMetricFindQuery.prototype.process = function() {
  12. var labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]+)\)$/;
  13. var metricNamesRegex = /^metrics\((.+)\)$/;
  14. var labelsRegex = /^labels\((.+)\)$/;
  15. var queryResultRegex = /^query_result\((.+)\)$/;
  16. var labelsQuery = this.query.match(labelsRegex);
  17. if (labelsQuery) {
  18. return this.labelsQuery(labelsQuery[1]);
  19. }
  20. var labelValuesQuery = this.query.match(labelValuesRegex);
  21. if (labelValuesQuery) {
  22. if (labelValuesQuery[1]) {
  23. return this.labelValuesQuery(labelValuesQuery[2], labelValuesQuery[1]);
  24. } else {
  25. return this.labelValuesQuery(labelValuesQuery[2], null);
  26. }
  27. }
  28. var metricNamesQuery = this.query.match(metricNamesRegex);
  29. if (metricNamesQuery) {
  30. return this.metricNameQuery(metricNamesQuery[1]);
  31. }
  32. var queryResultQuery = this.query.match(queryResultRegex);
  33. if (queryResultQuery) {
  34. return this.queryResultQuery(queryResultQuery[1]);
  35. }
  36. // if query contains full metric name, return metric name and label list
  37. return this.metricNameAndLabelsQuery(this.query);
  38. };
  39. PrometheusMetricFindQuery.prototype.labelValuesQuery = function(label, metric) {
  40. var url;
  41. if (!metric) {
  42. // return label values globally
  43. url = '/api/v1/label/' + label + '/values';
  44. return this.datasource._request('GET', url).then(function(result) {
  45. return _.map(result.data.data, function(value) {
  46. return {text: value};
  47. });
  48. });
  49. } else {
  50. url = '/api/v1/series?match[]=' + encodeURIComponent(metric)
  51. + '&start=' + (this.range.from.valueOf() / 1000)
  52. + '&end=' + (this.range.to.valueOf() / 1000);
  53. return this.datasource._request('GET', url)
  54. .then(function(result) {
  55. return _.map(result.data.data, function(metric) {
  56. return {
  57. text: metric[label],
  58. expandable: true
  59. };
  60. });
  61. });
  62. }
  63. };
  64. PrometheusMetricFindQuery.prototype.labelsQuery = function(metric) {
  65. var url;
  66. url = '/api/v1/series?match[]=' + encodeURIComponent(metric)
  67. + '&start=' + (this.range.from.valueOf() / 1000)
  68. + '&end=' + (this.range.to.valueOf() / 1000);
  69. return this.datasource._request('GET', url)
  70. .then(function(result) {
  71. var tags = {};
  72. _.each(result.data.data, function(metric) {
  73. _.each(metric, function(value, key) {
  74. if (key === "__name__") {
  75. return;
  76. }
  77. tags[key] = key;
  78. });
  79. });
  80. return _.map(tags, function(value) {
  81. return {text: value, value: value};
  82. });
  83. });
  84. };
  85. PrometheusMetricFindQuery.prototype.metricNameQuery = function(metricFilterPattern) {
  86. var url = '/api/v1/label/__name__/values';
  87. return this.datasource._request('GET', url)
  88. .then(function(result) {
  89. return _.chain(result.data.data)
  90. .filter(function(metricName) {
  91. var r = new RegExp(metricFilterPattern);
  92. return r.test(metricName);
  93. })
  94. .map(function(matchedMetricName) {
  95. return {
  96. text: matchedMetricName,
  97. expandable: true
  98. };
  99. })
  100. .value();
  101. });
  102. };
  103. PrometheusMetricFindQuery.prototype.queryResultQuery = function(query) {
  104. var url = '/api/v1/query?query=' + encodeURIComponent(query) + '&time=' + (this.range.to.valueOf() / 1000);
  105. return this.datasource._request('GET', url)
  106. .then(function(result) {
  107. return _.map(result.data.data.result, function(metricData) {
  108. var text = metricData.metric.__name__ || '';
  109. delete metricData.metric.__name__;
  110. text += '{' +
  111. _.map(metricData.metric, function(v, k) { return k + '="' + v + '"'; }).join(',') +
  112. '}';
  113. text += ' ' + metricData.value[1] + ' ' + metricData.value[0] * 1000;
  114. return {
  115. text: text,
  116. expandable: true
  117. };
  118. });
  119. });
  120. };
  121. PrometheusMetricFindQuery.prototype.metricNameAndLabelsQuery = function(query) {
  122. var url = '/api/v1/series?match[]=' + encodeURIComponent(query)
  123. + '&start=' + (this.range.from.valueOf() / 1000)
  124. + '&end=' + (this.range.to.valueOf() / 1000);
  125. var self = this;
  126. return this.datasource._request('GET', url)
  127. .then(function(result) {
  128. return _.map(result.data.data, function(metric) {
  129. return {
  130. text: self.datasource.getOriginalMetricName(metric),
  131. expandable: true
  132. };
  133. });
  134. });
  135. };
  136. return PrometheusMetricFindQuery;
  137. });