Azure Monitor: Add support for cross resource queries (#19115)

* Add new query mode picker with different states for each query. Also really simple migration script

* Populate cross resource dropdowns

* Cleanup. Handle change events

* Add multi select picker for subscriptions

* Fix markup issue

* Prepare for new query mode

* More cleanup

* Handle multiple queries both in ds and backend

* Refactoring

* Improve migration

* Add support for multiselect display name

* Use multiselect also for locations and resources

* Add more typings

* Fix migrations

* Custom multiselect built for array of options instead of variables

* Add url builder test

* fix datasource tests

* UI fixes

* Improve query editor init

* Fix brokens tests

* Cleanup

* Fix tslint issue

* Change query mode display name

* Make sure alerting works for single queries

* Friendly error for multi resources

* Add temporary typings
This commit is contained in:
Erik Sundell
2019-09-17 11:35:40 +02:00
committed by GitHub
parent b5f0a5d5ca
commit 88051258e9
16 changed files with 1039 additions and 311 deletions

View File

@@ -1,21 +1,51 @@
import _ from 'lodash';
import { QueryCtrl } from 'app/plugins/sdk';
// import './css/query_editor.css';
import TimegrainConverter from './time_grain_converter';
import './editor/editor_component';
import kbn from 'app/core/utils/kbn';
import { TemplateSrv } from 'app/features/templating/template_srv';
import { auto } from 'angular';
import { DataFrame } from '@grafana/data';
import { Resource } from './types';
import { migrateTargetSchema } from './migrations';
import TimegrainConverter from './time_grain_converter';
import './editor/editor_component';
import './multi-select.directive';
export interface ResultFormat {
text: string;
value: string;
}
interface AzureMonitor {
resourceGroup: string;
resourceGroups: string[];
resourceName: string;
metricDefinition: string;
metricNamespace: string;
metricName: string;
dimensionFilter: string;
timeGrain: string;
timeGrainUnit: string;
timeGrains: Option[];
allowedTimeGrainsMs: number[];
dimensions: any[];
dimension: any;
aggregation: string;
aggOptions: string[];
locations: string[];
queryMode: string;
}
interface Option {
value: string;
text: string;
displayName?: string;
}
export class AzureMonitorQueryCtrl extends QueryCtrl {
static templateUrl = 'partials/query.editor.html';
static defaultQueryMode = 'singleResource';
defaultDropdownValue = 'select';
@@ -23,21 +53,10 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
refId: string;
queryType: string;
subscription: string;
subscriptions: string[];
azureMonitor: {
resourceGroup: string;
resourceName: string;
metricDefinition: string;
metricNamespace: string;
metricName: string;
dimensionFilter: string;
timeGrain: string;
timeGrainUnit: string;
timeGrains: Array<{ text: string; value: string }>;
allowedTimeGrainsMs: number[];
dimensions: any[];
dimension: any;
aggregation: string;
aggOptions: string[];
queryMode: string;
data: { [queryMode: string]: AzureMonitor };
};
azureLogAnalytics: {
query: string;
@@ -63,14 +82,30 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
defaults = {
queryType: 'Azure Monitor',
subscriptions: new Array<string>(),
azureMonitor: {
resourceGroup: this.defaultDropdownValue,
metricDefinition: this.defaultDropdownValue,
resourceName: this.defaultDropdownValue,
metricNamespace: this.defaultDropdownValue,
metricName: this.defaultDropdownValue,
dimensionFilter: '*',
timeGrain: 'auto',
queryMode: 'singleResource',
data: {
singleResource: {
resourceGroups: new Array<string>(),
resourceGroup: this.defaultDropdownValue,
metricDefinition: this.defaultDropdownValue,
metricNamespace: this.defaultDropdownValue,
metricName: this.defaultDropdownValue,
resourceName: this.defaultDropdownValue,
dimensionFilter: '*',
timeGrain: 'auto',
},
crossResource: {
resourceGroups: new Array<string>(),
locations: new Array<string>(),
metricDefinition: this.defaultDropdownValue,
resourceName: this.defaultDropdownValue,
metricName: this.defaultDropdownValue,
dimensionFilter: '*',
timeGrain: 'auto',
},
},
},
azureLogAnalytics: {
query: [
@@ -108,12 +143,17 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
showLastQuery: boolean;
lastQuery: string;
lastQueryError?: string;
subscriptions: Array<{ text: string; value: string }>;
subscriptions: Option[];
subscriptionValues: string[];
resources: Resource[];
locations: Option[];
resourceGroups: Option[];
/** @ngInject */
constructor($scope: any, $injector: auto.IInjectorService, private templateSrv: TemplateSrv) {
super($scope, $injector);
this.target = migrateTargetSchema(this.target);
_.defaultsDeep(this.target, this.defaults);
this.migrateTimeGrains();
@@ -125,12 +165,35 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
this.panelCtrl.events.on('data-received', this.onDataReceived.bind(this), $scope);
this.panelCtrl.events.on('data-error', this.onDataError.bind(this), $scope);
this.resultFormats = [{ text: 'Time series', value: 'time_series' }, { text: 'Table', value: 'table' }];
this.getSubscriptions();
this.resources = new Array<Resource>();
this.subscriptionValues = [];
this.init();
if (this.target.queryType === 'Azure Log Analytics') {
this.getWorkspaces();
}
}
async init() {
const subscriptions = await this.getSubscriptions();
this.datasource.getResources(subscriptions.map((s: Option) => s.value)).then(async (resources: Resource[]) => {
if (!this.target.subscriptions.length) {
this.target.subscriptions = this.subscriptions.map(s => s.value);
}
this.resources = resources;
this.updateLocations();
this.updateCrossResourceGroups();
});
}
updateLocations() {
this.locations = this.getLocations().map(l => ({ text: l, value: l }));
}
updateCrossResourceGroups() {
this.resourceGroups = this.getCrossResourceGroups().map(rg => ({ text: rg, value: rg }));
}
onDataReceived(dataList: DataFrame[]) {
this.lastQueryError = undefined;
this.lastQuery = '';
@@ -170,24 +233,28 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
}
migrateTimeGrains() {
if (this.target.azureMonitor.timeGrainUnit) {
if (this.target.azureMonitor.timeGrain !== 'auto') {
this.target.azureMonitor.timeGrain = TimegrainConverter.createISO8601Duration(
this.target.azureMonitor.timeGrain,
this.target.azureMonitor.timeGrainUnit
const { queryMode } = this.target.azureMonitor;
if (this.target.azureMonitor.data[queryMode].timeGrainUnit) {
if (this.target.azureMonitor.data[queryMode].timeGrain !== 'auto') {
this.target.azureMonitor.data[queryMode].timeGrain = TimegrainConverter.createISO8601Duration(
this.target.azureMonitor.data[queryMode].timeGrain,
this.target.azureMonitor.data[queryMode].timeGrainUnit
);
}
delete this.target.azureMonitor.timeGrainUnit;
delete this.target.azureMonitor.data[queryMode].timeGrainUnit;
this.onMetricNameChange();
}
if (
this.target.azureMonitor.timeGrains &&
this.target.azureMonitor.timeGrains.length > 0 &&
(!this.target.azureMonitor.allowedTimeGrainsMs || this.target.azureMonitor.allowedTimeGrainsMs.length === 0)
this.target.azureMonitor.data[queryMode].timeGrains &&
this.target.azureMonitor.data[queryMode].timeGrains.length > 0 &&
(!this.target.azureMonitor.data[queryMode].allowedTimeGrainsMs ||
this.target.azureMonitor.data[queryMode].allowedTimeGrainsMs.length === 0)
) {
this.target.azureMonitor.allowedTimeGrainsMs = this.convertTimeGrainsToMs(this.target.azureMonitor.timeGrains);
this.target.azureMonitor.data[queryMode].allowedTimeGrainsMs = this.convertTimeGrainsToMs(
this.target.azureMonitor.data[queryMode].timeGrains
);
}
}
@@ -197,15 +264,18 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
}
async migrateToDefaultNamespace() {
const { queryMode } = this.target.azureMonitor;
if (
this.target.azureMonitor.metricNamespace &&
this.target.azureMonitor.metricNamespace !== this.defaultDropdownValue &&
this.target.azureMonitor.metricDefinition
this.target.azureMonitor.data[queryMode].metricNamespace &&
this.target.azureMonitor.data[queryMode].metricNamespace !== this.defaultDropdownValue &&
this.target.azureMonitor.data[queryMode].metricDefinition
) {
return;
}
this.target.azureMonitor.metricNamespace = this.target.azureMonitor.metricDefinition;
this.target.azureMonitor.data[queryMode].metricNamespace = this.target.azureMonitor.data[
queryMode
].metricDefinition;
}
replace(variable: string) {
@@ -218,13 +288,19 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
}
}
getSubscriptions() {
async getSubscriptions() {
if (!this.datasource.azureMonitorDatasource.isConfigured()) {
return;
}
return this.datasource.azureMonitorDatasource.getSubscriptions().then((subs: any) => {
this.subscriptions = subs;
this.subscriptionValues = subs.map((s: Option) => ({ value: s.value, text: s.displayName }));
if (!this.target.subscriptions.length) {
this.target.subscriptions = subs.map((s: Option) => s.value);
}
if (!this.target.subscription && this.target.queryType === 'Azure Monitor') {
this.target.subscription = this.datasource.azureMonitorDatasource.subscriptionId;
} else if (!this.target.subscription && this.target.queryType === 'Azure Log Analytics') {
@@ -244,16 +320,36 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
return this.getWorkspaces();
}
const { queryMode } = this.target.azureMonitor;
if (this.target.queryType === 'Azure Monitor') {
this.target.azureMonitor.resourceGroup = this.defaultDropdownValue;
this.target.azureMonitor.metricDefinition = this.defaultDropdownValue;
this.target.azureMonitor.resourceName = this.defaultDropdownValue;
this.target.azureMonitor.metricName = this.defaultDropdownValue;
this.target.azureMonitor.aggregation = '';
this.target.azureMonitor.timeGrains = [];
this.target.azureMonitor.timeGrain = '';
this.target.azureMonitor.dimensions = [];
this.target.azureMonitor.dimension = '';
this.target.azureMonitor.data[queryMode].resourceGroup = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].metricDefinition = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].resourceName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].metricName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].aggregation = '';
this.target.azureMonitor.data[queryMode].timeGrains = [];
this.target.azureMonitor.data[queryMode].timeGrain = '';
this.target.azureMonitor.data[queryMode].dimensions = [];
this.target.azureMonitor.data[queryMode].dimension = '';
}
}
async onSubscriptionsChange(values: any) {
if (!_.isEqual(this.target.subscriptions.sort(), values.sort())) {
this.target.subscriptions = values;
this.resources = await this.datasource.getResources(this.target.subscriptions);
const { queryMode } = this.target.azureMonitor;
this.target.azureMonitor.data[queryMode].resourceGroup = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].metricDefinition = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].resourceName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].metricName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].aggregation = '';
this.target.azureMonitor.data[queryMode].timeGrains = [];
this.target.azureMonitor.data[queryMode].timeGrain = '';
this.target.azureMonitor.data[queryMode].dimensions = [];
this.target.azureMonitor.data[queryMode].dimension = '';
this.updateLocations();
this.updateCrossResourceGroups();
}
}
@@ -270,29 +366,70 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
.catch(this.handleQueryCtrlError.bind(this));
}
getCrossResourceGroups() {
if (this.target.queryType !== 'Azure Monitor' || !this.datasource.azureMonitorDatasource.isConfigured()) {
return [];
}
return this.resources
.filter(({ location, subscriptionId }) => {
if (this.target.azureMonitor.data.crossResource.locations.length) {
return (
this.target.azureMonitor.data.crossResource.locations.includes(location) &&
this.target.subscriptions.includes(subscriptionId)
);
}
return this.target.subscriptions.includes(subscriptionId);
})
.reduce((options, { group }: Resource) => (options.some(o => o === group) ? options : [...options, group]), []);
}
async getCrossResourceMetricDefinitions(query: any) {
const { locations, resourceGroups } = this.target.azureMonitor.data.crossResource;
return this.resources
.filter(({ location, group }) => locations.includes(location) && resourceGroups.includes(group))
.reduce(
(options: Option[], { type }: Resource) =>
options.some(o => o.value === type) ? options : [...options, { text: type, value: type }],
[]
);
}
getLocations() {
return this.resources
.filter(({ subscriptionId }) => this.target.subscriptions.includes(subscriptionId))
.reduce(
(options: string[], { location }: Resource) =>
options.some(o => o === location) ? options : [...options, location],
[]
);
}
getMetricDefinitions(query: any) {
const { queryMode } = this.target.azureMonitor;
if (
this.target.queryType !== 'Azure Monitor' ||
!this.target.azureMonitor.resourceGroup ||
this.target.azureMonitor.resourceGroup === this.defaultDropdownValue
!this.target.azureMonitor.data[queryMode].resourceGroup ||
this.target.azureMonitor.data[queryMode].resourceGroup === this.defaultDropdownValue
) {
return;
}
return this.datasource
.getMetricDefinitions(
this.replace(this.target.subscription || this.datasource.azureMonitorDatasource.subscriptionId),
this.replace(this.target.azureMonitor.resourceGroup)
this.replace(this.target.azureMonitor.data[queryMode].resourceGroup)
)
.catch(this.handleQueryCtrlError.bind(this));
}
getResourceNames(query: any) {
const { queryMode } = this.target.azureMonitor;
if (
this.target.queryType !== 'Azure Monitor' ||
!this.target.azureMonitor.resourceGroup ||
this.target.azureMonitor.resourceGroup === this.defaultDropdownValue ||
!this.target.azureMonitor.metricDefinition ||
this.target.azureMonitor.metricDefinition === this.defaultDropdownValue
!this.target.azureMonitor.data[queryMode].resourceGroup ||
this.target.azureMonitor.data[queryMode].resourceGroup === this.defaultDropdownValue ||
!this.target.azureMonitor.data[queryMode].metricDefinition ||
this.target.azureMonitor.data[queryMode].metricDefinition === this.defaultDropdownValue
) {
return;
}
@@ -300,21 +437,22 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
return this.datasource
.getResourceNames(
this.replace(this.target.subscription || this.datasource.azureMonitorDatasource.subscriptionId),
this.replace(this.target.azureMonitor.resourceGroup),
this.replace(this.target.azureMonitor.metricDefinition)
this.replace(this.target.azureMonitor.data[queryMode].resourceGroup),
this.replace(this.target.azureMonitor.data[queryMode].metricDefinition)
)
.catch(this.handleQueryCtrlError.bind(this));
}
getMetricNamespaces() {
const { queryMode } = this.target.azureMonitor;
if (
this.target.queryType !== 'Azure Monitor' ||
!this.target.azureMonitor.resourceGroup ||
this.target.azureMonitor.resourceGroup === this.defaultDropdownValue ||
!this.target.azureMonitor.metricDefinition ||
this.target.azureMonitor.metricDefinition === this.defaultDropdownValue ||
!this.target.azureMonitor.resourceName ||
this.target.azureMonitor.resourceName === this.defaultDropdownValue
!this.target.azureMonitor.data[queryMode].resourceGroup ||
this.target.azureMonitor.data[queryMode].resourceGroup === this.defaultDropdownValue ||
!this.target.azureMonitor.data[queryMode].metricDefinition ||
this.target.azureMonitor.data[queryMode].metricDefinition === this.defaultDropdownValue ||
!this.target.azureMonitor.data[queryMode].resourceName ||
this.target.azureMonitor.data[queryMode].resourceName === this.defaultDropdownValue
) {
return;
}
@@ -322,24 +460,50 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
return this.datasource
.getMetricNamespaces(
this.replace(this.target.subscription || this.datasource.azureMonitorDatasource.subscriptionId),
this.replace(this.target.azureMonitor.resourceGroup),
this.replace(this.target.azureMonitor.metricDefinition),
this.replace(this.target.azureMonitor.resourceName)
this.replace(this.target.azureMonitor.data[queryMode].resourceGroup),
this.replace(this.target.azureMonitor.data[queryMode].metricDefinition),
this.replace(this.target.azureMonitor.data[queryMode].resourceName)
)
.catch(this.handleQueryCtrlError.bind(this));
}
async getCrossResourceMetricNames() {
const { locations, resourceGroups, metricDefinition } = this.target.azureMonitor.data.crossResource;
const resources = this.resources.filter(
({ type, location, name, group }) =>
resourceGroups.includes(group) && type === metricDefinition && locations.includes(location)
);
const uniqueResources = _.uniqBy(resources, ({ subscriptionId, name, type, group }: Resource) =>
[subscriptionId, name, locations, group].join()
);
const responses = await Promise.all(
uniqueResources.map(({ subscriptionId, group, type, name }) =>
this.datasource
.getMetricNames(subscriptionId, group, type, name)
.then((metrics: any) => metrics.map((m: any) => ({ ...m, subscriptionIds: [subscriptionId] })), [
{ text: this.defaultDropdownValue, value: this.defaultDropdownValue },
])
)
);
return _.uniqBy(responses.reduce((result, resources) => [...result, ...resources], []), ({ value }) => value);
}
getMetricNames() {
const { queryMode } = this.target.azureMonitor;
if (
this.target.queryType !== 'Azure Monitor' ||
!this.target.azureMonitor.resourceGroup ||
this.target.azureMonitor.resourceGroup === this.defaultDropdownValue ||
!this.target.azureMonitor.metricDefinition ||
this.target.azureMonitor.metricDefinition === this.defaultDropdownValue ||
!this.target.azureMonitor.resourceName ||
this.target.azureMonitor.resourceName === this.defaultDropdownValue ||
!this.target.azureMonitor.metricNamespace ||
this.target.azureMonitor.metricNamespace === this.defaultDropdownValue
!this.target.azureMonitor.data[queryMode].resourceGroup ||
this.target.azureMonitor.data[queryMode].resourceGroup === this.defaultDropdownValue ||
!this.target.azureMonitor.data[queryMode].metricDefinition ||
this.target.azureMonitor.data[queryMode].metricDefinition === this.defaultDropdownValue ||
!this.target.azureMonitor.data[queryMode].resourceName ||
this.target.azureMonitor.data[queryMode].resourceName === this.defaultDropdownValue ||
!this.target.azureMonitor.data[queryMode].metricNamespace ||
this.target.azureMonitor.data[queryMode].metricNamespace === this.defaultDropdownValue
) {
return;
}
@@ -347,87 +511,168 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
return this.datasource
.getMetricNames(
this.replace(this.target.subscription || this.datasource.azureMonitorDatasource.subscriptionId),
this.replace(this.target.azureMonitor.resourceGroup),
this.replace(this.target.azureMonitor.metricDefinition),
this.replace(this.target.azureMonitor.resourceName),
this.replace(this.target.azureMonitor.metricNamespace)
this.replace(this.target.azureMonitor.data[queryMode].resourceGroup),
this.replace(this.target.azureMonitor.data[queryMode].metricDefinition),
this.replace(this.target.azureMonitor.data[queryMode].resourceName),
this.replace(this.target.azureMonitor.data[queryMode].metricNamespace)
)
.catch(this.handleQueryCtrlError.bind(this));
}
onResourceGroupChange() {
this.target.azureMonitor.metricDefinition = this.defaultDropdownValue;
this.target.azureMonitor.resourceName = this.defaultDropdownValue;
this.target.azureMonitor.metricNamespace = this.defaultDropdownValue;
this.target.azureMonitor.metricName = this.defaultDropdownValue;
this.target.azureMonitor.aggregation = '';
this.target.azureMonitor.timeGrains = [];
this.target.azureMonitor.timeGrain = '';
this.target.azureMonitor.dimensions = [];
this.target.azureMonitor.dimension = '';
const { queryMode } = this.target.azureMonitor;
this.target.azureMonitor.data[queryMode].metricDefinition = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].resourceName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].metricNamespace = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].metricName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].aggregation = '';
this.target.azureMonitor.data[queryMode].timeGrains = [];
this.target.azureMonitor.data[queryMode].timeGrain = '';
this.target.azureMonitor.data[queryMode].dimensions = [];
this.target.azureMonitor.data[queryMode].dimension = '';
this.refresh();
}
onCrossResourceGroupChange(values: string[]) {
if (!_.isEqual(this.target.azureMonitor.data.crossResource.resourceGroups.sort(), values.sort())) {
this.target.azureMonitor.data.crossResource.resourceGroups = values;
const { queryMode } = this.target.azureMonitor;
this.target.azureMonitor.data[queryMode].metricDefinition = '';
this.target.azureMonitor.data[queryMode].metricName = '';
this.refresh();
}
}
onCrossResourceMetricDefinitionChange() {
const { queryMode } = this.target.azureMonitor;
this.target.azureMonitor.data[queryMode].metricName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].aggregation = '';
this.target.azureMonitor.data[queryMode].timeGrains = [];
this.target.azureMonitor.data[queryMode].timeGrain = '';
this.target.azureMonitor.data[queryMode].dimensions = [];
this.target.azureMonitor.data[queryMode].dimension = '';
this.refresh();
}
async onLocationsChange(values: string[]) {
if (!_.isEqual(this.target.azureMonitor.data.crossResource.locations.sort(), values.sort())) {
this.target.azureMonitor.data.crossResource.locations = values;
const { queryMode } = this.target.azureMonitor;
this.target.azureMonitor.data[queryMode].metricDefinition = '';
this.target.azureMonitor.data[queryMode].resourceGroup = '';
this.target.azureMonitor.data[queryMode].metricName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].aggregation = '';
this.target.azureMonitor.data[queryMode].timeGrains = [];
this.target.azureMonitor.data[queryMode].timeGrain = '';
this.target.azureMonitor.data[queryMode].dimensions = [];
this.target.azureMonitor.data[queryMode].dimension = '';
this.updateCrossResourceGroups();
this.refresh();
}
}
onMetricDefinitionChange() {
this.target.azureMonitor.resourceName = this.defaultDropdownValue;
this.target.azureMonitor.metricNamespace = this.defaultDropdownValue;
this.target.azureMonitor.metricName = this.defaultDropdownValue;
this.target.azureMonitor.aggregation = '';
this.target.azureMonitor.timeGrains = [];
this.target.azureMonitor.timeGrain = '';
this.target.azureMonitor.dimensions = [];
this.target.azureMonitor.dimension = '';
const { queryMode } = this.target.azureMonitor;
this.target.azureMonitor.data[queryMode].resourceName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].metricNamespace = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].metricName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].aggregation = '';
this.target.azureMonitor.data[queryMode].timeGrains = [];
this.target.azureMonitor.data[queryMode].timeGrain = '';
this.target.azureMonitor.data[queryMode].dimensions = [];
this.target.azureMonitor.data[queryMode].dimension = '';
}
onResourceNameChange() {
this.target.azureMonitor.metricNamespace = this.defaultDropdownValue;
this.target.azureMonitor.metricName = this.defaultDropdownValue;
this.target.azureMonitor.aggregation = '';
this.target.azureMonitor.timeGrains = [];
this.target.azureMonitor.timeGrain = '';
this.target.azureMonitor.dimensions = [];
this.target.azureMonitor.dimension = '';
const { queryMode } = this.target.azureMonitor;
this.target.azureMonitor.data[queryMode].metricNamespace = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].metricName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].aggregation = '';
this.target.azureMonitor.data[queryMode].timeGrains = [];
this.target.azureMonitor.data[queryMode].timeGrain = '';
this.target.azureMonitor.data[queryMode].dimensions = [];
this.target.azureMonitor.data[queryMode].dimension = '';
this.refresh();
}
onMetricNamespacesChange() {
this.target.azureMonitor.metricName = this.defaultDropdownValue;
this.target.azureMonitor.dimensions = [];
this.target.azureMonitor.dimension = '';
const { queryMode } = this.target.azureMonitor;
this.target.azureMonitor.data[queryMode].metricName = this.defaultDropdownValue;
this.target.azureMonitor.data[queryMode].dimensions = [];
this.target.azureMonitor.data[queryMode].dimension = '';
}
setMetricMetadata(metadata: any) {
const { queryMode } = this.target.azureMonitor;
this.target.azureMonitor.data[queryMode].aggOptions = metadata.supportedAggTypes || [metadata.primaryAggType];
this.target.azureMonitor.data[queryMode].aggregation = metadata.primaryAggType;
this.target.azureMonitor.data[queryMode].timeGrains = [{ text: 'auto', value: 'auto' }].concat(
metadata.supportedTimeGrains
);
this.target.azureMonitor.data[queryMode].timeGrain = 'auto';
this.target.azureMonitor.data[queryMode].allowedTimeGrainsMs = this.convertTimeGrainsToMs(
metadata.supportedTimeGrains || []
);
this.target.azureMonitor.data[queryMode].dimensions = metadata.dimensions;
if (metadata.dimensions.length > 0) {
this.target.azureMonitor.data[queryMode].dimension = metadata.dimensions[0].value;
}
return this.refresh();
}
onCrossResourceMetricNameChange() {
const { queryMode } = this.target.azureMonitor;
if (
!this.target.azureMonitor.data[queryMode].metricName ||
this.target.azureMonitor.data[queryMode].metricName === this.defaultDropdownValue
) {
return;
}
const { resourceGroups, metricDefinition, metricName } = this.target.azureMonitor.data[queryMode];
const resource = this.resources.find(
({ type, group }) => type === metricDefinition && resourceGroups.includes(group)
);
return this.datasource
.getMetricMetadata(
this.replace(this.target.subscriptions[0]),
resource.group,
metricDefinition,
resource.name,
metricName
)
.then(this.setMetricMetadata.bind(this))
.then(() => this.refresh())
.catch(this.handleQueryCtrlError.bind(this));
}
onMetricNameChange() {
if (!this.target.azureMonitor.metricName || this.target.azureMonitor.metricName === this.defaultDropdownValue) {
const { queryMode } = this.target.azureMonitor;
if (
!this.target.azureMonitor.data[queryMode].metricName ||
this.target.azureMonitor.data[queryMode].metricName === this.defaultDropdownValue
) {
return;
}
return this.datasource
.getMetricMetadata(
this.replace(this.target.subscription),
this.replace(this.target.azureMonitor.resourceGroup),
this.replace(this.target.azureMonitor.metricDefinition),
this.replace(this.target.azureMonitor.resourceName),
this.replace(this.target.azureMonitor.metricNamespace),
this.replace(this.target.azureMonitor.metricName)
this.replace(this.target.azureMonitor.data[queryMode].resourceGroup),
this.replace(this.target.azureMonitor.data[queryMode].metricDefinition),
this.replace(this.target.azureMonitor.data[queryMode].resourceName),
this.replace(this.target.azureMonitor.data[queryMode].metricName),
this.replace(this.target.azureMonitor.data[queryMode].metricNamespace)
)
.then((metadata: any) => {
this.target.azureMonitor.aggOptions = metadata.supportedAggTypes || [metadata.primaryAggType];
this.target.azureMonitor.aggregation = metadata.primaryAggType;
this.target.azureMonitor.timeGrains = [{ text: 'auto', value: 'auto' }].concat(metadata.supportedTimeGrains);
this.target.azureMonitor.timeGrain = 'auto';
this.target.azureMonitor.allowedTimeGrainsMs = this.convertTimeGrainsToMs(metadata.supportedTimeGrains || []);
this.target.azureMonitor.dimensions = metadata.dimensions;
if (metadata.dimensions.length > 0) {
this.target.azureMonitor.dimension = metadata.dimensions[0].value;
}
return this.refresh();
})
.then(this.setMetricMetadata.bind(this))
.catch(this.handleQueryCtrlError.bind(this));
}
convertTimeGrainsToMs(timeGrains: Array<{ text: string; value: string }>) {
convertTimeGrainsToMs(timeGrains: Option[]) {
const allowedTimeGrainsMs: number[] = [];
timeGrains.forEach((tg: any) => {
if (tg.value !== 'auto') {
@@ -438,10 +683,11 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
}
getAutoInterval() {
if (this.target.azureMonitor.timeGrain === 'auto') {
const { queryMode } = this.target.azureMonitor;
if (this.target.azureMonitor.data[queryMode].timeGrain === 'auto') {
return TimegrainConverter.findClosestTimeGrain(
this.templateSrv.getBuiltInIntervalValue(),
_.map(this.target.azureMonitor.timeGrains, o =>
_.map(this.target.azureMonitor.data[queryMode].timeGrains, o =>
TimegrainConverter.createKbnUnitFromISO8601Duration(o.value)
) || ['1m', '5m', '15m', '30m', '1h', '6h', '12h', '1d']
);