Files
Andreas Christou c9778c3332 AzureMonitor: Prometheus exemplars support (#87742)
* Update types

* Mark datasource as supporting traces

* Add logic to transform exemplar query to traces query

* Render appropriate editor

* Run trace query for exemplars

* Refactor out common functions

- Add function to retrieve first/default subscription

* Add route for trace exemplars

* Update logic to appropriately query exemplars

* Update traces query builder

* Update instance test

* Remove unneeded import

* Set traces pseudo data source

* Replace deprecated function calls

* Add helper for setting default traces query

* Don't show resource field for exemplars query

* When resetting operation ID for exemplars set query to default

- Update tests

* Update query header to appropriately set the service value

* Fix response frame creation and update tests

* Correctly select resource

* Convert subscriptionsApiVersion to const

* Add feature toggle
2024-06-06 17:53:17 +01:00

71 lines
1.7 KiB
Go

package utils
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
)
const SubscriptionsApiVersion = "2020-01-01"
func GetFirstSubscriptionOrDefault(ctx context.Context, dsInfo types.DatasourceInfo, logger log.Logger) (string, error) {
if dsInfo.Settings.SubscriptionId != "" {
return dsInfo.Settings.SubscriptionId, nil
}
url := fmt.Sprintf("%v/subscriptions?api-version=%v", dsInfo.Routes["Azure Monitor"].URL, SubscriptionsApiVersion)
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return "", err
}
res, err := dsInfo.Services["Azure Monitor"].HTTPClient.Do(request)
if err != nil {
return "", fmt.Errorf("failed to retrieve subscriptions: %v", err)
}
defer func() {
if err := res.Body.Close(); err != nil {
logger.Warn("Failed to close response body", "err", err)
}
}()
subscriptions, err := ParseSubscriptions(res, logger)
if err != nil {
return "", fmt.Errorf("failed to parse subscriptions: %v", err)
}
if len(subscriptions) == 0 {
return "", fmt.Errorf("no subscriptions found: %v", err)
}
return subscriptions[0], nil
}
func ParseSubscriptions(res *http.Response, logger log.Logger) ([]string, error) {
var target struct {
Value []struct {
SubscriptionId string `json:"subscriptionId"`
}
}
err := json.NewDecoder(res.Body).Decode(&target)
if err != nil {
return nil, err
}
defer func() {
if err := res.Body.Close(); err != nil {
logger.Warn("Failed to close response body", "err", err)
}
}()
result := make([]string, len(target.Value))
for i, v := range target.Value {
result[i] = v.SubscriptionId
}
return result, nil
}