mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 20:59:35 +08:00

* wip: add slo support * Export DataSourcePlugin * wip: break out metric query editor into its own component * wip: refactor frontend - keep SLO and Metric query in differnt objects * wip - load services and slos * Fix broken test * Add interactive slo expression builder * Change order of dropdowns * Refactoring backend model. slo unit testing in progress * Unit test migration and SLOs * Cleanup SLO editor * Simplify alias by component * Support alias by for slos * Support slos in variable queries * Fix broken last query error * Update Help section to include SLO aliases * streamline datasource resource cache * Break out api specific stuff in datasource to its own file * Move get projects call to frontend * Refactor api caching * Unit test api service * Fix lint go issue * Fix typescript strict errors * Fix test datasource * Use budget fraction selector instead of budget * Reset SLO when service is changed * Handle error in case resource call returned no data * Show real SLI display name * Use unsafe prefix on will mount hook * Store goal in query model since it will be used as soon as graph panel supports adding a threshold * Add comment to describe why componentWillMount is used * Interpolate sloid * Break out SLO aggregation into its own func * Also test group bys for metricquery test * Remove not used type fields * Remove annoying stackdriver prefix from error message * Default view param to FULL * Add part about SLO query builder in docs * Use new images * Fixes after feedback * Add one more group by test * Make stackdriver types internal * Update docs/sources/features/datasources/stackdriver.md Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> * Update docs/sources/features/datasources/stackdriver.md Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> * Update docs/sources/features/datasources/stackdriver.md Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> * Updates after PR feedback * add test for when no alias by defined * fix infinite loop when newVariables feature flag is on onChange being called in componentDidUpdate produces an infinite loop when using the new React template variable implementation. Also fixes a spelling mistake * implements feedback for documentation changes * more doc changes Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
162 lines
5.9 KiB
TypeScript
162 lines
5.9 KiB
TypeScript
import isString from 'lodash/isString';
|
|
import { alignmentPeriods, ValueTypes, MetricKind, selectors } from './constants';
|
|
import StackdriverDatasource from './datasource';
|
|
import { MetricFindQueryTypes, VariableQueryData } from './types';
|
|
import { SelectableValue } from '@grafana/data';
|
|
import {
|
|
getMetricTypesByService,
|
|
getAlignmentOptionsByMetric,
|
|
getAggregationOptionsByMetric,
|
|
extractServicesFromMetricDescriptors,
|
|
getLabelKeys,
|
|
} from './functions';
|
|
|
|
export default class StackdriverMetricFindQuery {
|
|
constructor(private datasource: StackdriverDatasource) {}
|
|
|
|
async execute(query: VariableQueryData) {
|
|
try {
|
|
if (!query.projectName) {
|
|
query.projectName = this.datasource.getDefaultProject();
|
|
}
|
|
|
|
switch (query.selectedQueryType) {
|
|
case MetricFindQueryTypes.Projects:
|
|
return this.handleProjectsQuery();
|
|
case MetricFindQueryTypes.Services:
|
|
return this.handleServiceQuery(query);
|
|
case MetricFindQueryTypes.MetricTypes:
|
|
return this.handleMetricTypesQuery(query);
|
|
case MetricFindQueryTypes.LabelKeys:
|
|
return this.handleLabelKeysQuery(query);
|
|
case MetricFindQueryTypes.LabelValues:
|
|
return this.handleLabelValuesQuery(query);
|
|
case MetricFindQueryTypes.ResourceTypes:
|
|
return this.handleResourceTypeQuery(query);
|
|
case MetricFindQueryTypes.Aligners:
|
|
return this.handleAlignersQuery(query);
|
|
case MetricFindQueryTypes.AlignmentPeriods:
|
|
return this.handleAlignmentPeriodQuery();
|
|
case MetricFindQueryTypes.Aggregations:
|
|
return this.handleAggregationQuery(query);
|
|
case MetricFindQueryTypes.SLOServices:
|
|
return this.handleSLOServicesQuery(query);
|
|
case MetricFindQueryTypes.SLO:
|
|
return this.handleSLOQuery(query);
|
|
case MetricFindQueryTypes.Selectors:
|
|
return this.handleSelectorQuery();
|
|
default:
|
|
return [];
|
|
}
|
|
} catch (error) {
|
|
console.error(`Could not run StackdriverMetricFindQuery ${query}`, error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
async handleProjectsQuery() {
|
|
const projects = await this.datasource.getProjects();
|
|
return (projects as SelectableValue<string>).map((s: { label: string; value: string }) => ({
|
|
text: s.label,
|
|
value: s.value,
|
|
expandable: true,
|
|
}));
|
|
}
|
|
|
|
async handleServiceQuery({ projectName }: VariableQueryData) {
|
|
const metricDescriptors = await this.datasource.getMetricTypes(projectName);
|
|
const services: any[] = extractServicesFromMetricDescriptors(metricDescriptors);
|
|
return services.map(s => ({
|
|
text: s.serviceShortName,
|
|
value: s.service,
|
|
expandable: true,
|
|
}));
|
|
}
|
|
|
|
async handleMetricTypesQuery({ selectedService, projectName }: VariableQueryData) {
|
|
if (!selectedService) {
|
|
return [];
|
|
}
|
|
const metricDescriptors = await this.datasource.getMetricTypes(projectName);
|
|
return getMetricTypesByService(metricDescriptors, this.datasource.templateSrv.replace(selectedService)).map(
|
|
(s: any) => ({
|
|
text: s.displayName,
|
|
value: s.type,
|
|
expandable: true,
|
|
})
|
|
);
|
|
}
|
|
|
|
async handleLabelKeysQuery({ selectedMetricType, projectName }: VariableQueryData) {
|
|
if (!selectedMetricType) {
|
|
return [];
|
|
}
|
|
const labelKeys = await getLabelKeys(this.datasource, selectedMetricType, projectName);
|
|
return labelKeys.map(this.toFindQueryResult);
|
|
}
|
|
|
|
async handleLabelValuesQuery({ selectedMetricType, labelKey, projectName }: VariableQueryData) {
|
|
if (!selectedMetricType) {
|
|
return [];
|
|
}
|
|
const refId = 'handleLabelValuesQuery';
|
|
const labels = await this.datasource.getLabels(selectedMetricType, refId, projectName, [labelKey]);
|
|
const interpolatedKey = this.datasource.templateSrv.replace(labelKey);
|
|
const values = labels.hasOwnProperty(interpolatedKey) ? labels[interpolatedKey] : [];
|
|
return values.map(this.toFindQueryResult);
|
|
}
|
|
|
|
async handleResourceTypeQuery({ selectedMetricType, projectName }: VariableQueryData) {
|
|
if (!selectedMetricType) {
|
|
return [];
|
|
}
|
|
const refId = 'handleResourceTypeQueryQueryType';
|
|
const labels = await this.datasource.getLabels(selectedMetricType, refId, projectName);
|
|
return labels['resource.type'].map(this.toFindQueryResult);
|
|
}
|
|
|
|
async handleAlignersQuery({ selectedMetricType, projectName }: VariableQueryData) {
|
|
if (!selectedMetricType) {
|
|
return [];
|
|
}
|
|
const metricDescriptors = await this.datasource.getMetricTypes(projectName);
|
|
const { valueType, metricKind } = metricDescriptors.find(
|
|
(m: any) => m.type === this.datasource.templateSrv.replace(selectedMetricType)
|
|
);
|
|
return getAlignmentOptionsByMetric(valueType, metricKind).map(this.toFindQueryResult);
|
|
}
|
|
|
|
async handleAggregationQuery({ selectedMetricType, projectName }: VariableQueryData) {
|
|
if (!selectedMetricType) {
|
|
return [];
|
|
}
|
|
const metricDescriptors = await this.datasource.getMetricTypes(projectName);
|
|
const { valueType, metricKind } = metricDescriptors.find(
|
|
(m: any) => m.type === this.datasource.templateSrv.replace(selectedMetricType)
|
|
);
|
|
return getAggregationOptionsByMetric(valueType as ValueTypes, metricKind as MetricKind).map(this.toFindQueryResult);
|
|
}
|
|
|
|
async handleSLOServicesQuery({ projectName }: VariableQueryData) {
|
|
const services = await this.datasource.getSLOServices(projectName);
|
|
return services.map(this.toFindQueryResult);
|
|
}
|
|
|
|
async handleSLOQuery({ selectedSLOService, projectName }: VariableQueryData) {
|
|
const slos = await this.datasource.getServiceLevelObjectives(projectName, selectedSLOService);
|
|
return slos.map(this.toFindQueryResult);
|
|
}
|
|
|
|
async handleSelectorQuery() {
|
|
return selectors.map(this.toFindQueryResult);
|
|
}
|
|
|
|
handleAlignmentPeriodQuery() {
|
|
return alignmentPeriods.map(this.toFindQueryResult);
|
|
}
|
|
|
|
toFindQueryResult(x: any) {
|
|
return isString(x) ? { text: x, expandable: true } : { ...x, expandable: true };
|
|
}
|
|
}
|