use logger context in cloudwatch (#57842)
This commit is contained in:
@@ -26,11 +26,12 @@ import (
|
|||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/clients"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/clients"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/cwlog"
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -71,10 +72,11 @@ const (
|
|||||||
timeSeriesQuery = "timeSeriesQuery"
|
timeSeriesQuery = "timeSeriesQuery"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var logger = log.New("tsdb.cloudwatch")
|
||||||
var aliasFormat = regexp.MustCompile(`\{\{\s*(.+?)\s*\}\}`)
|
var aliasFormat = regexp.MustCompile(`\{\{\s*(.+?)\s*\}\}`)
|
||||||
|
|
||||||
func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, features featuremgmt.FeatureToggles) *CloudWatchService {
|
func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, features featuremgmt.FeatureToggles) *CloudWatchService {
|
||||||
cwlog.Debug("initing")
|
logger.Debug("Initializing")
|
||||||
|
|
||||||
executor := newExecutor(datasource.NewInstanceManager(NewInstanceSettings(httpClientProvider)), cfg, awsds.NewSessionCache(), features)
|
executor := newExecutor(datasource.NewInstanceManager(NewInstanceSettings(httpClientProvider)), cfg, awsds.NewSessionCache(), features)
|
||||||
|
|
||||||
@@ -308,6 +310,7 @@ func (e *cloudWatchExecutor) alertQuery(ctx context.Context, logsClient cloudwat
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *cloudWatchExecutor) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
func (e *cloudWatchExecutor) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||||
|
logger := logger.FromContext(ctx)
|
||||||
/*
|
/*
|
||||||
Unlike many other data sources, with Cloudwatch Logs query requests don't receive the results as the response
|
Unlike many other data sources, with Cloudwatch Logs query requests don't receive the results as the response
|
||||||
to the query, but rather an ID is first returned. Following this, a client is expected to send requests along
|
to the query, but rather an ID is first returned. Following this, a client is expected to send requests along
|
||||||
@@ -333,11 +336,11 @@ func (e *cloudWatchExecutor) QueryData(ctx context.Context, req *backend.QueryDa
|
|||||||
case annotationQuery:
|
case annotationQuery:
|
||||||
result, err = e.executeAnnotationQuery(req.PluginContext, model, q)
|
result, err = e.executeAnnotationQuery(req.PluginContext, model, q)
|
||||||
case logAction:
|
case logAction:
|
||||||
result, err = e.executeLogActions(ctx, req)
|
result, err = e.executeLogActions(ctx, logger, req)
|
||||||
case timeSeriesQuery:
|
case timeSeriesQuery:
|
||||||
fallthrough
|
fallthrough
|
||||||
default:
|
default:
|
||||||
result, err = e.executeTimeSeriesQuery(ctx, req)
|
result, err = e.executeTimeSeriesQuery(ctx, logger, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, err
|
return result, err
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package cwlog
|
|
||||||
|
|
||||||
import "github.com/grafana/grafana/pkg/infra/log"
|
|
||||||
|
|
||||||
var (
|
|
||||||
cwlog = log.New("tsdb.cloudwatch")
|
|
||||||
)
|
|
||||||
|
|
||||||
func Warn(msg string, args ...interface{}) {
|
|
||||||
cwlog.Warn(msg, args)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Debug(msg string, args ...interface{}) {
|
|
||||||
cwlog.Debug(msg, args)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Error(msg string, args ...interface{}) {
|
|
||||||
cwlog.Error(msg, args)
|
|
||||||
}
|
|
||||||
@@ -14,8 +14,9 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/service/cloudwatchlogs/cloudwatchlogsiface"
|
"github.com/aws/aws-sdk-go/service/cloudwatchlogs/cloudwatchlogsiface"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"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/pkg/tsdb/cloudwatch/cwlog"
|
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -54,7 +55,7 @@ func (e *AWSError) Error() string {
|
|||||||
return fmt.Sprintf("%s: %s", e.Code, e.Message)
|
return fmt.Sprintf("%s: %s", e.Code, e.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *cloudWatchExecutor) executeLogActions(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
func (e *cloudWatchExecutor) executeLogActions(ctx context.Context, logger log.Logger, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||||
resp := backend.NewQueryDataResponse()
|
resp := backend.NewQueryDataResponse()
|
||||||
|
|
||||||
resultChan := make(chan backend.Responses, len(req.Queries))
|
resultChan := make(chan backend.Responses, len(req.Queries))
|
||||||
@@ -69,7 +70,7 @@ func (e *cloudWatchExecutor) executeLogActions(ctx context.Context, req *backend
|
|||||||
|
|
||||||
query := query
|
query := query
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
dataframe, err := e.executeLogAction(ectx, model, query, req.PluginContext)
|
dataframe, err := e.executeLogAction(ectx, logger, model, query, req.PluginContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var AWSError *AWSError
|
var AWSError *AWSError
|
||||||
if errors.As(err, &AWSError) {
|
if errors.As(err, &AWSError) {
|
||||||
@@ -109,7 +110,7 @@ func (e *cloudWatchExecutor) executeLogActions(ctx context.Context, req *backend
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *cloudWatchExecutor) executeLogAction(ctx context.Context, model LogQueryJson, query backend.DataQuery, pluginCtx backend.PluginContext) (*data.Frame, error) {
|
func (e *cloudWatchExecutor) executeLogAction(ctx context.Context, logger log.Logger, model LogQueryJson, query backend.DataQuery, pluginCtx backend.PluginContext) (*data.Frame, error) {
|
||||||
instance, err := e.getInstance(pluginCtx)
|
instance, err := e.getInstance(pluginCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -130,7 +131,7 @@ func (e *cloudWatchExecutor) executeLogAction(ctx context.Context, model LogQuer
|
|||||||
case "GetLogGroupFields":
|
case "GetLogGroupFields":
|
||||||
data, err = e.handleGetLogGroupFields(ctx, logsClient, model, query.RefID)
|
data, err = e.handleGetLogGroupFields(ctx, logsClient, model, query.RefID)
|
||||||
case "StartQuery":
|
case "StartQuery":
|
||||||
data, err = e.handleStartQuery(ctx, logsClient, model, query.TimeRange, query.RefID)
|
data, err = e.handleStartQuery(ctx, logger, logsClient, model, query.TimeRange, query.RefID)
|
||||||
case "StopQuery":
|
case "StopQuery":
|
||||||
data, err = e.handleStopQuery(ctx, logsClient, model)
|
data, err = e.handleStopQuery(ctx, logsClient, model)
|
||||||
case "GetQueryResults":
|
case "GetQueryResults":
|
||||||
@@ -235,13 +236,13 @@ func (e *cloudWatchExecutor) executeStartQuery(ctx context.Context, logsClient c
|
|||||||
return logsClient.StartQueryWithContext(ctx, startQueryInput)
|
return logsClient.StartQueryWithContext(ctx, startQueryInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *cloudWatchExecutor) handleStartQuery(ctx context.Context, logsClient cloudwatchlogsiface.CloudWatchLogsAPI,
|
func (e *cloudWatchExecutor) handleStartQuery(ctx context.Context, logger log.Logger, logsClient cloudwatchlogsiface.CloudWatchLogsAPI,
|
||||||
model LogQueryJson, timeRange backend.TimeRange, refID string) (*data.Frame, error) {
|
model LogQueryJson, timeRange backend.TimeRange, refID string) (*data.Frame, error) {
|
||||||
startQueryResponse, err := e.executeStartQuery(ctx, logsClient, model, timeRange)
|
startQueryResponse, err := e.executeStartQuery(ctx, logsClient, model, timeRange)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var awsErr awserr.Error
|
var awsErr awserr.Error
|
||||||
if errors.As(err, &awsErr) && awsErr.Code() == "LimitExceededException" {
|
if errors.As(err, &awsErr) && awsErr.Code() == "LimitExceededException" {
|
||||||
cwlog.Debug("executeStartQuery limit exceeded", "err", awsErr)
|
logger.Debug("executeStartQuery limit exceeded", "err", awsErr)
|
||||||
return nil, &AWSError{Code: limitExceededException, Message: err.Error()}
|
return nil, &AWSError{Code: limitExceededException, Message: err.Error()}
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *cloudWatchExecutor) buildMetricDataInput(startTime time.Time, endTime time.Time,
|
func (e *cloudWatchExecutor) buildMetricDataInput(logger log.Logger, startTime time.Time, endTime time.Time,
|
||||||
queries []*models.CloudWatchQuery) (*cloudwatch.GetMetricDataInput, error) {
|
queries []*models.CloudWatchQuery) (*cloudwatch.GetMetricDataInput, error) {
|
||||||
metricDataInput := &cloudwatch.GetMetricDataInput{
|
metricDataInput := &cloudwatch.GetMetricDataInput{
|
||||||
StartTime: aws.Time(startTime),
|
StartTime: aws.Time(startTime),
|
||||||
@@ -27,7 +28,7 @@ func (e *cloudWatchExecutor) buildMetricDataInput(startTime time.Time, endTime t
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, query := range queries {
|
for _, query := range queries {
|
||||||
metricDataQuery, err := e.buildMetricDataQuery(query)
|
metricDataQuery, err := e.buildMetricDataQuery(logger, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &models.QueryError{Err: err, RefID: query.RefId}
|
return nil, &models.QueryError{Err: err, RefID: query.RefId}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func TestMetricDataInputBuilder(t *testing.T) {
|
|||||||
|
|
||||||
from := now.Add(time.Hour * -2)
|
from := now.Add(time.Hour * -2)
|
||||||
to := now.Add(time.Hour * -1)
|
to := now.Add(time.Hour * -1)
|
||||||
mdi, err := executor.buildMetricDataInput(from, to, []*models.CloudWatchQuery{query})
|
mdi, err := executor.buildMetricDataInput(logger, from, to, []*models.CloudWatchQuery{query})
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
require.NotNil(t, mdi)
|
require.NotNil(t, mdi)
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import (
|
|||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *cloudWatchExecutor) buildMetricDataQuery(query *models.CloudWatchQuery) (*cloudwatch.MetricDataQuery, error) {
|
func (e *cloudWatchExecutor) buildMetricDataQuery(logger log.Logger, query *models.CloudWatchQuery) (*cloudwatch.MetricDataQuery, error) {
|
||||||
mdq := &cloudwatch.MetricDataQuery{
|
mdq := &cloudwatch.MetricDataQuery{
|
||||||
Id: aws.String(query.Id),
|
Id: aws.String(query.Id),
|
||||||
ReturnData: aws.Bool(query.ReturnData),
|
ReturnData: aws.Bool(query.ReturnData),
|
||||||
@@ -22,7 +24,7 @@ func (e *cloudWatchExecutor) buildMetricDataQuery(query *models.CloudWatchQuery)
|
|||||||
mdq.Label = &query.Label
|
mdq.Label = &query.Label
|
||||||
}
|
}
|
||||||
|
|
||||||
switch query.GetGMDAPIMode() {
|
switch query.GetGMDAPIMode(logger) {
|
||||||
case models.GMDApiModeMathExpression:
|
case models.GMDApiModeMathExpression:
|
||||||
mdq.Period = aws.Int64(int64(query.Period))
|
mdq.Period = aws.Int64(int64(query.Period))
|
||||||
mdq.Expression = aws.String(query.Expression)
|
mdq.Expression = aws.String(query.Expression)
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ package cloudwatch
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMetricDataQueryBuilder(t *testing.T) {
|
func TestMetricDataQueryBuilder(t *testing.T) {
|
||||||
@@ -16,7 +17,7 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
|||||||
query := getBaseQuery()
|
query := getBaseQuery()
|
||||||
query.MetricEditorMode = models.MetricEditorModeBuilder
|
query.MetricEditorMode = models.MetricEditorModeBuilder
|
||||||
query.MetricQueryType = models.MetricQueryTypeSearch
|
query.MetricQueryType = models.MetricQueryTypeSearch
|
||||||
mdq, err := executor.buildMetricDataQuery(query)
|
mdq, err := executor.buildMetricDataQuery(logger, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Empty(t, mdq.Expression)
|
require.Empty(t, mdq.Expression)
|
||||||
assert.Equal(t, query.MetricName, *mdq.MetricStat.Metric.MetricName)
|
assert.Equal(t, query.MetricName, *mdq.MetricStat.Metric.MetricName)
|
||||||
@@ -29,7 +30,7 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
|||||||
query.MetricEditorMode = models.MetricEditorModeBuilder
|
query.MetricEditorMode = models.MetricEditorModeBuilder
|
||||||
query.MetricQueryType = models.MetricQueryTypeSearch
|
query.MetricQueryType = models.MetricQueryTypeSearch
|
||||||
query.MatchExact = false
|
query.MatchExact = false
|
||||||
mdq, err := executor.buildMetricDataQuery(query)
|
mdq, err := executor.buildMetricDataQuery(logger, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Nil(t, mdq.MetricStat)
|
require.Nil(t, mdq.MetricStat)
|
||||||
assert.Equal(t, `REMOVE_EMPTY(SEARCH('Namespace="AWS/EC2" MetricName="CPUUtilization" "LoadBalancer"="lb1"', '', 300))`, *mdq.Expression)
|
assert.Equal(t, `REMOVE_EMPTY(SEARCH('Namespace="AWS/EC2" MetricName="CPUUtilization" "LoadBalancer"="lb1"', '', 300))`, *mdq.Expression)
|
||||||
@@ -41,7 +42,7 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
|||||||
query.MetricEditorMode = models.MetricEditorModeRaw
|
query.MetricEditorMode = models.MetricEditorModeRaw
|
||||||
query.MetricQueryType = models.MetricQueryTypeQuery
|
query.MetricQueryType = models.MetricQueryTypeQuery
|
||||||
query.SqlExpression = `SELECT SUM(CPUUTilization) FROM "AWS/EC2"`
|
query.SqlExpression = `SELECT SUM(CPUUTilization) FROM "AWS/EC2"`
|
||||||
mdq, err := executor.buildMetricDataQuery(query)
|
mdq, err := executor.buildMetricDataQuery(logger, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Nil(t, mdq.MetricStat)
|
require.Nil(t, mdq.MetricStat)
|
||||||
assert.Equal(t, query.SqlExpression, *mdq.Expression)
|
assert.Equal(t, query.SqlExpression, *mdq.Expression)
|
||||||
@@ -53,7 +54,7 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
|||||||
query.MetricEditorMode = models.MetricEditorModeRaw
|
query.MetricEditorMode = models.MetricEditorModeRaw
|
||||||
query.MetricQueryType = models.MetricQueryTypeSearch
|
query.MetricQueryType = models.MetricQueryTypeSearch
|
||||||
query.Expression = `SUM(x+y)`
|
query.Expression = `SUM(x+y)`
|
||||||
mdq, err := executor.buildMetricDataQuery(query)
|
mdq, err := executor.buildMetricDataQuery(logger, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Nil(t, mdq.MetricStat)
|
require.Nil(t, mdq.MetricStat)
|
||||||
assert.Equal(t, query.Expression, *mdq.Expression)
|
assert.Equal(t, query.Expression, *mdq.Expression)
|
||||||
@@ -66,7 +67,7 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
|||||||
query.MetricQueryType = models.MetricQueryTypeSearch
|
query.MetricQueryType = models.MetricQueryTypeSearch
|
||||||
query.MatchExact = false
|
query.MatchExact = false
|
||||||
query.Expression = `SUM([a,b])`
|
query.Expression = `SUM([a,b])`
|
||||||
mdq, err := executor.buildMetricDataQuery(query)
|
mdq, err := executor.buildMetricDataQuery(logger, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Nil(t, mdq.MetricStat)
|
require.Nil(t, mdq.MetricStat)
|
||||||
assert.Equal(t, int64(300), *mdq.Period)
|
assert.Equal(t, int64(300), *mdq.Period)
|
||||||
@@ -78,7 +79,7 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
|||||||
query := getBaseQuery()
|
query := getBaseQuery()
|
||||||
query.Label = "some label"
|
query.Label = "some label"
|
||||||
|
|
||||||
mdq, err := executor.buildMetricDataQuery(query)
|
mdq, err := executor.buildMetricDataQuery(logger, query)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
require.NotNil(t, mdq.Label)
|
require.NotNil(t, mdq.Label)
|
||||||
@@ -105,7 +106,7 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
|||||||
query := getBaseQuery()
|
query := getBaseQuery()
|
||||||
query.Label = tc.label
|
query.Label = tc.label
|
||||||
|
|
||||||
mdq, err := executor.buildMetricDataQuery(query)
|
mdq, err := executor.buildMetricDataQuery(logger, query)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Nil(t, mdq.Label)
|
assert.Nil(t, mdq.Label)
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
|
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/constants"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/constants"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/cwlog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type suggestData struct {
|
type suggestData struct {
|
||||||
@@ -66,7 +66,7 @@ func (e *cloudWatchExecutor) handleGetRegions(pluginCtx backend.PluginContext, p
|
|||||||
r, err := client.DescribeRegions(&ec2.DescribeRegionsInput{})
|
r, err := client.DescribeRegions(&ec2.DescribeRegionsInput{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// ignore error for backward compatibility
|
// ignore error for backward compatibility
|
||||||
cwlog.Error("Failed to get regions", "error", err)
|
logger.Error("Failed to get regions", "error", err)
|
||||||
} else {
|
} else {
|
||||||
for _, region := range r.Regions {
|
for _, region := range r.Regions {
|
||||||
exists := false
|
exists := false
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ import (
|
|||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/cwlog"
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -61,7 +62,7 @@ type CloudWatchQuery struct {
|
|||||||
MetricEditorMode MetricEditorMode
|
MetricEditorMode MetricEditorMode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *CloudWatchQuery) GetGMDAPIMode() GMDApiMode {
|
func (q *CloudWatchQuery) GetGMDAPIMode(logger log.Logger) GMDApiMode {
|
||||||
if q.MetricQueryType == MetricQueryTypeSearch && q.MetricEditorMode == MetricEditorModeBuilder {
|
if q.MetricQueryType == MetricQueryTypeSearch && q.MetricEditorMode == MetricEditorModeBuilder {
|
||||||
if q.IsInferredSearchExpression() {
|
if q.IsInferredSearchExpression() {
|
||||||
return GMDApiModeInferredSearchExpression
|
return GMDApiModeInferredSearchExpression
|
||||||
@@ -73,7 +74,7 @@ func (q *CloudWatchQuery) GetGMDAPIMode() GMDApiMode {
|
|||||||
return GMDApiModeSQLExpression
|
return GMDApiModeSQLExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
cwlog.Warn("could not resolve CloudWatch metric query type. Falling back to metric stat.", "query", q)
|
logger.Warn("could not resolve CloudWatch metric query type. Falling back to metric stat.", "query", q)
|
||||||
return GMDApiModeMetricStat
|
return GMDApiModeMetricStat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import (
|
|||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log/logtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCloudWatchQuery(t *testing.T) {
|
func TestCloudWatchQuery(t *testing.T) {
|
||||||
@@ -642,7 +644,7 @@ func Test_ParseMetricDataQueries_query_type_and_metric_editor_mode_and_GMD_query
|
|||||||
require.NotNil(t, res[0])
|
require.NotNil(t, res[0])
|
||||||
assert.Equal(t, tc.expectedMetricQueryType, res[0].MetricQueryType)
|
assert.Equal(t, tc.expectedMetricQueryType, res[0].MetricQueryType)
|
||||||
assert.Equal(t, tc.expectedMetricEditorMode, res[0].MetricEditorMode)
|
assert.Equal(t, tc.expectedMetricEditorMode, res[0].MetricEditorMode)
|
||||||
assert.Equal(t, tc.expectedGMDApiMode, res[0].GetGMDAPIMode())
|
assert.Equal(t, tc.expectedGMDApiMode, res[0].GetGMDAPIMode(&logtest.Fake{}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ 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/resource/httpadapter"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/cwlog"
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/routes"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/routes"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,10 +20,10 @@ func (e *cloudWatchExecutor) newResourceMux() *http.ServeMux {
|
|||||||
mux.HandleFunc("/resource-arns", handleResourceReq(e.handleGetResourceArns))
|
mux.HandleFunc("/resource-arns", handleResourceReq(e.handleGetResourceArns))
|
||||||
mux.HandleFunc("/log-groups", handleResourceReq(e.handleGetLogGroups))
|
mux.HandleFunc("/log-groups", handleResourceReq(e.handleGetLogGroups))
|
||||||
mux.HandleFunc("/all-log-groups", handleResourceReq(e.handleGetAllLogGroups))
|
mux.HandleFunc("/all-log-groups", handleResourceReq(e.handleGetAllLogGroups))
|
||||||
mux.HandleFunc("/metrics", routes.ResourceRequestMiddleware(routes.MetricsHandler, e.getRequestContext))
|
mux.HandleFunc("/metrics", routes.ResourceRequestMiddleware(routes.MetricsHandler, logger, e.getRequestContext))
|
||||||
mux.HandleFunc("/dimension-values", routes.ResourceRequestMiddleware(routes.DimensionValuesHandler, e.getRequestContext))
|
mux.HandleFunc("/dimension-values", routes.ResourceRequestMiddleware(routes.DimensionValuesHandler, logger, e.getRequestContext))
|
||||||
mux.HandleFunc("/dimension-keys", routes.ResourceRequestMiddleware(routes.DimensionKeysHandler, e.getRequestContext))
|
mux.HandleFunc("/dimension-keys", routes.ResourceRequestMiddleware(routes.DimensionKeysHandler, logger, e.getRequestContext))
|
||||||
mux.HandleFunc("/namespaces", routes.ResourceRequestMiddleware(routes.NamespacesHandler, e.getRequestContext))
|
mux.HandleFunc("/namespaces", routes.ResourceRequestMiddleware(routes.NamespacesHandler, logger, e.getRequestContext))
|
||||||
return mux
|
return mux
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ func handleResourceReq(handleFunc handleFn) func(rw http.ResponseWriter, req *ht
|
|||||||
rw.WriteHeader(http.StatusOK)
|
rw.WriteHeader(http.StatusOK)
|
||||||
_, err = rw.Write(body)
|
_, err = rw.Write(body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cwlog.Error("Unable to write HTTP response", "error", err)
|
logger.Error("Unable to write HTTP response", "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,6 +57,6 @@ func writeResponse(rw http.ResponseWriter, code int, msg string) {
|
|||||||
rw.WriteHeader(code)
|
rw.WriteHeader(code)
|
||||||
_, err := rw.Write([]byte(msg))
|
_, err := rw.Write([]byte(msg))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cwlog.Error("Unable to write HTTP response", "error", err)
|
logger.Error("Unable to write HTTP response", "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,17 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log/logtest"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/services"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/services"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var logger = &logtest.Fake{}
|
||||||
|
|
||||||
func Test_DimensionKeys_Route(t *testing.T) {
|
func Test_DimensionKeys_Route(t *testing.T) {
|
||||||
t.Run("calls FilterDimensionKeysRequest when a StandardDimensionKeysRequest is passed", func(t *testing.T) {
|
t.Run("calls FilterDimensionKeysRequest when a StandardDimensionKeysRequest is passed", func(t *testing.T) {
|
||||||
mockListMetricsService := mocks.ListMetricsServiceMock{}
|
mockListMetricsService := mocks.ListMetricsServiceMock{}
|
||||||
@@ -24,7 +28,7 @@ func Test_DimensionKeys_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", `/dimension-keys?region=us-east-2&namespace=AWS/EC2&metricName=CPUUtilization&dimensionFilters={"NodeID":["Shared"],"stage":["QueryCommit"]}`, nil)
|
req := httptest.NewRequest("GET", `/dimension-keys?region=us-east-2&namespace=AWS/EC2&metricName=CPUUtilization&dimensionFilters={"NodeID":["Shared"],"stage":["QueryCommit"]}`, nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionKeysHandler, nil))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionKeysHandler, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
mockListMetricsService.AssertNumberOfCalls(t, "GetDimensionKeysByDimensionFilter", 1)
|
mockListMetricsService.AssertNumberOfCalls(t, "GetDimensionKeysByDimensionFilter", 1)
|
||||||
})
|
})
|
||||||
@@ -37,7 +41,7 @@ func Test_DimensionKeys_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", `/dimension-keys?region=us-east-2&namespace=custom&metricName=CPUUtilization`, nil)
|
req := httptest.NewRequest("GET", `/dimension-keys?region=us-east-2&namespace=custom&metricName=CPUUtilization`, nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionKeysHandler, nil))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionKeysHandler, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
mockListMetricsService.AssertNumberOfCalls(t, "GetDimensionKeysByNamespace", 1)
|
mockListMetricsService.AssertNumberOfCalls(t, "GetDimensionKeysByNamespace", 1)
|
||||||
})
|
})
|
||||||
@@ -56,7 +60,7 @@ func Test_DimensionKeys_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", "/dimension-keys?region=us-east-2&namespace=AWS/EC2&metricName=CPUUtilization", nil)
|
req := httptest.NewRequest("GET", "/dimension-keys?region=us-east-2&namespace=AWS/EC2&metricName=CPUUtilization", nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionKeysHandler, nil))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionKeysHandler, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
res := []models.Metric{}
|
res := []models.Metric{}
|
||||||
err := json.Unmarshal(rr.Body.Bytes(), &res)
|
err := json.Unmarshal(rr.Body.Bytes(), &res)
|
||||||
@@ -73,7 +77,7 @@ func Test_DimensionKeys_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", `/dimension-keys?region=us-east-2&namespace=AWS/EC2&metricName=CPUUtilization&dimensionFilters={"NodeID":["Shared"],"stage":["QueryCommit"]}`, nil)
|
req := httptest.NewRequest("GET", `/dimension-keys?region=us-east-2&namespace=AWS/EC2&metricName=CPUUtilization&dimensionFilters={"NodeID":["Shared"],"stage":["QueryCommit"]}`, nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionKeysHandler, nil))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionKeysHandler, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
||||||
assert.Equal(t, `{"Message":"error in DimensionKeyHandler: some error","Error":"some error","StatusCode":500}`, rr.Body.String())
|
assert.Equal(t, `{"Message":"error in DimensionKeyHandler: some error","Error":"some error","StatusCode":500}`, rr.Body.String())
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_DimensionValues_Route(t *testing.T) {
|
func Test_DimensionValues_Route(t *testing.T) {
|
||||||
@@ -21,7 +22,7 @@ func Test_DimensionValues_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", `/dimension-values?region=us-east-2&dimensionKey=instanceId&namespace=AWS/EC2&metricName=CPUUtilization&dimensionFilters={"NodeID":["Shared"],"stage":["QueryCommit"]}`, nil)
|
req := httptest.NewRequest("GET", `/dimension-values?region=us-east-2&dimensionKey=instanceId&namespace=AWS/EC2&metricName=CPUUtilization&dimensionFilters={"NodeID":["Shared"],"stage":["QueryCommit"]}`, nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionValuesHandler, nil))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionValuesHandler, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ func Test_DimensionValues_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", `/dimension-values?region=us-east-2&dimensionKey=instanceId&namespace=AWS/EC2&metricName=CPUUtilization&dimensionFilters={"NodeID":["Shared"],"stage":["QueryCommit"]}`, nil)
|
req := httptest.NewRequest("GET", `/dimension-values?region=us-east-2&dimensionKey=instanceId&namespace=AWS/EC2&metricName=CPUUtilization&dimensionFilters={"NodeID":["Shared"],"stage":["QueryCommit"]}`, nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionValuesHandler, nil))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(DimensionValuesHandler, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
||||||
assert.Equal(t, `{"Message":"error in DimensionValuesHandler: some error","Error":"some error","StatusCode":500}`, rr.Body.String())
|
assert.Equal(t, `{"Message":"error in DimensionValuesHandler: some error","Error":"some error","StatusCode":500}`, rr.Body.String())
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/services"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/services"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_Metrics_Route(t *testing.T) {
|
func Test_Metrics_Route(t *testing.T) {
|
||||||
@@ -24,7 +25,7 @@ func Test_Metrics_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", "/metrics?region=us-east-2&namespace=customNamespace", nil)
|
req := httptest.NewRequest("GET", "/metrics?region=us-east-2&namespace=customNamespace", nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(MetricsHandler, nil))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(MetricsHandler, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
mockListMetricsService.AssertNumberOfCalls(t, "GetMetricsByNamespace", 1)
|
mockListMetricsService.AssertNumberOfCalls(t, "GetMetricsByNamespace", 1)
|
||||||
})
|
})
|
||||||
@@ -41,7 +42,7 @@ func Test_Metrics_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", "/metrics?region=us-east-2", nil)
|
req := httptest.NewRequest("GET", "/metrics?region=us-east-2", nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(MetricsHandler, nil))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(MetricsHandler, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
res := []models.Metric{}
|
res := []models.Metric{}
|
||||||
err := json.Unmarshal(rr.Body.Bytes(), &res)
|
err := json.Unmarshal(rr.Body.Bytes(), &res)
|
||||||
@@ -63,7 +64,7 @@ func Test_Metrics_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", "/metrics?region=us-east-2&namespace=AWS/DMS", nil)
|
req := httptest.NewRequest("GET", "/metrics?region=us-east-2&namespace=AWS/DMS", nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(MetricsHandler, nil))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(MetricsHandler, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
res := []models.Metric{}
|
res := []models.Metric{}
|
||||||
err := json.Unmarshal(rr.Body.Bytes(), &res)
|
err := json.Unmarshal(rr.Body.Bytes(), &res)
|
||||||
@@ -80,7 +81,7 @@ func Test_Metrics_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", "/metrics?region=us-east-2&namespace=customNamespace", nil)
|
req := httptest.NewRequest("GET", "/metrics?region=us-east-2&namespace=customNamespace", nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(MetricsHandler, nil))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(MetricsHandler, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
||||||
assert.Equal(t, `{"Message":"error in MetricsHandler: some error","Error":"some error","StatusCode":500}`, rr.Body.String())
|
assert.Equal(t, `{"Message":"error in MetricsHandler: some error","Error":"some error","StatusCode":500}`, rr.Body.String())
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/cwlog"
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ResourceRequestMiddleware(handleFunc models.RouteHandlerFunc, reqCtxFactory models.RequestContextFactoryFunc) func(rw http.ResponseWriter, req *http.Request) {
|
func ResourceRequestMiddleware(handleFunc models.RouteHandlerFunc, logger log.Logger, reqCtxFactory models.RequestContextFactoryFunc) func(rw http.ResponseWriter, req *http.Request) {
|
||||||
return func(rw http.ResponseWriter, req *http.Request) {
|
return func(rw http.ResponseWriter, req *http.Request) {
|
||||||
if req.Method != "GET" {
|
if req.Method != "GET" {
|
||||||
respondWithError(rw, models.NewHttpError("Invalid method", http.StatusMethodNotAllowed, nil))
|
respondWithError(rw, models.NewHttpError("Invalid method", http.StatusMethodNotAllowed, nil))
|
||||||
@@ -19,7 +20,7 @@ func ResourceRequestMiddleware(handleFunc models.RouteHandlerFunc, reqCtxFactory
|
|||||||
pluginContext := httpadapter.PluginConfigFromContext(ctx)
|
pluginContext := httpadapter.PluginConfigFromContext(ctx)
|
||||||
json, httpError := handleFunc(pluginContext, reqCtxFactory, req.URL.Query())
|
json, httpError := handleFunc(pluginContext, reqCtxFactory, req.URL.Query())
|
||||||
if httpError != nil {
|
if httpError != nil {
|
||||||
cwlog.Error("error handling resource request", "error", httpError.Message)
|
logger.Error("error handling resource request", "error", httpError.Message)
|
||||||
respondWithError(rw, httpError)
|
respondWithError(rw, httpError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -27,7 +28,7 @@ func ResourceRequestMiddleware(handleFunc models.RouteHandlerFunc, reqCtxFactory
|
|||||||
rw.Header().Set("Content-Type", "application/json")
|
rw.Header().Set("Content-Type", "application/json")
|
||||||
_, err := rw.Write(json)
|
_, err := rw.Write(json)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cwlog.Error("error handling resource request", "error", err)
|
logger.Error("error handling resource request", "error", err)
|
||||||
respondWithError(rw, models.NewHttpError("error writing response in resource request middleware", http.StatusInternalServerError, err))
|
respondWithError(rw, models.NewHttpError("error writing response in resource request middleware", http.StatusInternalServerError, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_Middleware(t *testing.T) {
|
func Test_Middleware(t *testing.T) {
|
||||||
@@ -18,7 +19,7 @@ func Test_Middleware(t *testing.T) {
|
|||||||
req := httptest.NewRequest("POST", "/dimension-keys?region=us-east-1", nil)
|
req := httptest.NewRequest("POST", "/dimension-keys?region=us-east-1", nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(func(pluginCtx backend.PluginContext, reqCtxFactory models.RequestContextFactoryFunc, parameters url.Values) ([]byte, *models.HttpError) {
|
handler := http.HandlerFunc(ResourceRequestMiddleware(func(pluginCtx backend.PluginContext, reqCtxFactory models.RequestContextFactoryFunc, parameters url.Values) ([]byte, *models.HttpError) {
|
||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
}, nil))
|
}, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
assert.Equal(t, http.StatusMethodNotAllowed, rr.Code)
|
assert.Equal(t, http.StatusMethodNotAllowed, rr.Code)
|
||||||
})
|
})
|
||||||
@@ -30,7 +31,7 @@ func Test_Middleware(t *testing.T) {
|
|||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(func(pluginCtx backend.PluginContext, reqCtxFactory models.RequestContextFactoryFunc, parameters url.Values) ([]byte, *models.HttpError) {
|
handler := http.HandlerFunc(ResourceRequestMiddleware(func(pluginCtx backend.PluginContext, reqCtxFactory models.RequestContextFactoryFunc, parameters url.Values) ([]byte, *models.HttpError) {
|
||||||
testPluginContext = pluginCtx
|
testPluginContext = pluginCtx
|
||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
}, nil))
|
}, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
assert.NotNil(t, testPluginContext)
|
assert.NotNil(t, testPluginContext)
|
||||||
})
|
})
|
||||||
@@ -40,7 +41,7 @@ func Test_Middleware(t *testing.T) {
|
|||||||
req := httptest.NewRequest("GET", "/some-path", nil)
|
req := httptest.NewRequest("GET", "/some-path", nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(func(pluginCtx backend.PluginContext, reqCtxFactory models.RequestContextFactoryFunc, parameters url.Values) ([]byte, *models.HttpError) {
|
handler := http.HandlerFunc(ResourceRequestMiddleware(func(pluginCtx backend.PluginContext, reqCtxFactory models.RequestContextFactoryFunc, parameters url.Values) ([]byte, *models.HttpError) {
|
||||||
return []byte{}, models.NewHttpError("error", http.StatusBadRequest, fmt.Errorf("error from handler"))
|
return []byte{}, models.NewHttpError("error", http.StatusBadRequest, fmt.Errorf("error from handler"))
|
||||||
}, nil))
|
}, logger, nil))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||||
assert.Equal(t, `{"Message":"error: error from handler","Error":"error from handler","StatusCode":400}`, rr.Body.String())
|
assert.Equal(t, `{"Message":"error: error from handler","Error":"error from handler","StatusCode":400}`, rr.Body.String())
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/services"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/services"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_Namespaces_Route(t *testing.T) {
|
func Test_Namespaces_Route(t *testing.T) {
|
||||||
@@ -33,7 +34,7 @@ func Test_Namespaces_Route(t *testing.T) {
|
|||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", "/namespaces", nil)
|
req := httptest.NewRequest("GET", "/namespaces", nil)
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(NamespacesHandler, factoryFunc))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(NamespacesHandler, logger, factoryFunc))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
assert.True(t, haveBeenCalled)
|
assert.True(t, haveBeenCalled)
|
||||||
})
|
})
|
||||||
@@ -49,7 +50,7 @@ func Test_Namespaces_Route(t *testing.T) {
|
|||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", "/namespaces", nil)
|
req := httptest.NewRequest("GET", "/namespaces", nil)
|
||||||
customNamespaces = "customNamespace1,customNamespace2"
|
customNamespaces = "customNamespace1,customNamespace2"
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(NamespacesHandler, factoryFunc))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(NamespacesHandler, logger, factoryFunc))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
assert.JSONEq(t, `["AWS/EC2", "AWS/ELB", "customNamespace1", "customNamespace2"]`, rr.Body.String())
|
assert.JSONEq(t, `["AWS/EC2", "AWS/ELB", "customNamespace1", "customNamespace2"]`, rr.Body.String())
|
||||||
})
|
})
|
||||||
@@ -65,7 +66,7 @@ func Test_Namespaces_Route(t *testing.T) {
|
|||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
req := httptest.NewRequest("GET", "/namespaces", nil)
|
req := httptest.NewRequest("GET", "/namespaces", nil)
|
||||||
customNamespaces = "DCustomNamespace1,ACustomNamespace2"
|
customNamespaces = "DCustomNamespace1,ACustomNamespace2"
|
||||||
handler := http.HandlerFunc(ResourceRequestMiddleware(NamespacesHandler, factoryFunc))
|
handler := http.HandlerFunc(ResourceRequestMiddleware(NamespacesHandler, logger, factoryFunc))
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
assert.JSONEq(t, `["ACustomNamespace2", "AWS/ELB", "AWS/XYZ", "DCustomNamespace1"]`, rr.Body.String())
|
assert.JSONEq(t, `["ACustomNamespace2", "AWS/ELB", "AWS/XYZ", "DCustomNamespace1"]`, rr.Body.String())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/cwlog"
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type responseWrapper struct {
|
type responseWrapper struct {
|
||||||
@@ -17,8 +17,8 @@ type responseWrapper struct {
|
|||||||
RefId string
|
RefId string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, logger log.Logger, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||||
cwlog.Debug("Executing time series query")
|
logger.Debug("Executing time series query")
|
||||||
resp := backend.NewQueryDataResponse()
|
resp := backend.NewQueryDataResponse()
|
||||||
|
|
||||||
if len(req.Queries) == 0 {
|
if len(req.Queries) == 0 {
|
||||||
@@ -56,7 +56,7 @@ func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, req *ba
|
|||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
cwlog.Error("Execute Get Metric Data Query Panic", "error", err, "stack", log.Stack(1))
|
logger.Error("Execute Get Metric Data Query Panic", "error", err, "stack", log.Stack(1))
|
||||||
if theErr, ok := err.(error); ok {
|
if theErr, ok := err.(error); ok {
|
||||||
resultChan <- &responseWrapper{
|
resultChan <- &responseWrapper{
|
||||||
DataResponse: &backend.DataResponse{
|
DataResponse: &backend.DataResponse{
|
||||||
@@ -72,7 +72,7 @@ func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, req *ba
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
metricDataInput, err := e.buildMetricDataInput(startTime, endTime, requestQueries)
|
metricDataInput, err := e.buildMetricDataInput(logger, startTime, endTime, requestQueries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ func TestTimeSeriesQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("End time before start time should result in error", func(t *testing.T) {
|
t.Run("End time before start time should result in error", func(t *testing.T) {
|
||||||
_, err := executor.executeTimeSeriesQuery(context.Background(), &backend.QueryDataRequest{Queries: []backend.DataQuery{{TimeRange: backend.TimeRange{
|
_, err := executor.executeTimeSeriesQuery(context.Background(), logger, &backend.QueryDataRequest{Queries: []backend.DataQuery{{TimeRange: backend.TimeRange{
|
||||||
From: now.Add(time.Hour * -1),
|
From: now.Add(time.Hour * -1),
|
||||||
To: now.Add(time.Hour * -2),
|
To: now.Add(time.Hour * -2),
|
||||||
}}}})
|
}}}})
|
||||||
@@ -134,7 +134,7 @@ func TestTimeSeriesQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("End time equals start time should result in error", func(t *testing.T) {
|
t.Run("End time equals start time should result in error", func(t *testing.T) {
|
||||||
_, err := executor.executeTimeSeriesQuery(context.Background(), &backend.QueryDataRequest{Queries: []backend.DataQuery{{TimeRange: backend.TimeRange{
|
_, err := executor.executeTimeSeriesQuery(context.Background(), logger, &backend.QueryDataRequest{Queries: []backend.DataQuery{{TimeRange: backend.TimeRange{
|
||||||
From: now.Add(time.Hour * -1),
|
From: now.Add(time.Hour * -1),
|
||||||
To: now.Add(time.Hour * -1),
|
To: now.Add(time.Hour * -1),
|
||||||
}}}})
|
}}}})
|
||||||
|
|||||||
Reference in New Issue
Block a user