Update azure monitor

pull/97363/head
Ivana Huckova 6 months ago
parent 348c8fa927
commit 21b53845b8
  1. 21
      pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource.go
  2. 10
      pkg/tsdb/azuremonitor/loganalytics/utils.go
  3. 12
      pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource.go
  4. 9
      pkg/tsdb/azuremonitor/utils/utils.go
  5. 58
      pkg/tsdb/azuremonitor/utils/utils_test.go

@ -18,7 +18,6 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
@ -142,12 +141,12 @@ func (e *AzureLogAnalyticsDatasource) ExecuteTimeSeriesQuery(ctx context.Context
for _, query := range originalQueries {
logsQuery, err := e.buildQuery(ctx, query, dsInfo, fromAlert)
if err != nil {
errorsource.AddErrorToResponse(query.RefID, result, err)
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
continue
}
res, err := e.executeQuery(ctx, logsQuery, dsInfo, client, url)
if err != nil {
errorsource.AddErrorToResponse(query.RefID, result, err)
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
continue
}
result.Responses[query.RefID] = *res
@ -252,7 +251,7 @@ func (e *AzureLogAnalyticsDatasource) buildQuery(ctx context.Context, query back
cfg := backend.GrafanaConfigFromContext(ctx)
hasPromExemplarsToggle := cfg.FeatureToggles().IsEnabled("azureMonitorPrometheusExemplars")
if !hasPromExemplarsToggle {
return nil, errorsource.DownstreamError(fmt.Errorf("query type unsupported as azureMonitorPrometheusExemplars feature toggle is not enabled"), false)
return nil, backend.DownstreamError(fmt.Errorf("query type unsupported as azureMonitorPrometheusExemplars feature toggle is not enabled"))
}
}
azureAppInsightsQuery, err := buildAppInsightsQuery(ctx, query, dsInfo, appInsightsRegExp, e.Logger)
@ -269,7 +268,7 @@ func (e *AzureLogAnalyticsDatasource) buildQuery(ctx context.Context, query back
func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *AzureLogAnalyticsQuery, dsInfo types.DatasourceInfo, client *http.Client, url string) (*backend.DataResponse, error) {
// If azureLogAnalyticsSameAs is defined and set to false, return an error
if sameAs, ok := dsInfo.JSONData["azureLogAnalyticsSameAs"]; ok && !sameAs.(bool) {
return nil, errorsource.DownstreamError(fmt.Errorf("credentials for Log Analytics are no longer supported. Go to the data source configuration to update Azure Monitor credentials"), false)
return nil, backend.DownstreamError(fmt.Errorf("credentials for Log Analytics are no longer supported. Go to the data source configuration to update Azure Monitor credentials"))
}
queryJSONModel := dataquery.AzureMonitorQuery{}
@ -280,7 +279,7 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *A
if query.QueryType == dataquery.AzureQueryTypeAzureTraces {
if query.ResultFormat == dataquery.ResultFormatTrace && query.Query == "" {
return nil, errorsource.DownstreamError(fmt.Errorf("cannot visualise trace events using the trace visualiser"), false)
return nil, backend.DownstreamError(fmt.Errorf("cannot visualise trace events using the trace visualiser"))
}
}
@ -301,7 +300,7 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *A
res, err := client.Do(req)
if err != nil {
return nil, errorsource.DownstreamError(err, false)
return nil, backend.DownstreamError(err)
}
defer func() {
@ -597,11 +596,11 @@ func getCorrelationWorkspaces(ctx context.Context, baseResource string, resource
res, err := azMonService.HTTPClient.Do(req)
if err != nil {
return AzureCorrelationAPIResponse{}, errorsource.DownstreamError(err, false)
return AzureCorrelationAPIResponse{}, backend.DownstreamError(err)
}
body, err := io.ReadAll(res.Body)
if err != nil {
return AzureCorrelationAPIResponse{}, errorsource.DownstreamError(err, false)
return AzureCorrelationAPIResponse{}, backend.DownstreamError(err)
}
defer func() {
@ -611,7 +610,7 @@ func getCorrelationWorkspaces(ctx context.Context, baseResource string, resource
}()
if res.StatusCode/100 != 2 {
return AzureCorrelationAPIResponse{}, errorsource.SourceError(backend.ErrorSourceFromHTTPStatus(res.StatusCode), fmt.Errorf("request failed, status: %s, body: %s", res.Status, string(body)), false)
return AzureCorrelationAPIResponse{}, utils.CreateResponseErrorFromStatusCode(res.StatusCode, res.Status, body)
}
var data AzureCorrelationAPIResponse
d := json.NewDecoder(bytes.NewReader(body))
@ -675,7 +674,7 @@ func (e *AzureLogAnalyticsDatasource) unmarshalResponse(res *http.Response) (Azu
}()
if res.StatusCode/100 != 2 {
return AzureLogAnalyticsResponse{}, errorsource.SourceError(backend.ErrorSourceFromHTTPStatus(res.StatusCode), fmt.Errorf("request failed, status: %s, body: %s", res.Status, string(body)), false)
return AzureLogAnalyticsResponse{}, utils.CreateResponseErrorFromStatusCode(res.StatusCode, res.Status, body)
}
var data AzureLogAnalyticsResponse

@ -7,8 +7,8 @@ import (
"strings"
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery"
)
@ -47,18 +47,18 @@ func AddConfigLinks(frame data.Frame, dl string, title *string) data.Frame {
// 4. the ds toggle is set to true
func meetsBasicLogsCriteria(resources []string, fromAlert bool, basicLogsEnabled bool) (bool, error) {
if fromAlert {
return false, errorsource.DownstreamError(fmt.Errorf("basic Logs queries cannot be used for alerts"), false)
return false, backend.DownstreamError(fmt.Errorf("basic Logs queries cannot be used for alerts"))
}
if len(resources) != 1 {
return false, errorsource.DownstreamError(fmt.Errorf("basic logs queries cannot be run against multiple resources"), false)
return false, backend.DownstreamError(fmt.Errorf("basic logs queries cannot be run against multiple resources"))
}
if !strings.Contains(strings.ToLower(resources[0]), "microsoft.operationalinsights/workspaces") {
return false, errorsource.DownstreamError(fmt.Errorf("basic logs queries may only be run against Log Analytics workspaces"), false)
return false, backend.DownstreamError(fmt.Errorf("basic logs queries may only be run against Log Analytics workspaces"))
}
if !basicLogsEnabled {
return false, errorsource.DownstreamError(fmt.Errorf("basic Logs queries are disabled for this data source"), false)
return false, backend.DownstreamError(fmt.Errorf("basic Logs queries are disabled for this data source"))
}
return true, nil

@ -17,7 +17,6 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
@ -25,6 +24,7 @@ import (
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/loganalytics"
azTime "github.com/grafana/grafana/pkg/tsdb/azuremonitor/time"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/utils"
)
// AzureMonitorDatasource calls the Azure Monitor API - one of the four API's supported
@ -55,12 +55,12 @@ func (e *AzureMonitorDatasource) ExecuteTimeSeriesQuery(ctx context.Context, ori
for _, query := range originalQueries {
azureQuery, err := e.buildQuery(query, dsInfo)
if err != nil {
errorsource.AddErrorToResponse(query.RefID, result, err)
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
continue
}
res, err := e.executeQuery(ctx, azureQuery, dsInfo, client, url)
if err != nil {
errorsource.AddErrorToResponse(query.RefID, result, err)
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
continue
}
result.Responses[query.RefID] = *res
@ -284,7 +284,7 @@ func (e *AzureMonitorDatasource) retrieveSubscriptionDetails(cli *http.Client, c
}
if res.StatusCode/100 != 2 {
return "", errorsource.SourceError(backend.ErrorSourceFromHTTPStatus(res.StatusCode), fmt.Errorf("request failed, status: %s, error: %s", res.Status, string(body)), false)
return "", utils.CreateResponseErrorFromStatusCode(res.StatusCode, res.Status, body)
}
var data types.SubscriptionsResponse
@ -321,7 +321,7 @@ func (e *AzureMonitorDatasource) executeQuery(ctx context.Context, query *types.
res, err := cli.Do(req)
if err != nil {
return nil, errorsource.DownstreamError(err, false)
return nil, backend.DownstreamError(err)
}
defer func() {
@ -366,7 +366,7 @@ func (e *AzureMonitorDatasource) unmarshalResponse(res *http.Response) (types.Az
}
if res.StatusCode/100 != 2 {
return types.AzureMonitorResponse{}, errorsource.SourceError(backend.ErrorSourceFromHTTPStatus(res.StatusCode), fmt.Errorf("request failed, status: %s, body: %s", res.Status, string(body)), false)
return types.AzureMonitorResponse{}, utils.CreateResponseErrorFromStatusCode(res.StatusCode, res.Status, body)
}
var data types.AzureMonitorResponse

@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
@ -78,3 +79,11 @@ func ApplySourceFromError(errorMessage error, err error) error {
}
return errorMessage
}
func CreateResponseErrorFromStatusCode(statusCode int, status string, body []byte) error {
statusErr := fmt.Errorf("request failed, status: %s, body: %s", status, string(body))
if backend.ErrorSourceFromHTTPStatus(statusCode) == backend.ErrorSourceDownstream {
return backend.DownstreamError(statusErr)
}
return backend.PluginError(statusErr)
}

@ -0,0 +1,58 @@
package utils
import (
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/stretchr/testify/assert"
)
func TestCreateResponseErrorFromStatusCode(t *testing.T) {
tests := []struct {
name string
statusCode int
status string
body []byte
expectedErrMessage string
expectedType backend.ErrorSource
}{
{
name: "Downstream error for 500 status",
statusCode: 500,
status: "500 Internal Server Error",
body: []byte("body bytes"),
expectedErrMessage: "request failed, status: 500 Internal Server Error, body: body bytes",
expectedType: backend.ErrorSourceDownstream,
},
{
name: "Plugin error for 501 status",
statusCode: 501,
status: "501 Not Implemented",
body: []byte("body bytes"),
expectedErrMessage: "request failed, status: 501 Not Implemented, body: body bytes",
expectedType: backend.ErrorSourcePlugin,
},
{
name: "Downstream error for 502 status",
statusCode: 502,
status: "502 Gateway Error",
body: []byte("body bytes"),
expectedErrMessage: "request failed, status: 502 Gateway Error, body: body bytes",
expectedType: backend.ErrorSourceDownstream,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := CreateResponseErrorFromStatusCode(tt.statusCode, tt.status, tt.body)
assert.Error(t, err)
// Check if error is of type ErrorWithSource
errorWithSource, ok := err.(backend.ErrorWithSource)
assert.True(t, ok, "error should implement ErrorWithSource")
// Validate the source of the error
assert.Equal(t, tt.expectedType, errorWithSource.ErrorSource())
assert.Contains(t, err.Error(), tt.expectedErrMessage)
})
}
}
Loading…
Cancel
Save