mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 20:59:35 +08:00
stackdriver: return values for services and metric types
This commit is contained in:
@ -1,11 +1,7 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
import { TemplateQueryProps } from 'app/types/plugins';
|
||||||
|
|
||||||
interface Props {
|
export default class DefaultTemplateQueryComponent extends PureComponent<TemplateQueryProps, any> {
|
||||||
query: string;
|
|
||||||
onChange: (c: string) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class DefaultTemplateQueryComponent extends PureComponent<Props, any> {
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { value: props.query };
|
this.state = { value: props.query };
|
||||||
|
@ -72,6 +72,7 @@ export class VariableEditorCtrl {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
$scope.current.type === 'query' &&
|
$scope.current.type === 'query' &&
|
||||||
|
_.isString($scope.current.query) &&
|
||||||
$scope.current.query.match(new RegExp('\\$' + $scope.current.name + '(/| |$)'))
|
$scope.current.query.match(new RegExp('\\$' + $scope.current.name + '(/| |$)'))
|
||||||
) {
|
) {
|
||||||
appEvents.emit('alert-warning', [
|
appEvents.emit('alert-warning', [
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
import { extractServicesFromMetricDescriptors, getMetricTypesByService } from './functions';
|
||||||
|
|
||||||
|
export default class StackdriverMetricFindQuery {
|
||||||
|
constructor(private datasource) {}
|
||||||
|
|
||||||
|
async query(query: any) {
|
||||||
|
switch (query.type) {
|
||||||
|
case 'services':
|
||||||
|
return this.handleServiceQueryType();
|
||||||
|
case 'metricTypes':
|
||||||
|
return this.handleMetricTypesQueryType(query);
|
||||||
|
default:
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleServiceQueryType() {
|
||||||
|
const metricDescriptors = await this.datasource.getMetricTypes(this.datasource.projectName);
|
||||||
|
const services = extractServicesFromMetricDescriptors(metricDescriptors);
|
||||||
|
return services.map(s => ({
|
||||||
|
text: s.name,
|
||||||
|
expandable: true,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleMetricTypesQueryType({ service }) {
|
||||||
|
if (!service) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const metricDescriptors = await this.datasource.getMetricTypes(this.datasource.projectName);
|
||||||
|
return getMetricTypesByService(metricDescriptors, service).map(s => ({
|
||||||
|
text: s.name,
|
||||||
|
expandable: true,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import React, { SFC } from 'react';
|
import React, { SFC } from 'react';
|
||||||
|
import { getMetricTypesByService } from '../functions';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onMetricTypeChange: any;
|
onMetricTypeChange: any;
|
||||||
@ -12,7 +13,7 @@ const MetricTypeSelector: SFC<Props> = props => {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return props.metricDescriptors.filter(m => m.service === props.selectedService).map(m => ({
|
return getMetricTypesByService(props.metricDescriptors, props.selectedService).map(m => ({
|
||||||
value: m.service,
|
value: m.service,
|
||||||
name: m.displayName,
|
name: m.displayName,
|
||||||
}));
|
}));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { SFC } from 'react';
|
import React, { SFC } from 'react';
|
||||||
import uniqBy from 'lodash/uniqBy';
|
import { extractServicesFromMetricDescriptors } from '../functions';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onServiceChange: any;
|
onServiceChange: any;
|
||||||
@ -7,11 +7,12 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ServiceSelector: SFC<Props> = props => {
|
const ServiceSelector: SFC<Props> = props => {
|
||||||
const extractServices = () =>
|
const extractServices = () => {
|
||||||
uniqBy(props.metricDescriptors, 'service').map(m => ({
|
return extractServicesFromMetricDescriptors(props.metricDescriptors).map(m => ({
|
||||||
value: m.service,
|
value: m.service,
|
||||||
name: m.serviceShortName,
|
name: m.serviceShortName,
|
||||||
}));
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="gf-form max-width-21">
|
<div className="gf-form max-width-21">
|
||||||
|
@ -1,27 +1,24 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import StackdriverDatasource from '../datasource';
|
// import StackdriverDatasource from '../datasource';
|
||||||
import ServiceSelector from './ServiceSelector';
|
import ServiceSelector from './ServiceSelector';
|
||||||
import MetricTypeSelector from './MetricTypeSelector';
|
import MetricTypeSelector from './MetricTypeSelector';
|
||||||
|
import { TemplateQueryProps } from 'app/types/plugins';
|
||||||
|
import defaultsDeep from 'lodash/defaultsDeep';
|
||||||
|
|
||||||
interface Props {
|
export class StackdriverTemplateQueryComponent extends PureComponent<TemplateQueryProps, any> {
|
||||||
datasource: StackdriverDatasource;
|
|
||||||
query: any;
|
|
||||||
onChange: (c: string) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class StackdriverTemplateQueryComponent extends PureComponent<Props, any> {
|
|
||||||
queryTypes: Array<{ value: string; name: string }> = [
|
queryTypes: Array<{ value: string; name: string }> = [
|
||||||
{ value: 'services', name: 'Services' },
|
{ value: 'services', name: 'Services' },
|
||||||
{ value: 'metricTypes', name: 'Metric Types' },
|
{ value: 'metricTypes', name: 'Metric Types' },
|
||||||
{ value: 'metricLabels', name: 'Metric labels For Metric Type' },
|
{ value: 'metricLabels', name: 'Metric labels For Metric Type' },
|
||||||
];
|
];
|
||||||
|
defaults = { type: undefined, metricDescriptors: [], service: undefined, metricType: undefined };
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props: TemplateQueryProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.handleQueryTypeChange = this.handleQueryTypeChange.bind(this);
|
this.handleQueryTypeChange = this.handleQueryTypeChange.bind(this);
|
||||||
this.onServiceChange = this.onServiceChange.bind(this);
|
this.onServiceChange = this.onServiceChange.bind(this);
|
||||||
this.onMetricTypeChange = this.onMetricTypeChange.bind(this);
|
this.onMetricTypeChange = this.onMetricTypeChange.bind(this);
|
||||||
this.state = { queryType: undefined, metricDescriptors: [], service: undefined, metricType: undefined };
|
this.state = defaultsDeep(this.props.query, this.defaults);
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
@ -30,7 +27,7 @@ export class StackdriverTemplateQueryComponent extends PureComponent<Props, any>
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleQueryTypeChange(event) {
|
handleQueryTypeChange(event) {
|
||||||
this.setState({ queryType: event.target.value });
|
this.setState({ type: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
onServiceChange(event) {
|
onServiceChange(event) {
|
||||||
@ -41,6 +38,11 @@ export class StackdriverTemplateQueryComponent extends PureComponent<Props, any>
|
|||||||
this.setState({ metricType: event.target.value });
|
this.setState({ metricType: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
const { metricDescriptors, ...queryModel } = this.state;
|
||||||
|
this.props.onChange(queryModel);
|
||||||
|
}
|
||||||
|
|
||||||
renderSwitch(queryType) {
|
renderSwitch(queryType) {
|
||||||
switch (queryType) {
|
switch (queryType) {
|
||||||
case 'metricTypes':
|
case 'metricTypes':
|
||||||
@ -78,7 +80,7 @@ export class StackdriverTemplateQueryComponent extends PureComponent<Props, any>
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{this.renderSwitch(this.state.queryType)}
|
{this.renderSwitch(this.state.type)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { stackdriverUnitMappings } from './constants';
|
import { stackdriverUnitMappings } from './constants';
|
||||||
import appEvents from 'app/core/app_events';
|
import appEvents from 'app/core/app_events';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import StackdriverMetricFindQuery from './StackdriverMetricFindQuery';
|
||||||
|
|
||||||
export default class StackdriverDatasource {
|
export default class StackdriverDatasource {
|
||||||
id: number;
|
id: number;
|
||||||
@ -9,6 +10,7 @@ export default class StackdriverDatasource {
|
|||||||
projectName: string;
|
projectName: string;
|
||||||
authenticationType: string;
|
authenticationType: string;
|
||||||
queryPromise: Promise<any>;
|
queryPromise: Promise<any>;
|
||||||
|
metricTypes: any[];
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(instanceSettings, private backendSrv, private templateSrv, private timeSrv) {
|
constructor(instanceSettings, private backendSrv, private templateSrv, private timeSrv) {
|
||||||
@ -18,6 +20,7 @@ export default class StackdriverDatasource {
|
|||||||
this.id = instanceSettings.id;
|
this.id = instanceSettings.id;
|
||||||
this.projectName = instanceSettings.jsonData.defaultProject || '';
|
this.projectName = instanceSettings.jsonData.defaultProject || '';
|
||||||
this.authenticationType = instanceSettings.jsonData.authenticationType || 'jwt';
|
this.authenticationType = instanceSettings.jsonData.authenticationType || 'jwt';
|
||||||
|
this.metricTypes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTimeSeries(options) {
|
async getTimeSeries(options) {
|
||||||
@ -177,8 +180,10 @@ export default class StackdriverDatasource {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
metricFindQuery(query) {
|
async metricFindQuery(query) {
|
||||||
throw new Error('Template variables support is not yet imlemented');
|
const stackdriverMetricFindQuery = new StackdriverMetricFindQuery(this);
|
||||||
|
return stackdriverMetricFindQuery.query(query);
|
||||||
|
// throw new Error('Template variables support is not yet imlemented');
|
||||||
}
|
}
|
||||||
|
|
||||||
async testDatasource() {
|
async testDatasource() {
|
||||||
@ -258,10 +263,11 @@ export default class StackdriverDatasource {
|
|||||||
|
|
||||||
async getMetricTypes(projectName: string) {
|
async getMetricTypes(projectName: string) {
|
||||||
try {
|
try {
|
||||||
|
if (this.metricTypes.length === 0) {
|
||||||
const metricsApiPath = `v3/projects/${projectName}/metricDescriptors`;
|
const metricsApiPath = `v3/projects/${projectName}/metricDescriptors`;
|
||||||
const { data } = await this.doRequest(`${this.baseUrl}${metricsApiPath}`);
|
const { data } = await this.doRequest(`${this.baseUrl}${metricsApiPath}`);
|
||||||
|
|
||||||
const metrics = data.metricDescriptors.map(m => {
|
this.metricTypes = data.metricDescriptors.map(m => {
|
||||||
const [service] = m.type.split('/');
|
const [service] = m.type.split('/');
|
||||||
const [serviceShortName] = service.split('.');
|
const [serviceShortName] = service.split('.');
|
||||||
m.service = service;
|
m.service = service;
|
||||||
@ -269,8 +275,9 @@ export default class StackdriverDatasource {
|
|||||||
m.displayName = m.displayName || m.type;
|
m.displayName = m.displayName || m.type;
|
||||||
return m;
|
return m;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return metrics;
|
return this.metricTypes;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
appEvents.emit('ds-request-error', this.formatStackdriverError(error));
|
appEvents.emit('ds-request-error', this.formatStackdriverError(error));
|
||||||
return [];
|
return [];
|
||||||
|
6
public/app/plugins/datasource/stackdriver/functions.ts
Normal file
6
public/app/plugins/datasource/stackdriver/functions.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import uniqBy from 'lodash/uniqBy';
|
||||||
|
|
||||||
|
export const extractServicesFromMetricDescriptors = metricDescriptors => uniqBy(metricDescriptors, 'service');
|
||||||
|
|
||||||
|
export const getMetricTypesByService = (metricDescriptors, service) =>
|
||||||
|
metricDescriptors.filter(m => m.service === service);
|
@ -99,3 +99,10 @@ export interface PluginsState {
|
|||||||
hasFetched: boolean;
|
hasFetched: boolean;
|
||||||
dashboards: PluginDashboard[];
|
dashboards: PluginDashboard[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TemplateQueryProps {
|
||||||
|
query: any;
|
||||||
|
onChange: (c: any) => void;
|
||||||
|
datasource: any;
|
||||||
|
// datasource: StackdriverDatasource;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user