From 9bab551d8b2e55884daedef0a7c39696c257fb34 Mon Sep 17 00:00:00 2001 From: Kyle Brandt Date: Tue, 8 Sep 2020 15:12:08 -0400 Subject: [PATCH] AzureMonitor: change filterDimensions property to match what is stored (#27459) Changes the dimensionsFilters property to dimensionsFilter in the Azure Monitor Datasource's AzureMonitor service to make what is sent to match the saved model. Before this, the property that the backend was expecting was not available in the case of alerting, where the stored model is fetched. This also fixes a panic when there is a dimension alias but no dimension --- pkg/tsdb/azuremonitor/azuremonitor-datasource.go | 12 +++++++++--- .../azuremonitor/azuremonitor-datasource_test.go | 12 ++++++------ pkg/tsdb/azuremonitor/types.go | 8 ++++++-- .../azure_monitor/azure_monitor_datasource.ts | 4 ++-- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/pkg/tsdb/azuremonitor/azuremonitor-datasource.go b/pkg/tsdb/azuremonitor/azuremonitor-datasource.go index 51d1c3ebbec..0db32ee5550 100644 --- a/pkg/tsdb/azuremonitor/azuremonitor-datasource.go +++ b/pkg/tsdb/azuremonitor/azuremonitor-datasource.go @@ -135,12 +135,12 @@ func (e *AzureMonitorDatasource) buildQueries(queries []*tsdb.Query, timeRange * dimSB := strings.Builder{} - if dimension != "" && dimensionFilter != "" && dimension != "None" && len(azJSONModel.DimensionsFilters) == 0 { + if dimension != "" && dimensionFilter != "" && dimension != "None" && len(azJSONModel.DimensionFilters) == 0 { dimSB.WriteString(fmt.Sprintf("%s eq '%s'", dimension, dimensionFilter)) } else { - for i, filter := range azJSONModel.DimensionsFilters { + for i, filter := range azJSONModel.DimensionFilters { dimSB.WriteString(filter.String()) - if i != len(azJSONModel.DimensionsFilters)-1 { + if i != len(azJSONModel.DimensionFilters)-1 { dimSB.WriteString(" and ") } } @@ -381,10 +381,16 @@ func formatAzureMonitorLegendKey(alias string, resourceName string, metricName s } if metaPartName == "dimensionname" { + if len(keys) == 0 { + return []byte{} + } return []byte(keys[0]) } if metaPartName == "dimensionvalue" { + if len(keys) == 0 { + return []byte{} + } return []byte(lowerLabels[keys[0]]) } diff --git a/pkg/tsdb/azuremonitor/azuremonitor-datasource_test.go b/pkg/tsdb/azuremonitor/azuremonitor-datasource_test.go index 6d398c97832..271e7aac3a8 100644 --- a/pkg/tsdb/azuremonitor/azuremonitor-datasource_test.go +++ b/pkg/tsdb/azuremonitor/azuremonitor-datasource_test.go @@ -86,9 +86,9 @@ func TestAzureMonitorBuildQueries(t *testing.T) { { name: "has dimensionFilter*s* property with one dimension", azureMonitorVariedProperties: map[string]interface{}{ - "timeGrain": "PT1M", - "dimensionsFilters": []azureMonitorDimensionFilter{{"blob", "eq", "*"}}, - "top": "30", + "timeGrain": "PT1M", + "dimensionFilters": []azureMonitorDimensionFilter{{"blob", "eq", "*"}}, + "top": "30", }, queryIntervalMS: 400000, expectedInterval: "PT1M", @@ -97,9 +97,9 @@ func TestAzureMonitorBuildQueries(t *testing.T) { { name: "has dimensionFilter*s* property with two dimensions", azureMonitorVariedProperties: map[string]interface{}{ - "timeGrain": "PT1M", - "dimensionsFilters": []azureMonitorDimensionFilter{{"blob", "eq", "*"}, {"tier", "eq", "*"}}, - "top": "30", + "timeGrain": "PT1M", + "dimensionFilters": []azureMonitorDimensionFilter{{"blob", "eq", "*"}, {"tier", "eq", "*"}}, + "top": "30", }, queryIntervalMS: 400000, expectedInterval: "PT1M", diff --git a/pkg/tsdb/azuremonitor/types.go b/pkg/tsdb/azuremonitor/types.go index 71371ea1ab5..e412f46750e 100644 --- a/pkg/tsdb/azuremonitor/types.go +++ b/pkg/tsdb/azuremonitor/types.go @@ -98,7 +98,7 @@ type azureMonitorJSONQuery struct { TimeGrain string `json:"timeGrain"` Top string `json:"top"` - DimensionsFilters []azureMonitorDimensionFilter `json:"dimensionsFilters"` // new model + DimensionFilters []azureMonitorDimensionFilter `json:"dimensionFilters"` // new model } `json:"azureMonitor"` Subscription string `json:"subscription"` } @@ -112,7 +112,11 @@ type azureMonitorDimensionFilter struct { } func (a azureMonitorDimensionFilter) String() string { - return fmt.Sprintf("%v %v '%v'", a.Dimension, a.Operator, a.Filter) + filter := "*" + if a.Filter != "" { + filter = a.Filter + } + return fmt.Sprintf("%v %v '%v'", a.Dimension, a.Operator, filter) } // insightsJSONQuery is the frontend JSON query model for an Azure Application Insights query. diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts index e7bd4980b67..613585150e9 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts @@ -69,7 +69,7 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend f.dimension && f.dimension !== 'None') .map(f => { const filter = templateSrv.replace(f.filter ?? '', scopedVars); @@ -94,7 +94,7 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend