diff --git a/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource.go b/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource.go index bd32e927fbb..b2aebfde98c 100644 --- a/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource.go +++ b/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource.go @@ -43,8 +43,6 @@ func (e *AzureMonitorDatasource) ResourceRequest(rw http.ResponseWriter, req *ht e.Proxy.Do(rw, req, cli) } -var subscriptions = map[string]string{} - // executeTimeSeriesQuery does the following: // 1. build the AzureMonitor url and querystring for each query // 2. executes each query by calling the Azure Monitor API @@ -245,7 +243,7 @@ func getParams(azJSONModel *dataquery.AzureMetricQuery, query backend.DataQuery) return params, nil } -func retrieveSubscriptionDetails(e *AzureMonitorDatasource, cli *http.Client, ctx context.Context, logger log.Logger, tracer tracing.Tracer, subscriptionId string, baseUrl string, dsId int64, orgId int64) { +func (e *AzureMonitorDatasource) retrieveSubscriptionDetails(cli *http.Client, ctx context.Context, logger log.Logger, tracer tracing.Tracer, subscriptionId string, baseUrl string, dsId int64, orgId int64) string { req, err := e.createRequest(ctx, logger, fmt.Sprintf("%s/subscriptions/%s", baseUrl, subscriptionId)) if err != nil { logger.Error("failed to retrieve subscription details for subscription %s: %s", subscriptionId, err) @@ -287,7 +285,7 @@ func retrieveSubscriptionDetails(e *AzureMonitorDatasource, cli *http.Client, ct logger.Warn("Failed to unmarshal subscription detail response", "error", err, "status", res.Status, "body", string(body)) } - subscriptions[data.SubscriptionID] = data.DisplayName + return data.DisplayName } func (e *AzureMonitorDatasource) executeQuery(ctx context.Context, logger log.Logger, query *types.AzureMonitorQuery, dsInfo types.DatasourceInfo, cli *http.Client, @@ -342,11 +340,9 @@ func (e *AzureMonitorDatasource) executeQuery(ctx context.Context, logger log.Lo return dataResponse } - if _, ok := subscriptions[query.Subscription]; !ok { - retrieveSubscriptionDetails(e, cli, ctx, logger, tracer, query.Subscription, dsInfo.Routes["Azure Monitor"].URL, dsInfo.DatasourceID, dsInfo.OrgID) - } + subscription := e.retrieveSubscriptionDetails(cli, ctx, logger, tracer, query.Subscription, dsInfo.Routes["Azure Monitor"].URL, dsInfo.DatasourceID, dsInfo.OrgID) - dataResponse.Frames, err = e.parseResponse(data, query, azurePortalUrl) + dataResponse.Frames, err = e.parseResponse(data, query, azurePortalUrl, subscription) if err != nil { dataResponse.Error = err return dataResponse @@ -387,7 +383,7 @@ func (e *AzureMonitorDatasource) unmarshalResponse(logger log.Logger, res *http. return data, nil } -func (e *AzureMonitorDatasource) parseResponse(amr types.AzureMonitorResponse, query *types.AzureMonitorQuery, azurePortalUrl string) (data.Frames, error) { +func (e *AzureMonitorDatasource) parseResponse(amr types.AzureMonitorResponse, query *types.AzureMonitorQuery, azurePortalUrl string, subscription string) (data.Frames, error) { if len(amr.Value) == 0 { return nil, nil } @@ -433,10 +429,8 @@ func (e *AzureMonitorDatasource) parseResponse(amr types.AzureMonitorResponse, q labels["resourceName"] = resourceName } - currentResource := query.Resources[resourceID] if query.Alias != "" { - displayName := formatAzureMonitorLegendKey(query.Alias, query.Subscription, currentResource, - amr.Value[0].Name.LocalizedValue, "", "", amr.Namespace, amr.Value[0].ID, labels) + displayName := formatAzureMonitorLegendKey(query, resourceID, &amr, labels, subscription) if dataField.Config != nil { dataField.Config.DisplayName = displayName @@ -601,8 +595,12 @@ func getQueryUrl(query *types.AzureMonitorQuery, azurePortalUrl, resourceID, res // formatAzureMonitorLegendKey builds the legend key or timeseries name // Alias patterns like {{resourcename}} are replaced with the appropriate data values. -func formatAzureMonitorLegendKey(alias string, subscriptionId string, resource dataquery.AzureMonitorResource, metricName string, metadataName string, - metadataValue string, namespace string, seriesID string, labels data.Labels) string { +func formatAzureMonitorLegendKey(query *types.AzureMonitorQuery, resourceId string, amr *types.AzureMonitorResponse, labels data.Labels, subscription string) string { + alias := query.Alias + subscriptionId := query.Subscription + resource := query.Resources[resourceId] + metricName := amr.Value[0].Name.LocalizedValue + namespace := amr.Namespace // Could be a collision problem if there were two keys that varied only in case, but I don't think that would happen in azure. lowerLabels := data.Labels{} for k, v := range labels { @@ -624,11 +622,10 @@ func formatAzureMonitorLegendKey(alias string, subscriptionId string, resource d } if metaPartName == "subscription" { - if subscription, ok := subscriptions[subscriptionId]; ok { - return []byte(subscription) - } else { + if subscription == "" { return []byte{} } + return []byte(subscription) } if metaPartName == "resourcegroup" && resource.ResourceGroup != nil { diff --git a/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource_test.go b/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource_test.go index fb486d25de8..66e1be60276 100644 --- a/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource_test.go +++ b/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource_test.go @@ -559,7 +559,7 @@ func TestAzureMonitorParseResponse(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { azData := loadTestFile(t, tt.responseFile) - dframes, err := datasource.parseResponse(azData, tt.mockQuery, "http://ds") + dframes, err := datasource.parseResponse(azData, tt.mockQuery, "http://ds", "") require.NoError(t, err) require.NotNil(t, dframes)