2018-09-07 23:18:15 +08:00
|
|
|
import _ from 'lodash';
|
2018-12-13 07:16:48 +08:00
|
|
|
import appEvents from 'app/core/app_events';
|
2018-09-04 19:21:02 +08:00
|
|
|
import { QueryCtrl } from 'app/plugins/sdk';
|
2018-09-25 20:42:47 +08:00
|
|
|
import './query_aggregation_ctrl';
|
2018-09-27 20:22:20 +08:00
|
|
|
import './query_filter_ctrl';
|
2018-12-13 07:16:48 +08:00
|
|
|
import { MetricPicker } from './components/MetricPicker';
|
2018-12-11 20:14:55 +08:00
|
|
|
import { OptionPicker } from './components/OptionPicker';
|
2018-12-12 03:12:33 +08:00
|
|
|
import { OptionGroupPicker } from './components/OptionGroupPicker';
|
2018-12-11 20:14:55 +08:00
|
|
|
import { react2AngularDirective } from 'app/core/utils/react2angular';
|
2018-09-04 19:21:02 +08:00
|
|
|
|
2018-09-12 04:41:24 +08:00
|
|
|
export interface QueryMeta {
|
2018-09-26 23:50:08 +08:00
|
|
|
alignmentPeriod: string;
|
2018-09-12 04:41:24 +08:00
|
|
|
rawQuery: string;
|
|
|
|
|
rawQueryString: string;
|
2018-09-14 05:51:45 +08:00
|
|
|
metricLabels: { [key: string]: string[] };
|
|
|
|
|
resourceLabels: { [key: string]: string[] };
|
2018-09-12 04:41:24 +08:00
|
|
|
}
|
2018-09-14 07:49:39 +08:00
|
|
|
|
2018-09-04 19:21:02 +08:00
|
|
|
export class StackdriverQueryCtrl extends QueryCtrl {
|
|
|
|
|
static templateUrl = 'partials/query.editor.html';
|
2018-09-10 04:53:35 +08:00
|
|
|
target: {
|
2018-10-10 17:04:06 +08:00
|
|
|
defaultProject: string;
|
2018-09-27 20:03:52 +08:00
|
|
|
unit: string;
|
2018-09-10 04:53:35 +08:00
|
|
|
metricType: string;
|
2018-09-26 17:23:46 +08:00
|
|
|
service: string;
|
2018-09-12 04:41:24 +08:00
|
|
|
refId: string;
|
2018-09-13 17:02:31 +08:00
|
|
|
aggregation: {
|
|
|
|
|
crossSeriesReducer: string;
|
|
|
|
|
alignmentPeriod: string;
|
|
|
|
|
perSeriesAligner: string;
|
|
|
|
|
groupBys: string[];
|
|
|
|
|
};
|
2018-09-14 21:44:12 +08:00
|
|
|
filters: string[];
|
2018-09-20 17:44:17 +08:00
|
|
|
aliasBy: string;
|
2018-09-25 15:34:14 +08:00
|
|
|
metricKind: any;
|
|
|
|
|
valueType: any;
|
2018-09-07 23:18:15 +08:00
|
|
|
};
|
2018-09-27 20:22:20 +08:00
|
|
|
|
2018-09-11 01:08:39 +08:00
|
|
|
defaults = {
|
2018-10-10 17:04:06 +08:00
|
|
|
defaultProject: 'loading project...',
|
2018-12-12 16:14:06 +08:00
|
|
|
metricType: '',
|
|
|
|
|
service: '',
|
2018-09-25 22:51:12 +08:00
|
|
|
metric: '',
|
2018-09-27 20:03:52 +08:00
|
|
|
unit: '',
|
2018-09-13 17:02:31 +08:00
|
|
|
aggregation: {
|
|
|
|
|
crossSeriesReducer: 'REDUCE_MEAN',
|
2018-09-28 21:23:13 +08:00
|
|
|
alignmentPeriod: 'stackdriver-auto',
|
2018-09-17 20:32:49 +08:00
|
|
|
perSeriesAligner: 'ALIGN_MEAN',
|
2018-09-13 17:02:31 +08:00
|
|
|
groupBys: [],
|
|
|
|
|
},
|
2018-09-14 07:49:39 +08:00
|
|
|
filters: [],
|
2018-09-17 20:32:49 +08:00
|
|
|
showAggregationOptions: false,
|
2018-09-20 17:44:17 +08:00
|
|
|
aliasBy: '',
|
2018-09-25 15:34:14 +08:00
|
|
|
metricKind: '',
|
|
|
|
|
valueType: '',
|
2018-09-11 01:08:39 +08:00
|
|
|
};
|
|
|
|
|
|
2018-09-12 04:41:24 +08:00
|
|
|
showHelp: boolean;
|
|
|
|
|
showLastQuery: boolean;
|
|
|
|
|
lastQueryMeta: QueryMeta;
|
|
|
|
|
lastQueryError?: string;
|
2018-12-13 07:16:48 +08:00
|
|
|
labelData: QueryMeta;
|
|
|
|
|
|
|
|
|
|
loadLabelsPromise: Promise<any>;
|
|
|
|
|
templateSrv: any;
|
2018-09-12 04:41:24 +08:00
|
|
|
|
2018-09-04 19:21:02 +08:00
|
|
|
/** @ngInject */
|
2018-12-13 07:16:48 +08:00
|
|
|
constructor($scope, $injector, templateSrv, private $rootScope) {
|
2018-09-04 19:21:02 +08:00
|
|
|
super($scope, $injector);
|
2018-12-13 07:16:48 +08:00
|
|
|
this.templateSrv = templateSrv;
|
2018-09-11 01:08:39 +08:00
|
|
|
_.defaultsDeep(this.target, this.defaults);
|
2018-09-12 04:41:24 +08:00
|
|
|
this.panelCtrl.events.on('data-received', this.onDataReceived.bind(this), $scope);
|
|
|
|
|
this.panelCtrl.events.on('data-error', this.onDataError.bind(this), $scope);
|
2018-12-13 07:16:48 +08:00
|
|
|
this.handleMetricTypeChange = this.handleMetricTypeChange.bind(this);
|
2018-12-11 20:14:55 +08:00
|
|
|
react2AngularDirective('optionPicker', OptionPicker, [
|
|
|
|
|
'options',
|
|
|
|
|
'onChange',
|
|
|
|
|
'selected',
|
2018-12-12 03:12:33 +08:00
|
|
|
'searchable',
|
|
|
|
|
'className',
|
|
|
|
|
'placeholder',
|
|
|
|
|
]);
|
|
|
|
|
react2AngularDirective('optionGroupPicker', OptionGroupPicker, [
|
|
|
|
|
'groups',
|
|
|
|
|
'onChange',
|
|
|
|
|
'selected',
|
|
|
|
|
'searchable',
|
2018-12-11 20:14:55 +08:00
|
|
|
'className',
|
|
|
|
|
'placeholder',
|
|
|
|
|
]);
|
2018-12-13 07:16:48 +08:00
|
|
|
react2AngularDirective('metricPicker', MetricPicker, [
|
|
|
|
|
'target',
|
|
|
|
|
['onChange', { watchDepth: 'reference' }],
|
|
|
|
|
'defaultProject',
|
|
|
|
|
'metricType',
|
|
|
|
|
['templateSrv', { watchDepth: 'reference' }],
|
|
|
|
|
['datasource', { watchDepth: 'reference' }],
|
|
|
|
|
]);
|
|
|
|
|
this.getLabels();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handleMetricTypeChange({ valueType, metricKind, type, unit }) {
|
|
|
|
|
this.target.metricType = type;
|
|
|
|
|
this.target.unit = unit;
|
|
|
|
|
this.target.valueType = valueType;
|
|
|
|
|
this.target.metricKind = metricKind;
|
|
|
|
|
this.$rootScope.$broadcast('metricTypeChanged');
|
|
|
|
|
this.getLabels();
|
|
|
|
|
this.refresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getLabels() {
|
|
|
|
|
this.loadLabelsPromise = new Promise(async resolve => {
|
|
|
|
|
try {
|
|
|
|
|
const { meta } = await this.datasource.getLabels(this.target.metricType, this.target.refId);
|
|
|
|
|
this.labelData = meta;
|
|
|
|
|
resolve();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
if (error.data && error.data.message) {
|
|
|
|
|
console.log(error.data.message);
|
|
|
|
|
} else {
|
|
|
|
|
console.log(error);
|
|
|
|
|
}
|
|
|
|
|
appEvents.emit('alert-error', ['Error', 'Error loading metric labels for ' + this.target.metricType]);
|
|
|
|
|
resolve();
|
|
|
|
|
}
|
|
|
|
|
});
|
2018-09-13 17:02:31 +08:00
|
|
|
}
|
|
|
|
|
|
2018-09-12 04:41:24 +08:00
|
|
|
onDataReceived(dataList) {
|
|
|
|
|
this.lastQueryError = null;
|
|
|
|
|
this.lastQueryMeta = null;
|
|
|
|
|
|
|
|
|
|
const anySeriesFromQuery: any = _.find(dataList, { refId: this.target.refId });
|
|
|
|
|
if (anySeriesFromQuery) {
|
|
|
|
|
this.lastQueryMeta = anySeriesFromQuery.meta;
|
|
|
|
|
this.lastQueryMeta.rawQueryString = decodeURIComponent(this.lastQueryMeta.rawQuery);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onDataError(err) {
|
|
|
|
|
if (err.data && err.data.results) {
|
|
|
|
|
const queryRes = err.data.results[this.target.refId];
|
2018-09-14 23:47:39 +08:00
|
|
|
if (queryRes && queryRes.error) {
|
2018-09-12 04:41:24 +08:00
|
|
|
this.lastQueryMeta = queryRes.meta;
|
|
|
|
|
this.lastQueryMeta.rawQueryString = decodeURIComponent(this.lastQueryMeta.rawQuery);
|
|
|
|
|
|
|
|
|
|
let jsonBody;
|
|
|
|
|
try {
|
|
|
|
|
jsonBody = JSON.parse(queryRes.error);
|
|
|
|
|
} catch {
|
|
|
|
|
this.lastQueryError = queryRes.error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.lastQueryError = jsonBody.error.message;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-09-04 19:21:02 +08:00
|
|
|
}
|