mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
stackdriver: load time series meta data for group by dropdown
This commit is contained in:
parent
5763d3cae2
commit
add23d9716
@ -103,6 +103,7 @@ func (e *StackdriverExecutor) buildQueries(tsdbQuery *tsdb.TsdbQuery) ([]*Stackd
|
|||||||
params.Add("interval.startTime", startTime.UTC().Format(time.RFC3339))
|
params.Add("interval.startTime", startTime.UTC().Format(time.RFC3339))
|
||||||
params.Add("interval.endTime", endTime.UTC().Format(time.RFC3339))
|
params.Add("interval.endTime", endTime.UTC().Format(time.RFC3339))
|
||||||
params.Add("filter", "metric.type=\""+metricType+"\"")
|
params.Add("filter", "metric.type=\""+metricType+"\"")
|
||||||
|
params.Add("view", query.Model.Get("view").MustString())
|
||||||
setAggParams(¶ms, query)
|
setAggParams(¶ms, query)
|
||||||
|
|
||||||
if setting.Env == setting.DEV {
|
if setting.Env == setting.DEV {
|
||||||
|
@ -11,17 +11,16 @@ export default class StackdriverDatasource {
|
|||||||
this.id = instanceSettings.id;
|
this.id = instanceSettings.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async query(options) {
|
async getTimeSeries(options) {
|
||||||
const queries = options.targets.filter(target => !target.hide).map(t => ({
|
const queries = options.targets.filter(target => !target.hide).map(t => ({
|
||||||
refId: t.refId,
|
refId: t.refId,
|
||||||
datasourceId: this.id,
|
datasourceId: this.id,
|
||||||
metricType: t.metricType,
|
metricType: t.metricType,
|
||||||
primaryAggregation: t.aggregation.crossSeriesReducer,
|
primaryAggregation: 'REDUCE_MEAN', //t.aggregation.crossSeriesReducer,
|
||||||
groupBys: t.aggregation.groupBys,
|
// groupBys: t.aggregation.groupBys,
|
||||||
|
view: t.view || 'FULL',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const result = [];
|
|
||||||
|
|
||||||
const { data } = await this.backendSrv.datasourceRequest({
|
const { data } = await this.backendSrv.datasourceRequest({
|
||||||
url: '/api/tsdb/query',
|
url: '/api/tsdb/query',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -31,7 +30,12 @@ export default class StackdriverDatasource {
|
|||||||
queries,
|
queries,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async query(options) {
|
||||||
|
const result = [];
|
||||||
|
const data = await this.getTimeSeries(options);
|
||||||
if (data.results) {
|
if (data.results) {
|
||||||
Object['values'](data.results).forEach(queryRes => {
|
Object['values'](data.results).forEach(queryRes => {
|
||||||
if (!queryRes.series) {
|
if (!queryRes.series) {
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<div class="gf-form-inline">
|
<div class="gf-form-inline">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label width-9">Metric Type</span>
|
<span class="gf-form-label width-9">Metric Type</span>
|
||||||
<gf-form-dropdown model="ctrl.target.metricType" get-options="ctrl.getMetricTypes($query)" class="min-width-20"
|
<gf-form-dropdown model="ctrl.target.metricType" get-options="ctrl.getMetricTypes($query)" class="min-width-20" disabled
|
||||||
disabled type="text" allow-custom="true" lookup-text="true" css-class="min-width-12" on-change="ctrl.refresh()"></gf-form-dropdown>
|
type="text" allow-custom="true" lookup-text="true" css-class="min-width-12" on-change="ctrl.onMetricTypeChange()"></gf-form-dropdown>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
@ -30,8 +30,8 @@
|
|||||||
<div class="gf-form-inline">
|
<div class="gf-form-inline">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label width-9">Project</span>
|
<span class="gf-form-label width-9">Project</span>
|
||||||
<input class="gf-form-input" disabled type="text" ng-model='ctrl.target.project.name' get-options="ctrl.getProjects()"
|
<input class="gf-form-input" disabled type="text" ng-model='ctrl.target.project.name' get-options="ctrl.getProjects()" css-class="min-width-12"
|
||||||
css-class="min-width-12" />
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label query-keyword" ng-click="ctrl.showHelp = !ctrl.showHelp">
|
<label class="gf-form-label query-keyword" ng-click="ctrl.showHelp = !ctrl.showHelp">
|
||||||
@ -63,4 +63,4 @@ Help text for aliasing
|
|||||||
<div class="gf-form" ng-show="ctrl.lastQueryError">
|
<div class="gf-form" ng-show="ctrl.lastQueryError">
|
||||||
<pre class="gf-form-pre alert alert-error">{{ctrl.lastQueryError}}</pre>
|
<pre class="gf-form-pre alert alert-error">{{ctrl.lastQueryError}}</pre>
|
||||||
</div>
|
</div>
|
||||||
</query-editor-row>
|
</query-editor-row>
|
@ -2,10 +2,16 @@ import _ from 'lodash';
|
|||||||
import { QueryCtrl } from 'app/plugins/sdk';
|
import { QueryCtrl } from 'app/plugins/sdk';
|
||||||
import appEvents from 'app/core/app_events';
|
import appEvents from 'app/core/app_events';
|
||||||
|
|
||||||
|
export interface LabelType {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface QueryMeta {
|
export interface QueryMeta {
|
||||||
rawQuery: string;
|
rawQuery: string;
|
||||||
rawQueryString: string;
|
rawQueryString: string;
|
||||||
metricLabels: any;
|
metricLabels: LabelType[];
|
||||||
|
resourceLabels: LabelType[];
|
||||||
}
|
}
|
||||||
export class StackdriverQueryCtrl extends QueryCtrl {
|
export class StackdriverQueryCtrl extends QueryCtrl {
|
||||||
static templateUrl = 'partials/query.editor.html';
|
static templateUrl = 'partials/query.editor.html';
|
||||||
@ -59,18 +65,22 @@ export class StackdriverQueryCtrl extends QueryCtrl {
|
|||||||
showLastQuery: boolean;
|
showLastQuery: boolean;
|
||||||
lastQueryMeta: QueryMeta;
|
lastQueryMeta: QueryMeta;
|
||||||
lastQueryError?: string;
|
lastQueryError?: string;
|
||||||
|
metricLabels: LabelType[];
|
||||||
|
resourceLabels: LabelType[];
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor($scope, $injector, private uiSegmentSrv) {
|
constructor($scope, $injector, private uiSegmentSrv, private timeSrv) {
|
||||||
super($scope, $injector);
|
super($scope, $injector);
|
||||||
_.defaultsDeep(this.target, this.defaults);
|
_.defaultsDeep(this.target, this.defaults);
|
||||||
|
|
||||||
this.panelCtrl.events.on('data-received', this.onDataReceived.bind(this), $scope);
|
this.panelCtrl.events.on('data-received', this.onDataReceived.bind(this), $scope);
|
||||||
this.panelCtrl.events.on('data-error', this.onDataError.bind(this), $scope);
|
this.panelCtrl.events.on('data-error', this.onDataError.bind(this), $scope);
|
||||||
|
|
||||||
this.getCurrentProject().then(this.getMetricTypes.bind(this));
|
this.getCurrentProject()
|
||||||
|
.then(this.getMetricTypes.bind(this))
|
||||||
|
.then(this.getLabels.bind(this));
|
||||||
|
|
||||||
this.groupBySegments = _.map(this.target.aggregation.groupBys, groupBy => {
|
this.groupBySegments = this.target.aggregation.groupBys.map(groupBy => {
|
||||||
return uiSegmentSrv.getSegmentForValue(groupBy);
|
return uiSegmentSrv.getSegmentForValue(groupBy);
|
||||||
});
|
});
|
||||||
this.ensurePlusButton(this.groupBySegments);
|
this.ensurePlusButton(this.groupBySegments);
|
||||||
@ -116,12 +126,47 @@ export class StackdriverQueryCtrl extends QueryCtrl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getGroupBys() {
|
async getLabels() {
|
||||||
const segments = _.map(Object.keys(this.lastQueryMeta.metricLabels), (label: string) => {
|
const data = await this.datasource.getTimeSeries({
|
||||||
return this.uiSegmentSrv.newSegment({ value: label, expandable: false });
|
targets: [
|
||||||
|
{
|
||||||
|
refId: this.target.refId,
|
||||||
|
datasourceId: this.datasource.id,
|
||||||
|
metricType: this.target.metricType,
|
||||||
|
aggregation: {
|
||||||
|
crossSeriesReducer: 'REDUCE_NONE',
|
||||||
|
},
|
||||||
|
view: 'HEADERS',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
range: this.timeSrv.timeRange(),
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.resolve(segments);
|
this.metricLabels = data.results[this.target.refId].meta.metricLabels;
|
||||||
|
this.resourceLabels = data.results[this.target.refId].meta.resourceLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
async onMetricTypeChange() {
|
||||||
|
this.refresh();
|
||||||
|
this.getLabels();
|
||||||
|
}
|
||||||
|
|
||||||
|
getGroupBys() {
|
||||||
|
const metricLabels = Object.keys(this.metricLabels).map(l => {
|
||||||
|
return this.uiSegmentSrv.newSegment({
|
||||||
|
value: `metric.label.${l}`,
|
||||||
|
expandable: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const resourceLabels = Object.keys(this.resourceLabels).map(l => {
|
||||||
|
return this.uiSegmentSrv.newSegment({
|
||||||
|
value: `resource.label.${l}`,
|
||||||
|
expandable: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return Promise.resolve([...metricLabels, ...resourceLabels]);
|
||||||
}
|
}
|
||||||
|
|
||||||
groupByChanged(segment, index) {
|
groupByChanged(segment, index) {
|
||||||
@ -136,6 +181,7 @@ export class StackdriverQueryCtrl extends QueryCtrl {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
this.ensurePlusButton(this.groupBySegments);
|
this.ensurePlusButton(this.groupBySegments);
|
||||||
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
ensurePlusButton(segments) {
|
ensurePlusButton(segments) {
|
||||||
|
Loading…
Reference in New Issue
Block a user