mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Stackdriver: Loads project name and metrics descriptions into the query controller
This commit is contained in:
parent
684aa3ff33
commit
75c002645c
@ -9,6 +9,10 @@ export default class StackdriverDatasource {
|
||||
this.doRequest = this.doRequest;
|
||||
}
|
||||
|
||||
query() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
testDatasource() {
|
||||
const path = `v3/projects/raintank-production/metricDescriptors`;
|
||||
return this.doRequest(`${this.baseUrl}${path}`)
|
||||
@ -48,6 +52,16 @@ export default class StackdriverDatasource {
|
||||
return response.data.projects.map(p => ({ id: p.projectId, name: p.name }));
|
||||
}
|
||||
|
||||
async getMetricTypes(projectId: string) {
|
||||
try {
|
||||
const metricsApiPath = `v3/projects/${projectId}/metricDescriptors`;
|
||||
const { data } = await this.doRequest(`${this.baseUrl}${metricsApiPath}`);
|
||||
return data.metricDescriptors.map(m => ({ id: m.name, name: m.displayName }));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
async doRequest(url, maxRetries = 1) {
|
||||
return this.backendSrv
|
||||
.datasourceRequest({
|
||||
|
@ -1,5 +1,5 @@
|
||||
import StackdriverDatasource from './datasource';
|
||||
// import { StackdriverQueryCtrl } from './query_ctrl';
|
||||
import { StackdriverQueryCtrl } from './query_ctrl';
|
||||
import { StackdriverConfigCtrl } from './config_ctrl';
|
||||
|
||||
// class AnnotationsQueryCtrl {
|
||||
@ -8,7 +8,7 @@ import { StackdriverConfigCtrl } from './config_ctrl';
|
||||
|
||||
export {
|
||||
StackdriverDatasource as Datasource,
|
||||
// StackdriverQueryCtrl as QueryCtrl,
|
||||
StackdriverQueryCtrl as QueryCtrl,
|
||||
StackdriverConfigCtrl as ConfigCtrl,
|
||||
// AnnotationsQueryCtrl,
|
||||
};
|
||||
|
@ -1,81 +1,16 @@
|
||||
<query-editor-row query-ctrl="ctrl" has-text-edit-mode="true">
|
||||
|
||||
<div class="gf-form" ng-show="ctrl.target.textEditor">
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.target" spellcheck="false" ng-blur="ctrl.targetTextChanged()"></input>
|
||||
</div>
|
||||
|
||||
<div ng-hide="ctrl.target.textEditor">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-6 query-keyword">Series</label>
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.queryModel.seriesByTagUsed" ng-repeat="tag in ctrl.queryModel.tags" class="gf-form">
|
||||
<gf-form-dropdown
|
||||
model="tag.key"
|
||||
allow-custom="true"
|
||||
label-mode="true"
|
||||
debounce="true"
|
||||
placeholder="Tag key"
|
||||
css-class="query-segment-key"
|
||||
get-options="ctrl.getTags($index, $query)"
|
||||
on-change="ctrl.tagChanged(tag, $index)"
|
||||
/>
|
||||
<gf-form-dropdown
|
||||
model="tag.operator"
|
||||
label-mode="true"
|
||||
css-class="query-segment-operator"
|
||||
get-options="ctrl.getTagOperators()"
|
||||
on-change="ctrl.tagChanged(tag, $index)"
|
||||
min-input-width="30"
|
||||
/>
|
||||
<gf-form-dropdown
|
||||
model="tag.value"
|
||||
allow-custom="true"
|
||||
label-mode="true"
|
||||
debounce="true"
|
||||
css-class="query-segment-value"
|
||||
placeholder="Tag value"
|
||||
get-options="ctrl.getTagValues(tag, $index, $query)"
|
||||
on-change="ctrl.tagChanged(tag, $index)"
|
||||
/>
|
||||
<label class="gf-form-label query-keyword" ng-if="ctrl.showDelimiter($index)">AND</label>
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.queryModel.seriesByTagUsed" ng-repeat="segment in ctrl.addTagSegments" role="menuitem" class="gf-form">
|
||||
<metric-segment segment="segment" get-options="ctrl.getTagsAsSegments($query)" on-change="ctrl.addNewTag(segment)" debounce="true" />
|
||||
</div>
|
||||
|
||||
<div ng-if="!ctrl.queryModel.seriesByTagUsed" ng-repeat="segment in ctrl.segments" role="menuitem" class="gf-form">
|
||||
<metric-segment segment="segment" get-options="ctrl.getAltSegments($index, $query)" on-change="ctrl.segmentValueChanged(segment, $index)" />
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.paused" class="gf-form">
|
||||
<a ng-click="ctrl.unpause()" class="gf-form-label query-part"><i class="fa fa-play"></i></a>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-6 query-keyword">Functions</label>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="func in ctrl.queryModel.functions" class="gf-form">
|
||||
<span graphite-func-editor class="gf-form-label query-part" ng-hide="func.hidden"></span>
|
||||
</div>
|
||||
|
||||
<div class="gf-form dropdown">
|
||||
<span graphite-add-func></span>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-9">Project</span>
|
||||
<input class="gf-form-input" disabled type="text" ng-model='ctrl.project.name' get-options="ctrl.getProjects()" css-class="min-width-12"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-9">Metric Type</span>
|
||||
<gf-form-dropdown model="ctrl.metricType" get-options="ctrl.getMetricTypes($query)" class="gf-form-input" disabled type="text"
|
||||
allow-custom="true" lookup-text="true" css-class="min-width-12"></gf-form-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</query-editor-row>
|
@ -1,11 +1,65 @@
|
||||
import './add_graphite_func';
|
||||
import './func_editor';
|
||||
import _ from 'lodash';
|
||||
import { QueryCtrl } from 'app/plugins/sdk';
|
||||
import appEvents from 'app/core/app_events';
|
||||
|
||||
export class StackdriverQueryCtrl extends QueryCtrl {
|
||||
static templateUrl = 'partials/query.editor.html';
|
||||
project: {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
metricType: string;
|
||||
defaultDropdownValue = 'select';
|
||||
|
||||
/** @ngInject */
|
||||
constructor($scope, $injector) {
|
||||
super($scope, $injector);
|
||||
this.project = {
|
||||
id: 'default',
|
||||
name: 'loading project...',
|
||||
};
|
||||
this.metricType = this.defaultDropdownValue;
|
||||
|
||||
this.getCurrentProject().then(this.getMetricTypes.bind(this));
|
||||
}
|
||||
|
||||
async getCurrentProject() {
|
||||
try {
|
||||
const projects = await this.datasource.getProjects();
|
||||
if (projects && projects.length > 0) {
|
||||
this.project = this.project = projects[0];
|
||||
} else {
|
||||
throw new Error('No projects found');
|
||||
}
|
||||
} catch (error) {
|
||||
let message = 'Projects cannot be fetched: ';
|
||||
message += error.statusText ? error.statusText + ': ' : '';
|
||||
if (error && error.data && error.data.error && error.data.error.message) {
|
||||
if (error.data.error.code === 403) {
|
||||
message += `
|
||||
A list of projects could not be fetched from the Google Cloud Resource Manager API.
|
||||
You might need to enable it first:
|
||||
https://console.developers.google.com/apis/library/cloudresourcemanager.googleapis.com`;
|
||||
} else {
|
||||
message += error.data.error.code + '. ' + error.data.error.message;
|
||||
}
|
||||
} else {
|
||||
message += 'Cannot connect to Stackdriver API';
|
||||
}
|
||||
appEvents.emit('ds-request-error', message);
|
||||
}
|
||||
}
|
||||
|
||||
async getMetricTypes() {
|
||||
//projects/raintank-production/metricDescriptors/agent.googleapis.com/agent/api_request_count
|
||||
if (this.project.id !== 'default') {
|
||||
const metricTypes = await this.datasource.getMetricTypes(this.project.id);
|
||||
if (this.metricType === this.defaultDropdownValue && metricTypes.length > 0) {
|
||||
this.$scope.$apply(() => (this.metricType = metricTypes[0].name));
|
||||
}
|
||||
return metricTypes.map(mt => ({ value: mt.id, text: mt.id }));
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user