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