mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(plugin-editors): more work on plugin editor loading
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
declare var Datasource: any;
|
||||
export default Datasource;
|
||||
|
||||
@@ -1,282 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
'lodash',
|
||||
'moment',
|
||||
'app/core/utils/datemath',
|
||||
'./query_ctrl',
|
||||
],
|
||||
function (angular, _, moment, dateMath) {
|
||||
'use strict';
|
||||
|
||||
var durationSplitRegexp = /(\d+)(ms|s|m|h|d|w|M|y)/;
|
||||
|
||||
/** @ngInject */
|
||||
function PrometheusDatasource(instanceSettings, $q, backendSrv, templateSrv) {
|
||||
this.type = 'prometheus';
|
||||
this.editorSrc = 'app/features/prometheus/partials/query.editor.html';
|
||||
this.name = instanceSettings.name;
|
||||
this.supportMetrics = true;
|
||||
this.url = instanceSettings.url;
|
||||
this.directUrl = instanceSettings.directUrl;
|
||||
this.basicAuth = instanceSettings.basicAuth;
|
||||
this.withCredentials = instanceSettings.withCredentials;
|
||||
this.lastErrors = {};
|
||||
|
||||
this._request = function(method, url) {
|
||||
var options = {
|
||||
url: this.url + url,
|
||||
method: method
|
||||
};
|
||||
|
||||
if (this.basicAuth || this.withCredentials) {
|
||||
options.withCredentials = true;
|
||||
}
|
||||
if (this.basicAuth) {
|
||||
options.headers = {
|
||||
"Authorization": this.basicAuth
|
||||
};
|
||||
}
|
||||
|
||||
return backendSrv.datasourceRequest(options);
|
||||
};
|
||||
|
||||
// Called once per panel (graph)
|
||||
this.query = function(options) {
|
||||
var start = getPrometheusTime(options.range.from, false);
|
||||
var end = getPrometheusTime(options.range.to, true);
|
||||
|
||||
var queries = [];
|
||||
options = _.clone(options);
|
||||
_.each(options.targets, _.bind(function(target) {
|
||||
if (!target.expr || target.hide) {
|
||||
return;
|
||||
}
|
||||
|
||||
var query = {};
|
||||
query.expr = templateSrv.replace(target.expr, options.scopedVars);
|
||||
|
||||
var interval = target.interval || options.interval;
|
||||
var intervalFactor = target.intervalFactor || 1;
|
||||
target.step = query.step = this.calculateInterval(interval, intervalFactor);
|
||||
var range = Math.ceil(end - start);
|
||||
// Prometheus drop query if range/step > 11000
|
||||
// calibrate step if it is too big
|
||||
if (query.step !== 0 && range / query.step > 11000) {
|
||||
target.step = query.step = Math.ceil(range / 11000);
|
||||
}
|
||||
|
||||
queries.push(query);
|
||||
}, this));
|
||||
|
||||
// No valid targets, return the empty result to save a round trip.
|
||||
if (_.isEmpty(queries)) {
|
||||
var d = $q.defer();
|
||||
d.resolve({ data: [] });
|
||||
return d.promise;
|
||||
}
|
||||
|
||||
var allQueryPromise = _.map(queries, _.bind(function(query) {
|
||||
return this.performTimeSeriesQuery(query, start, end);
|
||||
}, this));
|
||||
|
||||
var self = this;
|
||||
return $q.all(allQueryPromise)
|
||||
.then(function(allResponse) {
|
||||
var result = [];
|
||||
|
||||
_.each(allResponse, function(response, index) {
|
||||
if (response.status === 'error') {
|
||||
self.lastErrors.query = response.error;
|
||||
throw response.error;
|
||||
}
|
||||
delete self.lastErrors.query;
|
||||
|
||||
_.each(response.data.data.result, function(metricData) {
|
||||
result.push(transformMetricData(metricData, options.targets[index], start, end));
|
||||
});
|
||||
});
|
||||
|
||||
return { data: result };
|
||||
});
|
||||
};
|
||||
|
||||
this.performTimeSeriesQuery = function(query, start, end) {
|
||||
var url = '/api/v1/query_range?query=' + encodeURIComponent(query.expr) + '&start=' + start + '&end=' + end + '&step=' + query.step;
|
||||
return this._request('GET', url);
|
||||
};
|
||||
|
||||
this.performSuggestQuery = function(query) {
|
||||
var url = '/api/v1/label/__name__/values';
|
||||
|
||||
return this._request('GET', url).then(function(result) {
|
||||
return _.filter(result.data.data, function (metricName) {
|
||||
return metricName.indexOf(query) !== 1;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.metricFindQuery = function(query) {
|
||||
if (!query) { return $q.when([]); }
|
||||
|
||||
var interpolated;
|
||||
try {
|
||||
interpolated = templateSrv.replace(query);
|
||||
}
|
||||
catch (err) {
|
||||
return $q.reject(err);
|
||||
}
|
||||
|
||||
var label_values_regex = /^label_values\(([^,]+)(?:,\s*(.+))?\)$/;
|
||||
var metric_names_regex = /^metrics\((.+)\)$/;
|
||||
|
||||
var url;
|
||||
var label_values_query = interpolated.match(label_values_regex);
|
||||
if (label_values_query) {
|
||||
if (!label_values_query[2]) {
|
||||
// return label values globally
|
||||
url = '/api/v1/label/' + label_values_query[1] + '/values';
|
||||
|
||||
return this._request('GET', url).then(function(result) {
|
||||
return _.map(result.data.data, function(value) {
|
||||
return {text: value};
|
||||
});
|
||||
});
|
||||
} else {
|
||||
url = '/api/v1/series?match[]=' + encodeURIComponent(label_values_query[1]);
|
||||
|
||||
return this._request('GET', url)
|
||||
.then(function(result) {
|
||||
return _.map(result.data.data, function(metric) {
|
||||
return {
|
||||
text: metric[label_values_query[2]],
|
||||
expandable: true
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var metric_names_query = interpolated.match(metric_names_regex);
|
||||
if (metric_names_query) {
|
||||
url = '/api/v1/label/__name__/values';
|
||||
|
||||
return this._request('GET', url)
|
||||
.then(function(result) {
|
||||
return _.chain(result.data.data)
|
||||
.filter(function(metricName) {
|
||||
var r = new RegExp(metric_names_query[1]);
|
||||
return r.test(metricName);
|
||||
})
|
||||
.map(function(matchedMetricName) {
|
||||
return {
|
||||
text: matchedMetricName,
|
||||
expandable: true
|
||||
};
|
||||
})
|
||||
.value();
|
||||
});
|
||||
} else {
|
||||
// if query contains full metric name, return metric name and label list
|
||||
url = '/api/v1/series?match[]=' + encodeURIComponent(interpolated);
|
||||
|
||||
return this._request('GET', url)
|
||||
.then(function(result) {
|
||||
return _.map(result.data.data, function(metric) {
|
||||
return {
|
||||
text: getOriginalMetricName(metric),
|
||||
expandable: true
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.testDatasource = function() {
|
||||
return this.metricFindQuery('metrics(.*)').then(function() {
|
||||
return { status: 'success', message: 'Data source is working', title: 'Success' };
|
||||
});
|
||||
};
|
||||
|
||||
PrometheusDatasource.prototype.calculateInterval = function(interval, intervalFactor) {
|
||||
var m = interval.match(durationSplitRegexp);
|
||||
var dur = moment.duration(parseInt(m[1]), m[2]);
|
||||
var sec = dur.asSeconds();
|
||||
if (sec < 1) {
|
||||
sec = 1;
|
||||
}
|
||||
|
||||
return Math.ceil(sec * intervalFactor);
|
||||
};
|
||||
|
||||
function transformMetricData(md, options, start, end) {
|
||||
var dps = [],
|
||||
metricLabel = null;
|
||||
|
||||
metricLabel = createMetricLabel(md.metric, options);
|
||||
|
||||
var stepMs = parseInt(options.step) * 1000;
|
||||
var baseTimestamp = start * 1000;
|
||||
_.each(md.values, function(value) {
|
||||
var dp_value = parseFloat(value[1]);
|
||||
if (_.isNaN(dp_value)) {
|
||||
dp_value = null;
|
||||
}
|
||||
|
||||
var timestamp = value[0] * 1000;
|
||||
for (var t = baseTimestamp; t < timestamp; t += stepMs) {
|
||||
dps.push([null, t]);
|
||||
}
|
||||
baseTimestamp = timestamp + stepMs;
|
||||
dps.push([dp_value, timestamp]);
|
||||
});
|
||||
|
||||
var endTimestamp = end * 1000;
|
||||
for (var t = baseTimestamp; t <= endTimestamp; t += stepMs) {
|
||||
dps.push([null, t]);
|
||||
}
|
||||
|
||||
return { target: metricLabel, datapoints: dps };
|
||||
}
|
||||
|
||||
function createMetricLabel(labelData, options) {
|
||||
if (_.isUndefined(options) || _.isEmpty(options.legendFormat)) {
|
||||
return getOriginalMetricName(labelData);
|
||||
}
|
||||
|
||||
var originalSettings = _.templateSettings;
|
||||
_.templateSettings = {
|
||||
interpolate: /\{\{(.+?)\}\}/g
|
||||
};
|
||||
|
||||
var template = _.template(templateSrv.replace(options.legendFormat));
|
||||
var metricName;
|
||||
try {
|
||||
metricName = template(labelData);
|
||||
} catch (e) {
|
||||
metricName = '{}';
|
||||
}
|
||||
|
||||
_.templateSettings = originalSettings;
|
||||
|
||||
return metricName;
|
||||
}
|
||||
|
||||
function getOriginalMetricName(labelData) {
|
||||
var metricName = labelData.__name__ || '';
|
||||
delete labelData.__name__;
|
||||
var labelPart = _.map(_.pairs(labelData), function(label) {
|
||||
return label[0] + '="' + label[1] + '"';
|
||||
}).join(',');
|
||||
return metricName + '{' + labelPart + '}';
|
||||
}
|
||||
|
||||
function getPrometheusTime(date, roundUp) {
|
||||
if (_.isString(date)) {
|
||||
date = dateMath.parse(date, roundUp);
|
||||
}
|
||||
return (date.valueOf() / 1000).toFixed(0);
|
||||
}
|
||||
}
|
||||
|
||||
return PrometheusDatasource;
|
||||
});
|
||||
278
public/app/plugins/datasource/prometheus/datasource.ts
Normal file
278
public/app/plugins/datasource/prometheus/datasource.ts
Normal file
@@ -0,0 +1,278 @@
|
||||
///<reference path="../../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
||||
import * as dateMath from 'app/core/utils/datemath';
|
||||
|
||||
var durationSplitRegexp = /(\d+)(ms|s|m|h|d|w|M|y)/;
|
||||
|
||||
/** @ngInject */
|
||||
function PrometheusDatasource(instanceSettings, $q, backendSrv, templateSrv) {
|
||||
this.type = 'prometheus';
|
||||
this.editorSrc = 'app/features/prometheus/partials/query.editor.html';
|
||||
this.name = instanceSettings.name;
|
||||
this.supportMetrics = true;
|
||||
this.url = instanceSettings.url;
|
||||
this.directUrl = instanceSettings.directUrl;
|
||||
this.basicAuth = instanceSettings.basicAuth;
|
||||
this.withCredentials = instanceSettings.withCredentials;
|
||||
this.lastErrors = {};
|
||||
|
||||
this._request = function(method, url) {
|
||||
var options: any = {
|
||||
url: this.url + url,
|
||||
method: method
|
||||
};
|
||||
|
||||
if (this.basicAuth || this.withCredentials) {
|
||||
options.withCredentials = true;
|
||||
}
|
||||
if (this.basicAuth) {
|
||||
options.headers = {
|
||||
"Authorization": this.basicAuth
|
||||
};
|
||||
}
|
||||
|
||||
return backendSrv.datasourceRequest(options);
|
||||
};
|
||||
|
||||
// Called once per panel (graph)
|
||||
this.query = function(options) {
|
||||
var start = getPrometheusTime(options.range.from, false);
|
||||
var end = getPrometheusTime(options.range.to, true);
|
||||
|
||||
var queries = [];
|
||||
options = _.clone(options);
|
||||
_.each(options.targets, _.bind(function(target) {
|
||||
if (!target.expr || target.hide) {
|
||||
return;
|
||||
}
|
||||
|
||||
var query: any = {};
|
||||
query.expr = templateSrv.replace(target.expr, options.scopedVars);
|
||||
|
||||
var interval = target.interval || options.interval;
|
||||
var intervalFactor = target.intervalFactor || 1;
|
||||
target.step = query.step = this.calculateInterval(interval, intervalFactor);
|
||||
var range = Math.ceil(end - start);
|
||||
// Prometheus drop query if range/step > 11000
|
||||
// calibrate step if it is too big
|
||||
if (query.step !== 0 && range / query.step > 11000) {
|
||||
target.step = query.step = Math.ceil(range / 11000);
|
||||
}
|
||||
|
||||
queries.push(query);
|
||||
}, this));
|
||||
|
||||
// No valid targets, return the empty result to save a round trip.
|
||||
if (_.isEmpty(queries)) {
|
||||
var d = $q.defer();
|
||||
d.resolve({ data: [] });
|
||||
return d.promise;
|
||||
}
|
||||
|
||||
var allQueryPromise = _.map(queries, _.bind(function(query) {
|
||||
return this.performTimeSeriesQuery(query, start, end);
|
||||
}, this));
|
||||
|
||||
var self = this;
|
||||
return $q.all(allQueryPromise)
|
||||
.then(function(allResponse) {
|
||||
var result = [];
|
||||
|
||||
_.each(allResponse, function(response, index) {
|
||||
if (response.status === 'error') {
|
||||
self.lastErrors.query = response.error;
|
||||
throw response.error;
|
||||
}
|
||||
delete self.lastErrors.query;
|
||||
|
||||
_.each(response.data.data.result, function(metricData) {
|
||||
result.push(transformMetricData(metricData, options.targets[index], start, end));
|
||||
});
|
||||
});
|
||||
|
||||
return { data: result };
|
||||
});
|
||||
};
|
||||
|
||||
this.performTimeSeriesQuery = function(query, start, end) {
|
||||
var url = '/api/v1/query_range?query=' + encodeURIComponent(query.expr) + '&start=' + start + '&end=' + end + '&step=' + query.step;
|
||||
return this._request('GET', url);
|
||||
};
|
||||
|
||||
this.performSuggestQuery = function(query) {
|
||||
var url = '/api/v1/label/__name__/values';
|
||||
|
||||
return this._request('GET', url).then(function(result) {
|
||||
return _.filter(result.data.data, function (metricName) {
|
||||
return metricName.indexOf(query) !== 1;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.metricFindQuery = function(query) {
|
||||
if (!query) { return $q.when([]); }
|
||||
|
||||
var interpolated;
|
||||
try {
|
||||
interpolated = templateSrv.replace(query);
|
||||
} catch (err) {
|
||||
return $q.reject(err);
|
||||
}
|
||||
|
||||
var label_values_regex = /^label_values\(([^,]+)(?:,\s*(.+))?\)$/;
|
||||
var metric_names_regex = /^metrics\((.+)\)$/;
|
||||
|
||||
var url;
|
||||
var label_values_query = interpolated.match(label_values_regex);
|
||||
if (label_values_query) {
|
||||
if (!label_values_query[2]) {
|
||||
// return label values globally
|
||||
url = '/api/v1/label/' + label_values_query[1] + '/values';
|
||||
|
||||
return this._request('GET', url).then(function(result) {
|
||||
return _.map(result.data.data, function(value) {
|
||||
return {text: value};
|
||||
});
|
||||
});
|
||||
} else {
|
||||
url = '/api/v1/series?match[]=' + encodeURIComponent(label_values_query[1]);
|
||||
|
||||
return this._request('GET', url)
|
||||
.then(function(result) {
|
||||
return _.map(result.data.data, function(metric) {
|
||||
return {
|
||||
text: metric[label_values_query[2]],
|
||||
expandable: true
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var metric_names_query = interpolated.match(metric_names_regex);
|
||||
if (metric_names_query) {
|
||||
url = '/api/v1/label/__name__/values';
|
||||
|
||||
return this._request('GET', url)
|
||||
.then(function(result) {
|
||||
return _.chain(result.data.data)
|
||||
.filter(function(metricName) {
|
||||
var r = new RegExp(metric_names_query[1]);
|
||||
return r.test(metricName);
|
||||
})
|
||||
.map(function(matchedMetricName) {
|
||||
return {
|
||||
text: matchedMetricName,
|
||||
expandable: true
|
||||
};
|
||||
})
|
||||
.value();
|
||||
});
|
||||
} else {
|
||||
// if query contains full metric name, return metric name and label list
|
||||
url = '/api/v1/series?match[]=' + encodeURIComponent(interpolated);
|
||||
|
||||
return this._request('GET', url)
|
||||
.then(function(result) {
|
||||
return _.map(result.data.data, function(metric) {
|
||||
return {
|
||||
text: getOriginalMetricName(metric),
|
||||
expandable: true
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.testDatasource = function() {
|
||||
return this.metricFindQuery('metrics(.*)').then(function() {
|
||||
return { status: 'success', message: 'Data source is working', title: 'Success' };
|
||||
});
|
||||
};
|
||||
|
||||
PrometheusDatasource.prototype.calculateInterval = function(interval, intervalFactor) {
|
||||
var m = interval.match(durationSplitRegexp);
|
||||
var dur = moment.duration(parseInt(m[1]), m[2]);
|
||||
var sec = dur.asSeconds();
|
||||
if (sec < 1) {
|
||||
sec = 1;
|
||||
}
|
||||
|
||||
return Math.ceil(sec * intervalFactor);
|
||||
};
|
||||
|
||||
function transformMetricData(md, options, start, end) {
|
||||
var dps = [],
|
||||
metricLabel = null;
|
||||
|
||||
metricLabel = createMetricLabel(md.metric, options);
|
||||
|
||||
var stepMs = parseInt(options.step) * 1000;
|
||||
var baseTimestamp = start * 1000;
|
||||
_.each(md.values, function(value) {
|
||||
var dp_value = parseFloat(value[1]);
|
||||
if (_.isNaN(dp_value)) {
|
||||
dp_value = null;
|
||||
}
|
||||
|
||||
var timestamp = value[0] * 1000;
|
||||
for (var t = baseTimestamp; t < timestamp; t += stepMs) {
|
||||
dps.push([null, t]);
|
||||
}
|
||||
baseTimestamp = timestamp + stepMs;
|
||||
dps.push([dp_value, timestamp]);
|
||||
});
|
||||
|
||||
var endTimestamp = end * 1000;
|
||||
for (var t = baseTimestamp; t <= endTimestamp; t += stepMs) {
|
||||
dps.push([null, t]);
|
||||
}
|
||||
|
||||
return { target: metricLabel, datapoints: dps };
|
||||
}
|
||||
|
||||
function createMetricLabel(labelData, options) {
|
||||
if (_.isUndefined(options) || _.isEmpty(options.legendFormat)) {
|
||||
return getOriginalMetricName(labelData);
|
||||
}
|
||||
|
||||
var originalSettings = _.templateSettings;
|
||||
_.templateSettings = {
|
||||
interpolate: /\{\{(.+?)\}\}/g
|
||||
};
|
||||
|
||||
var template = _.template(templateSrv.replace(options.legendFormat));
|
||||
var metricName;
|
||||
try {
|
||||
metricName = template(labelData);
|
||||
} catch (e) {
|
||||
metricName = '{}';
|
||||
}
|
||||
|
||||
_.templateSettings = originalSettings;
|
||||
|
||||
return metricName;
|
||||
}
|
||||
|
||||
function getOriginalMetricName(labelData) {
|
||||
var metricName = labelData.__name__ || '';
|
||||
delete labelData.__name__;
|
||||
var labelPart = _.map(_.pairs(labelData), function(label) {
|
||||
return label[0] + '="' + label[1] + '"';
|
||||
}).join(',');
|
||||
return metricName + '{' + labelPart + '}';
|
||||
}
|
||||
|
||||
function getPrometheusTime(date, roundUp): number {
|
||||
if (_.isString(date)) {
|
||||
date = dateMath.parse(date, roundUp);
|
||||
}
|
||||
return Math.floor(date.valueOf() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
export {PrometheusDatasource};
|
||||
@@ -1,20 +0,0 @@
|
||||
define([
|
||||
'./datasource',
|
||||
],
|
||||
function (PromDatasource) {
|
||||
'use strict';
|
||||
|
||||
function metricsQueryEditor() {
|
||||
return {controller: 'PrometheusQueryCtrl', templateUrl: 'public/app/plugins/datasource/prometheus/partials/query.editor.html'};
|
||||
}
|
||||
|
||||
function configView() {
|
||||
return {templateUrl: 'public/app/plugins/datasource/prometheus/partials/config.html'};
|
||||
}
|
||||
|
||||
return {
|
||||
Datasource: PromDatasource,
|
||||
metricsQueryEditor: metricsQueryEditor,
|
||||
configView: configView,
|
||||
};
|
||||
});
|
||||
23
public/app/plugins/datasource/prometheus/module.ts
Normal file
23
public/app/plugins/datasource/prometheus/module.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import {PrometheusDatasource} from './datasource';
|
||||
import {PrometheusQueryCtrl} from './query_ctrl';
|
||||
|
||||
|
||||
|
||||
|
||||
// function metricsQueryEditor() {
|
||||
// return {controller: 'PrometheusQueryCtrl', templateUrl: 'public/app/plugins/datasource/prometheus/partials/query.editor.html'};
|
||||
// }
|
||||
//
|
||||
// function configView() {
|
||||
// return {templateUrl: ''};
|
||||
// }
|
||||
|
||||
class PrometheusConfigViewCtrl {
|
||||
static templateUrl = 'public/app/plugins/datasource/prometheus/partials/config.html';
|
||||
}
|
||||
|
||||
export {
|
||||
PrometheusDatasource as Datasource,
|
||||
PrometheusQueryCtrl as MetricsQueryEditor,
|
||||
PrometheusConfigViewCtrl as ConfigView
|
||||
};
|
||||
@@ -1,67 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
'lodash',
|
||||
],
|
||||
function (angular, _) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('PrometheusQueryCtrl', function($scope, templateSrv) {
|
||||
$scope.panelCtrl = $scope.ctrl;
|
||||
$scope.panel = $scope.panelCtrl.panel;
|
||||
|
||||
$scope.init = function() {
|
||||
var target = $scope.target;
|
||||
|
||||
target.expr = target.expr || '';
|
||||
target.intervalFactor = target.intervalFactor || 2;
|
||||
|
||||
$scope.metric = '';
|
||||
$scope.resolutions = _.map([1,2,3,4,5,10], function(f) {
|
||||
return {factor: f, label: '1/' + f};
|
||||
});
|
||||
|
||||
$scope.$on('typeahead-updated', function() {
|
||||
$scope.$apply($scope.inputMetric);
|
||||
$scope.refreshMetricData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.refreshMetricData = function() {
|
||||
if (!_.isEqual($scope.oldTarget, $scope.target)) {
|
||||
$scope.oldTarget = angular.copy($scope.target);
|
||||
$scope.paneCtrl.refresh();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.inputMetric = function() {
|
||||
$scope.target.expr += $scope.target.metric;
|
||||
$scope.metric = '';
|
||||
};
|
||||
|
||||
$scope.suggestMetrics = function(query, callback) {
|
||||
$scope.datasource
|
||||
.performSuggestQuery(query)
|
||||
.then(callback);
|
||||
};
|
||||
|
||||
$scope.linkToPrometheus = function() {
|
||||
var range = Math.ceil(($scope.range.to.valueOf() - $scope.range.from.valueOf()) / 1000);
|
||||
var endTime = $scope.range.to.utc().format('YYYY-MM-DD HH:mm');
|
||||
var expr = {
|
||||
expr: templateSrv.replace($scope.target.expr, $scope.panel.scopedVars),
|
||||
range_input: range + 's',
|
||||
end_input: endTime,
|
||||
step_input: '',
|
||||
stacked: $scope.panel.stack,
|
||||
tab: 0
|
||||
};
|
||||
var hash = encodeURIComponent(JSON.stringify([expr]));
|
||||
return $scope.datasource.directUrl + '/graph#' + hash;
|
||||
};
|
||||
|
||||
$scope.init();
|
||||
});
|
||||
|
||||
});
|
||||
66
public/app/plugins/datasource/prometheus/query_ctrl.ts
Normal file
66
public/app/plugins/datasource/prometheus/query_ctrl.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
///<reference path="../../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
||||
import * as dateMath from 'app/core/utils/datemath';
|
||||
|
||||
function PrometheusQueryCtrl($scope, templateSrv) {
|
||||
$scope.panelCtrl = $scope.ctrl;
|
||||
$scope.panel = $scope.panelCtrl.panel;
|
||||
|
||||
$scope.init = function() {
|
||||
var target = $scope.target;
|
||||
|
||||
target.expr = target.expr || '';
|
||||
target.intervalFactor = target.intervalFactor || 2;
|
||||
|
||||
$scope.metric = '';
|
||||
$scope.resolutions = _.map([1,2,3,4,5,10], function(f) {
|
||||
return {factor: f, label: '1/' + f};
|
||||
});
|
||||
|
||||
$scope.$on('typeahead-updated', function() {
|
||||
$scope.$apply($scope.inputMetric);
|
||||
$scope.refreshMetricData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.refreshMetricData = function() {
|
||||
if (!_.isEqual($scope.oldTarget, $scope.target)) {
|
||||
$scope.oldTarget = angular.copy($scope.target);
|
||||
$scope.paneCtrl.refresh();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.inputMetric = function() {
|
||||
$scope.target.expr += $scope.target.metric;
|
||||
$scope.metric = '';
|
||||
};
|
||||
|
||||
$scope.suggestMetrics = function(query, callback) {
|
||||
$scope.datasource
|
||||
.performSuggestQuery(query)
|
||||
.then(callback);
|
||||
};
|
||||
|
||||
$scope.linkToPrometheus = function() {
|
||||
var range = Math.ceil(($scope.range.to.valueOf() - $scope.range.from.valueOf()) / 1000);
|
||||
var endTime = $scope.range.to.utc().format('YYYY-MM-DD HH:mm');
|
||||
var expr = {
|
||||
expr: templateSrv.replace($scope.target.expr, $scope.panel.scopedVars),
|
||||
range_input: range + 's',
|
||||
end_input: endTime,
|
||||
step_input: '',
|
||||
stacked: $scope.panel.stack,
|
||||
tab: 0
|
||||
};
|
||||
var hash = encodeURIComponent(JSON.stringify([expr]));
|
||||
return $scope.datasource.directUrl + '/graph#' + hash;
|
||||
};
|
||||
|
||||
$scope.init();
|
||||
}
|
||||
|
||||
export {PrometheusQueryCtrl};
|
||||
Reference in New Issue
Block a user