mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Update azure monitor
This commit is contained in:
parent
348c8fa927
commit
21b53845b8
@ -18,7 +18,6 @@ import (
|
|||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"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/attribute"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
@ -142,12 +141,12 @@ func (e *AzureLogAnalyticsDatasource) ExecuteTimeSeriesQuery(ctx context.Context
|
|||||||
for _, query := range originalQueries {
|
for _, query := range originalQueries {
|
||||||
logsQuery, err := e.buildQuery(ctx, query, dsInfo, fromAlert)
|
logsQuery, err := e.buildQuery(ctx, query, dsInfo, fromAlert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorsource.AddErrorToResponse(query.RefID, result, err)
|
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
res, err := e.executeQuery(ctx, logsQuery, dsInfo, client, url)
|
res, err := e.executeQuery(ctx, logsQuery, dsInfo, client, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorsource.AddErrorToResponse(query.RefID, result, err)
|
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
result.Responses[query.RefID] = *res
|
result.Responses[query.RefID] = *res
|
||||||
@ -252,7 +251,7 @@ func (e *AzureLogAnalyticsDatasource) buildQuery(ctx context.Context, query back
|
|||||||
cfg := backend.GrafanaConfigFromContext(ctx)
|
cfg := backend.GrafanaConfigFromContext(ctx)
|
||||||
hasPromExemplarsToggle := cfg.FeatureToggles().IsEnabled("azureMonitorPrometheusExemplars")
|
hasPromExemplarsToggle := cfg.FeatureToggles().IsEnabled("azureMonitorPrometheusExemplars")
|
||||||
if !hasPromExemplarsToggle {
|
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)
|
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) {
|
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 azureLogAnalyticsSameAs is defined and set to false, return an error
|
||||||
if sameAs, ok := dsInfo.JSONData["azureLogAnalyticsSameAs"]; ok && !sameAs.(bool) {
|
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{}
|
queryJSONModel := dataquery.AzureMonitorQuery{}
|
||||||
@ -280,7 +279,7 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *A
|
|||||||
|
|
||||||
if query.QueryType == dataquery.AzureQueryTypeAzureTraces {
|
if query.QueryType == dataquery.AzureQueryTypeAzureTraces {
|
||||||
if query.ResultFormat == dataquery.ResultFormatTrace && query.Query == "" {
|
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)
|
res, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errorsource.DownstreamError(err, false)
|
return nil, backend.DownstreamError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -597,11 +596,11 @@ func getCorrelationWorkspaces(ctx context.Context, baseResource string, resource
|
|||||||
|
|
||||||
res, err := azMonService.HTTPClient.Do(req)
|
res, err := azMonService.HTTPClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return AzureCorrelationAPIResponse{}, errorsource.DownstreamError(err, false)
|
return AzureCorrelationAPIResponse{}, backend.DownstreamError(err)
|
||||||
}
|
}
|
||||||
body, err := io.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return AzureCorrelationAPIResponse{}, errorsource.DownstreamError(err, false)
|
return AzureCorrelationAPIResponse{}, backend.DownstreamError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -611,7 +610,7 @@ func getCorrelationWorkspaces(ctx context.Context, baseResource string, resource
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
if res.StatusCode/100 != 2 {
|
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
|
var data AzureCorrelationAPIResponse
|
||||||
d := json.NewDecoder(bytes.NewReader(body))
|
d := json.NewDecoder(bytes.NewReader(body))
|
||||||
@ -675,7 +674,7 @@ func (e *AzureLogAnalyticsDatasource) unmarshalResponse(res *http.Response) (Azu
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
if res.StatusCode/100 != 2 {
|
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
|
var data AzureLogAnalyticsResponse
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"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"
|
"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
|
// 4. the ds toggle is set to true
|
||||||
func meetsBasicLogsCriteria(resources []string, fromAlert bool, basicLogsEnabled bool) (bool, error) {
|
func meetsBasicLogsCriteria(resources []string, fromAlert bool, basicLogsEnabled bool) (bool, error) {
|
||||||
if fromAlert {
|
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 {
|
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") {
|
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 {
|
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
|
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/log"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"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/attribute"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
@ -25,6 +24,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/loganalytics"
|
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/loganalytics"
|
||||||
azTime "github.com/grafana/grafana/pkg/tsdb/azuremonitor/time"
|
azTime "github.com/grafana/grafana/pkg/tsdb/azuremonitor/time"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
"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
|
// 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 {
|
for _, query := range originalQueries {
|
||||||
azureQuery, err := e.buildQuery(query, dsInfo)
|
azureQuery, err := e.buildQuery(query, dsInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorsource.AddErrorToResponse(query.RefID, result, err)
|
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
res, err := e.executeQuery(ctx, azureQuery, dsInfo, client, url)
|
res, err := e.executeQuery(ctx, azureQuery, dsInfo, client, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorsource.AddErrorToResponse(query.RefID, result, err)
|
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
result.Responses[query.RefID] = *res
|
result.Responses[query.RefID] = *res
|
||||||
@ -284,7 +284,7 @@ func (e *AzureMonitorDatasource) retrieveSubscriptionDetails(cli *http.Client, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
if res.StatusCode/100 != 2 {
|
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
|
var data types.SubscriptionsResponse
|
||||||
@ -321,7 +321,7 @@ func (e *AzureMonitorDatasource) executeQuery(ctx context.Context, query *types.
|
|||||||
|
|
||||||
res, err := cli.Do(req)
|
res, err := cli.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errorsource.DownstreamError(err, false)
|
return nil, backend.DownstreamError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -366,7 +366,7 @@ func (e *AzureMonitorDatasource) unmarshalResponse(res *http.Response) (types.Az
|
|||||||
}
|
}
|
||||||
|
|
||||||
if res.StatusCode/100 != 2 {
|
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
|
var data types.AzureMonitorResponse
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"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/backend/log"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
||||||
@ -78,3 +79,11 @@ func ApplySourceFromError(errorMessage error, err error) error {
|
|||||||
}
|
}
|
||||||
return errorMessage
|
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)
|
||||||
|
}
|
||||||
|
58
pkg/tsdb/azuremonitor/utils/utils_test.go
Normal file
58
pkg/tsdb/azuremonitor/utils/utils_test.go
Normal file
@ -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…
Reference in New Issue
Block a user