diff --git a/pkg/tsdb/cloudwatch/annotation_query_test.go b/pkg/tsdb/cloudwatch/annotation_query_test.go index b1905bb8455..2aeab655b70 100644 --- a/pkg/tsdb/cloudwatch/annotation_query_test.go +++ b/pkg/tsdb/cloudwatch/annotation_query_test.go @@ -10,6 +10,7 @@ import ( "github.com/aws/aws-sdk-go/service/cloudwatch" "github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface" "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -29,7 +30,7 @@ func TestQuery_AnnotationQuery(t *testing.T) { client = fakeCWAnnotationsClient{describeAlarmsForMetricOutput: &cloudwatch.DescribeAlarmsForMetricOutput{}} im := defaultTestInstanceManager() - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, @@ -61,7 +62,7 @@ func TestQuery_AnnotationQuery(t *testing.T) { client = fakeCWAnnotationsClient{describeAlarmsOutput: &cloudwatch.DescribeAlarmsOutput{}} im := defaultTestInstanceManager() - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, diff --git a/pkg/tsdb/cloudwatch/cloudwatch.go b/pkg/tsdb/cloudwatch/cloudwatch.go index e6660accbd8..dc975543237 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch.go +++ b/pkg/tsdb/cloudwatch/cloudwatch.go @@ -21,9 +21,9 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/backend/proxy" "github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter" - "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/clients" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" @@ -61,12 +61,16 @@ const ( timeSeriesQuery = "timeSeriesQuery" ) -var logger = log.New("tsdb.cloudwatch") - func ProvideService(httpClientProvider *httpclient.Provider) *CloudWatchService { + logger := backend.NewLoggerWith("logger", "tsdb.cloudwatch") logger.Debug("Initializing") - executor := newExecutor(datasource.NewInstanceManager(NewInstanceSettings(httpClientProvider)), awsds.NewSessionCache()) + executor := newExecutor( + datasource.NewInstanceManager(NewInstanceSettings(httpClientProvider)), + awsds.NewSessionCache(), + logger, + ) + return &CloudWatchService{ Executor: executor, } @@ -80,10 +84,11 @@ type SessionCache interface { GetSession(c awsds.SessionConfig) (*session.Session, error) } -func newExecutor(im instancemgmt.InstanceManager, sessions SessionCache) *cloudWatchExecutor { +func newExecutor(im instancemgmt.InstanceManager, sessions SessionCache, logger log.Logger) *cloudWatchExecutor { e := &cloudWatchExecutor{ im: im, sessions: sessions, + logger: logger, } e.resourceHandler = httpadapter.New(e.newResourceMux()) @@ -122,10 +127,26 @@ type cloudWatchExecutor struct { im instancemgmt.InstanceManager sessions SessionCache regionCache sync.Map + logger log.Logger resourceHandler backend.CallResourceHandler } +// instrumentContext adds plugin key-values to the context; later, logger.FromContext(ctx) will provide a logger +// that adds these values to its output. +// TODO: move this into the sdk (see https://github.com/grafana/grafana/issues/82033) +func instrumentContext(ctx context.Context, endpoint string, pCtx backend.PluginContext) context.Context { + p := []any{"endpoint", endpoint, "pluginId", pCtx.PluginID} + if pCtx.DataSourceInstanceSettings != nil { + p = append(p, "dsName", pCtx.DataSourceInstanceSettings.Name) + p = append(p, "dsUID", pCtx.DataSourceInstanceSettings.UID) + } + if pCtx.User != nil { + p = append(p, "uname", pCtx.User.Login) + } + return log.WithContextualAttributes(ctx, p) +} + func (e *cloudWatchExecutor) getRequestContext(ctx context.Context, pluginCtx backend.PluginContext, region string) (models.RequestContext, error) { r := region instance, err := e.getInstance(ctx, pluginCtx) @@ -152,16 +173,17 @@ func (e *cloudWatchExecutor) getRequestContext(ctx context.Context, pluginCtx ba LogsAPIProvider: NewLogsAPI(sess), EC2APIProvider: ec2Client, Settings: instance.Settings, - Logger: logger, + Logger: e.logger.FromContext(ctx), }, nil } func (e *cloudWatchExecutor) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error { + ctx = instrumentContext(ctx, "callResource", req.PluginContext) return e.resourceHandler.CallResource(ctx, req, sender) } func (e *cloudWatchExecutor) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { - logger := logger.FromContext(ctx) + ctx = instrumentContext(ctx, "queryData", req.PluginContext) q := req.Queries[0] var model DataQueryJson err := json.Unmarshal(q.JSON, &model) @@ -185,17 +207,18 @@ func (e *cloudWatchExecutor) QueryData(ctx context.Context, req *backend.QueryDa case annotationQuery: result, err = e.executeAnnotationQuery(ctx, req.PluginContext, model, q) case logAction: - result, err = e.executeLogActions(ctx, logger, req) + result, err = e.executeLogActions(ctx, req) case timeSeriesQuery: fallthrough default: - result, err = e.executeTimeSeriesQuery(ctx, logger, req) + result, err = e.executeTimeSeriesQuery(ctx, req) } return result, err } func (e *cloudWatchExecutor) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) { + ctx = instrumentContext(ctx, "checkHealth", req.PluginContext) status := backend.HealthStatusOk metricsTest := "Successfully queried the CloudWatch metrics API." logsTest := "Successfully queried the CloudWatch logs API." diff --git a/pkg/tsdb/cloudwatch/cloudwatch_integration_test.go b/pkg/tsdb/cloudwatch/cloudwatch_integration_test.go index b476a78fae7..20eae1ac11f 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch_integration_test.go +++ b/pkg/tsdb/cloudwatch/cloudwatch_integration_test.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources" @@ -67,7 +68,7 @@ func Test_CloudWatch_CallResource_Integration_Test(t *testing.T) { {MetricName: aws.String("Test_MetricName8"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4"), Value: aws.String("Value1")}}}, {MetricName: aws.String("Test_MetricName9"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1"), Value: aws.String("Value2")}}}, }, MetricsPerPage: 100} - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) req := &backend.CallResourceRequest{ Method: "GET", @@ -103,7 +104,8 @@ func Test_CloudWatch_CallResource_Integration_Test(t *testing.T) { {MetricName: aws.String("Test_MetricName8"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4")}}}, {MetricName: aws.String("Test_MetricName9"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}}}, }, MetricsPerPage: 2} - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) + req := &backend.CallResourceRequest{ Method: "GET", Path: `/dimension-keys?region=us-east-2&namespace=AWS/EC2&metricName=CPUUtilization&dimensionFilters={"NodeID":["Shared"],"stage":["QueryCommit"]}`, @@ -127,7 +129,7 @@ func Test_CloudWatch_CallResource_Integration_Test(t *testing.T) { t.Run("Should handle standard dimension key query and return hard coded keys", func(t *testing.T) { im := defaultTestInstanceManager() api = mocks.FakeMetricsAPI{} - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) req := &backend.CallResourceRequest{ Method: "GET", @@ -152,7 +154,8 @@ func Test_CloudWatch_CallResource_Integration_Test(t *testing.T) { t.Run("Should handle custom namespace dimension key query and return hard coded keys", func(t *testing.T) { im := defaultTestInstanceManager() api = mocks.FakeMetricsAPI{} - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) + req := &backend.CallResourceRequest{ Method: "GET", Path: `/dimension-keys?region=us-east-2&namespace=AWS/CloudSearch&metricName=CPUUtilization`, @@ -187,7 +190,7 @@ func Test_CloudWatch_CallResource_Integration_Test(t *testing.T) { {MetricName: aws.String("Test_MetricName8"), Namespace: aws.String("AWS/EC2"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4")}}}, {MetricName: aws.String("Test_MetricName9"), Namespace: aws.String("AWS/EC2"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}}}, }, MetricsPerPage: 2} - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) req := &backend.CallResourceRequest{ Method: "GET", @@ -224,7 +227,7 @@ func Test_CloudWatch_CallResource_Integration_Test(t *testing.T) { }, }, }, nil) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) req := &backend.CallResourceRequest{ Method: "GET", @@ -246,7 +249,7 @@ func Test_CloudWatch_CallResource_Integration_Test(t *testing.T) { t.Run("Should handle region requests and return regions from the api", func(t *testing.T) { im := defaultTestInstanceManager() - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) req := &backend.CallResourceRequest{ Method: "GET", Path: `/regions`, @@ -272,7 +275,7 @@ func Test_CloudWatch_CallResource_Integration_Test(t *testing.T) { }}, nil }) - executor := newExecutor(imWithoutDefaultRegion, &fakeSessionCache{}) + executor := newExecutor(imWithoutDefaultRegion, &fakeSessionCache{}, log.NewNullLogger()) req := &backend.CallResourceRequest{ Method: "GET", Path: `/regions`, diff --git a/pkg/tsdb/cloudwatch/cloudwatch_test.go b/pkg/tsdb/cloudwatch/cloudwatch_test.go index 8bed94f5fd3..a989c7ada4d 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch_test.go +++ b/pkg/tsdb/cloudwatch/cloudwatch_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/backend/proxy" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/features" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks" @@ -134,7 +135,7 @@ func Test_CheckHealth(t *testing.T) { t.Run("successfully query metrics and logs", func(t *testing.T) { client = fakeCheckHealthClient{} - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.CheckHealth(context.Background(), &backend.CheckHealthRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -153,7 +154,7 @@ func Test_CheckHealth(t *testing.T) { return nil, fmt.Errorf("some logs query error") }} - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.CheckHealth(context.Background(), &backend.CheckHealthRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -172,7 +173,7 @@ func Test_CheckHealth(t *testing.T) { return fmt.Errorf("some list metrics error") }} - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.CheckHealth(context.Background(), &backend.CheckHealthRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -190,7 +191,7 @@ func Test_CheckHealth(t *testing.T) { executor := newExecutor(im, &fakeSessionCache{getSession: func(c awsds.SessionConfig) (*session.Session, error) { return nil, fmt.Errorf("some sessions error") - }}) + }}, log.NewNullLogger()) resp, err := executor.CheckHealth(context.Background(), &backend.CheckHealthRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -228,7 +229,7 @@ func TestNewSession_passes_authSettings(t *testing.T) { return &session.Session{ Config: &aws.Config{}, }, nil - }}) + }}, log.NewNullLogger()) _, err := executor.newSession(context.Background(), backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, "us-east-1") @@ -274,7 +275,7 @@ func TestQuery_ResourceRequest_DescribeLogGroups_with_CrossAccountQuerying(t *te }, } - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) err := executor.CallResource(contextWithFeaturesEnabled(features.FlagCloudWatchCrossAccountQuerying), req, sender) assert.NoError(t, err) diff --git a/pkg/tsdb/cloudwatch/get_dimension_values_for_wildcards.go b/pkg/tsdb/cloudwatch/get_dimension_values_for_wildcards.go index a0cecadef28..79c3caecd0f 100644 --- a/pkg/tsdb/cloudwatch/get_dimension_values_for_wildcards.go +++ b/pkg/tsdb/cloudwatch/get_dimension_values_for_wildcards.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/clients" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources" @@ -15,7 +14,7 @@ import ( // getDimensionValues gets the actual dimension values for dimensions with a wildcard func (e *cloudWatchExecutor) getDimensionValuesForWildcards(ctx context.Context, pluginCtx backend.PluginContext, region string, - client models.CloudWatchMetricsAPIProvider, origQueries []*models.CloudWatchQuery, tagValueCache *cache.Cache, logger log.Logger) ([]*models.CloudWatchQuery, error) { + client models.CloudWatchMetricsAPIProvider, origQueries []*models.CloudWatchQuery, tagValueCache *cache.Cache) ([]*models.CloudWatchQuery, error) { instance, err := e.getInstance(ctx, pluginCtx) if err != nil { return nil, err @@ -40,12 +39,12 @@ func (e *cloudWatchExecutor) getDimensionValuesForWildcards(ctx context.Context, cacheKey := fmt.Sprintf("%s-%s-%s-%s-%s", region, accountID, query.Namespace, query.MetricName, dimensionKey) cachedDimensions, found := tagValueCache.Get(cacheKey) if found { - logger.Debug("Fetching dimension values from cache") + e.logger.FromContext(ctx).Debug("Fetching dimension values from cache") query.Dimensions[dimensionKey] = cachedDimensions.([]string) continue } - logger.Debug("Cache miss, fetching dimension values from AWS") + e.logger.FromContext(ctx).Debug("Cache miss, fetching dimension values from AWS") request := resources.DimensionValuesRequest{ ResourceRequest: &resources.ResourceRequest{ Region: region, diff --git a/pkg/tsdb/cloudwatch/get_dimension_values_for_wildcards_test.go b/pkg/tsdb/cloudwatch/get_dimension_values_for_wildcards_test.go index 5a2c2e48e70..68514ccc684 100644 --- a/pkg/tsdb/cloudwatch/get_dimension_values_for_wildcards_test.go +++ b/pkg/tsdb/cloudwatch/get_dimension_values_for_wildcards_test.go @@ -7,7 +7,7 @@ import ( "github.com/aws/aws-sdk-go/service/cloudwatch" "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/infra/log/logtest" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils" @@ -16,8 +16,7 @@ import ( ) func TestGetDimensionValuesForWildcards(t *testing.T) { - logger := &logtest.Fake{} - executor := &cloudWatchExecutor{im: defaultTestInstanceManager()} + executor := &cloudWatchExecutor{im: defaultTestInstanceManager(), logger: log.NewNullLogger()} ctx := context.Background() pluginCtx := backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ID: 1, Updated: time.Now()}, @@ -28,7 +27,7 @@ func TestGetDimensionValuesForWildcards(t *testing.T) { query := getBaseQuery() query.MetricName = "Test_MetricName1" query.Dimensions = map[string][]string{"Test_DimensionName1": {"Value1"}} - queries, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", nil, []*models.CloudWatchQuery{query}, tagValueCache, logger) + queries, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", nil, []*models.CloudWatchQuery{query}, tagValueCache) assert.Nil(t, err) assert.Len(t, queries, 1) assert.NotNil(t, queries[0].Dimensions["Test_DimensionName1"], 1) @@ -39,7 +38,7 @@ func TestGetDimensionValuesForWildcards(t *testing.T) { query := getBaseQuery() query.MetricName = "Test_MetricName1" query.Dimensions = map[string][]string{"Test_DimensionName1": {"*"}} - queries, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", nil, []*models.CloudWatchQuery{query}, tagValueCache, logger) + queries, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", nil, []*models.CloudWatchQuery{query}, tagValueCache) assert.Nil(t, err) assert.Len(t, queries, 1) assert.NotNil(t, queries[0].Dimensions["Test_DimensionName1"]) @@ -58,7 +57,7 @@ func TestGetDimensionValuesForWildcards(t *testing.T) { {MetricName: utils.Pointer("Test_MetricName4"), Dimensions: []*cloudwatch.Dimension{{Name: utils.Pointer("Test_DimensionName1"), Value: utils.Pointer("Value2")}}}, }} api.On("ListMetricsPagesWithContext").Return(nil) - queries, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", api, []*models.CloudWatchQuery{query}, tagValueCache, logger) + queries, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", api, []*models.CloudWatchQuery{query}, tagValueCache) assert.Nil(t, err) assert.Len(t, queries, 1) assert.Equal(t, map[string][]string{"Test_DimensionName1": {"Value1", "Value2", "Value3", "Value4"}}, queries[0].Dimensions) @@ -74,13 +73,13 @@ func TestGetDimensionValuesForWildcards(t *testing.T) { {MetricName: utils.Pointer("Test_MetricName"), Dimensions: []*cloudwatch.Dimension{{Name: utils.Pointer("Test_DimensionName"), Value: utils.Pointer("Value")}}}, }} api.On("ListMetricsPagesWithContext").Return(nil) - _, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", api, []*models.CloudWatchQuery{query}, tagValueCache, logger) + _, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", api, []*models.CloudWatchQuery{query}, tagValueCache) assert.Nil(t, err) // make sure the original query wasn't altered assert.Equal(t, map[string][]string{"Test_DimensionName": {"*"}}, query.Dimensions) //setting the api to nil confirms that it's using the cached value - queries, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", nil, []*models.CloudWatchQuery{query}, tagValueCache, logger) + queries, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", nil, []*models.CloudWatchQuery{query}, tagValueCache) assert.Nil(t, err) assert.Len(t, queries, 1) assert.Equal(t, map[string][]string{"Test_DimensionName": {"Value"}}, queries[0].Dimensions) @@ -94,7 +93,7 @@ func TestGetDimensionValuesForWildcards(t *testing.T) { query.MatchExact = false api := &mocks.MetricsAPI{Metrics: []*cloudwatch.Metric{}} api.On("ListMetricsPagesWithContext").Return(nil) - queries, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", api, []*models.CloudWatchQuery{query}, tagValueCache, logger) + queries, err := executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", api, []*models.CloudWatchQuery{query}, tagValueCache) assert.Nil(t, err) assert.Len(t, queries, 1) // assert that the values was set to an empty array @@ -105,7 +104,7 @@ func TestGetDimensionValuesForWildcards(t *testing.T) { {MetricName: utils.Pointer("Test_MetricName"), Dimensions: []*cloudwatch.Dimension{{Name: utils.Pointer("Test_DimensionName2"), Value: utils.Pointer("Value")}}}, } api.On("ListMetricsPagesWithContext").Return(nil) - queries, err = executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", api, []*models.CloudWatchQuery{query}, tagValueCache, logger) + queries, err = executor.getDimensionValuesForWildcards(ctx, pluginCtx, "us-east-1", api, []*models.CloudWatchQuery{query}, tagValueCache) assert.Nil(t, err) assert.Len(t, queries, 1) assert.Equal(t, map[string][]string{"Test_DimensionName2": {"Value"}}, queries[0].Dimensions) diff --git a/pkg/tsdb/cloudwatch/get_metric_query_batches.go b/pkg/tsdb/cloudwatch/get_metric_query_batches.go index 2b4f0b47667..71d87292d99 100644 --- a/pkg/tsdb/cloudwatch/get_metric_query_batches.go +++ b/pkg/tsdb/cloudwatch/get_metric_query_batches.go @@ -3,7 +3,7 @@ package cloudwatch import ( "regexp" - "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" ) diff --git a/pkg/tsdb/cloudwatch/get_metric_query_batches_test.go b/pkg/tsdb/cloudwatch/get_metric_query_batches_test.go index f00fb982856..a5668ba6a45 100644 --- a/pkg/tsdb/cloudwatch/get_metric_query_batches_test.go +++ b/pkg/tsdb/cloudwatch/get_metric_query_batches_test.go @@ -3,13 +3,13 @@ package cloudwatch import ( "testing" - "github.com/grafana/grafana/pkg/infra/log/logtest" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" "github.com/stretchr/testify/assert" ) func TestGetMetricQueryBatches(t *testing.T) { - logger := &logtest.Fake{} + nullLogger := log.NewNullLogger() insight1 := models.CloudWatchQuery{ MetricQueryType: models.MetricQueryTypeQuery, Id: "i1", @@ -86,7 +86,7 @@ func TestGetMetricQueryBatches(t *testing.T) { &m88_ref_m98, } - result := getMetricQueryBatches(batch, logger) + result := getMetricQueryBatches(batch, nullLogger) assert.Len(t, result, 3) assert.ElementsMatch(t, []*models.CloudWatchQuery{&insight1}, result[0]) assert.ElementsMatch(t, []*models.CloudWatchQuery{&insight2}, result[1]) @@ -102,7 +102,7 @@ func TestGetMetricQueryBatches(t *testing.T) { &m4_ref_s1, } - result := getMetricQueryBatches(batch, logger) + result := getMetricQueryBatches(batch, nullLogger) assert.Len(t, result, 1) assert.Equal(t, batch, result[0]) }) @@ -113,7 +113,7 @@ func TestGetMetricQueryBatches(t *testing.T) { &metricStat, } - result := getMetricQueryBatches(batch, logger) + result := getMetricQueryBatches(batch, nullLogger) assert.Len(t, result, 1) assert.ElementsMatch(t, batch, result[0]) }) @@ -125,7 +125,7 @@ func TestGetMetricQueryBatches(t *testing.T) { &insight2, } - result := getMetricQueryBatches(batch, logger) + result := getMetricQueryBatches(batch, nullLogger) assert.Len(t, result, 3) assert.ElementsMatch(t, []*models.CloudWatchQuery{&insight1}, result[0]) assert.ElementsMatch(t, []*models.CloudWatchQuery{&metricStat}, result[1]) @@ -142,7 +142,7 @@ func TestGetMetricQueryBatches(t *testing.T) { &m4_ref_s1, } - result := getMetricQueryBatches(batch, logger) + result := getMetricQueryBatches(batch, nullLogger) assert.Len(t, result, 1) assert.ElementsMatch(t, batch, result[0]) }) @@ -157,7 +157,7 @@ func TestGetMetricQueryBatches(t *testing.T) { &m4_ref_s1, } - result := getMetricQueryBatches(batch, logger) + result := getMetricQueryBatches(batch, nullLogger) assert.Len(t, result, 3) assert.ElementsMatch(t, []*models.CloudWatchQuery{&insight2}, result[0]) assert.ElementsMatch(t, []*models.CloudWatchQuery{&insight1, &m1_ref_i1, &m2_ref_i1, &m3_ref_m1_m2}, result[1]) @@ -172,7 +172,7 @@ func TestGetMetricQueryBatches(t *testing.T) { &m4_ref_i1_i3, } - result := getMetricQueryBatches(batch, logger) + result := getMetricQueryBatches(batch, nullLogger) assert.Len(t, result, 3) assert.ElementsMatch(t, []*models.CloudWatchQuery{&insight2}, result[0]) assert.ElementsMatch(t, []*models.CloudWatchQuery{&insight1, &m1_ref_i1}, result[1]) diff --git a/pkg/tsdb/cloudwatch/log_actions.go b/pkg/tsdb/cloudwatch/log_actions.go index eae9da79740..416aaa676cc 100644 --- a/pkg/tsdb/cloudwatch/log_actions.go +++ b/pkg/tsdb/cloudwatch/log_actions.go @@ -17,10 +17,9 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/features" - "golang.org/x/sync/errgroup" - - "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" + + "golang.org/x/sync/errgroup" ) const ( @@ -41,7 +40,7 @@ func (e *AWSError) Error() string { return fmt.Sprintf("%s: %s", e.Code, e.Message) } -func (e *cloudWatchExecutor) executeLogActions(ctx context.Context, logger log.Logger, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { +func (e *cloudWatchExecutor) executeLogActions(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { resp := backend.NewQueryDataResponse() resultChan := make(chan backend.Responses, len(req.Queries)) @@ -56,7 +55,7 @@ func (e *cloudWatchExecutor) executeLogActions(ctx context.Context, logger log.L query := query eg.Go(func() error { - dataframe, err := e.executeLogAction(ectx, logger, logsQuery, query, req.PluginContext) + dataframe, err := e.executeLogAction(ectx, logsQuery, query, req.PluginContext) if err != nil { var AWSError *AWSError if errors.As(err, &AWSError) { @@ -96,7 +95,7 @@ func (e *cloudWatchExecutor) executeLogActions(ctx context.Context, logger log.L return resp, nil } -func (e *cloudWatchExecutor) executeLogAction(ctx context.Context, logger log.Logger, logsQuery models.LogsQuery, query backend.DataQuery, pluginCtx backend.PluginContext) (*data.Frame, error) { +func (e *cloudWatchExecutor) executeLogAction(ctx context.Context, logsQuery models.LogsQuery, query backend.DataQuery, pluginCtx backend.PluginContext) (*data.Frame, error) { instance, err := e.getInstance(ctx, pluginCtx) if err != nil { return nil, err @@ -115,7 +114,7 @@ func (e *cloudWatchExecutor) executeLogAction(ctx context.Context, logger log.Lo var data *data.Frame = nil switch logsQuery.Subtype { case "StartQuery": - data, err = e.handleStartQuery(ctx, logger, logsClient, logsQuery, query.TimeRange, query.RefID) + data, err = e.handleStartQuery(ctx, logsClient, logsQuery, query.TimeRange, query.RefID) case "StopQuery": data, err = e.handleStopQuery(ctx, logsClient, logsQuery) case "GetQueryResults": @@ -229,17 +228,17 @@ func (e *cloudWatchExecutor) executeStartQuery(ctx context.Context, logsClient c startQueryInput.Limit = aws.Int64(*logsQuery.Limit) } - logger.Debug("Calling startquery with context with input", "input", startQueryInput) + e.logger.FromContext(ctx).Debug("Calling startquery with context with input", "input", startQueryInput) return logsClient.StartQueryWithContext(ctx, startQueryInput) } -func (e *cloudWatchExecutor) handleStartQuery(ctx context.Context, logger log.Logger, logsClient cloudwatchlogsiface.CloudWatchLogsAPI, +func (e *cloudWatchExecutor) handleStartQuery(ctx context.Context, logsClient cloudwatchlogsiface.CloudWatchLogsAPI, logsQuery models.LogsQuery, timeRange backend.TimeRange, refID string) (*data.Frame, error) { startQueryResponse, err := e.executeStartQuery(ctx, logsClient, logsQuery, timeRange) if err != nil { var awsErr awserr.Error if errors.As(err, &awsErr) && awsErr.Code() == "LimitExceededException" { - logger.Debug("ExecuteStartQuery limit exceeded", "err", awsErr) + e.logger.FromContext(ctx).Debug("ExecuteStartQuery limit exceeded", "err", awsErr) return nil, &AWSError{Code: limitExceededException, Message: err.Error()} } return nil, err diff --git a/pkg/tsdb/cloudwatch/log_actions_test.go b/pkg/tsdb/cloudwatch/log_actions_test.go index b42aefb2bf5..1155c9090fb 100644 --- a/pkg/tsdb/cloudwatch/log_actions_test.go +++ b/pkg/tsdb/cloudwatch/log_actions_test.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/features" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks" @@ -90,7 +91,7 @@ func TestQuery_handleGetLogEvents_passes_nil_start_and_end_times_to_GetLogEvents return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, @@ -123,7 +124,7 @@ func TestQuery_GetLogEvents_returns_response_from_GetLogEvents_to_data_frame_fie im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) cli = &mocks.MockLogEvents{} cli.On("GetLogEventsWithContext", mock.Anything, mock.Anything, mock.Anything).Return(&cloudwatchlogs.GetLogEventsOutput{ @@ -208,7 +209,7 @@ func TestQuery_StartQuery(t *testing.T) { }}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, @@ -265,7 +266,7 @@ func TestQuery_StartQuery(t *testing.T) { }}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, @@ -322,7 +323,7 @@ func Test_executeStartQuery(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -358,7 +359,7 @@ func Test_executeStartQuery(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -384,7 +385,7 @@ func Test_executeStartQuery(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(contextWithFeaturesEnabled(features.FlagCloudWatchCrossAccountQuerying), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -420,7 +421,7 @@ func Test_executeStartQuery(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(contextWithFeaturesEnabled(features.FlagCloudWatchCrossAccountQuerying), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -456,8 +457,7 @@ func Test_executeStartQuery(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) - + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, Queries: []backend.DataQuery{ @@ -492,7 +492,7 @@ func Test_executeStartQuery(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, Queries: []backend.DataQuery{ @@ -526,7 +526,7 @@ func Test_executeStartQuery(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(contextWithFeaturesEnabled(features.FlagCloudWatchCrossAccountQuerying), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, Queries: []backend.DataQuery{ @@ -597,7 +597,7 @@ func TestQuery_StopQuery(t *testing.T) { To: time.Unix(1584700643, 0), } - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, @@ -687,7 +687,7 @@ func TestQuery_GetQueryResults(t *testing.T) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, diff --git a/pkg/tsdb/cloudwatch/log_sync_query_test.go b/pkg/tsdb/cloudwatch/log_sync_query_test.go index a6760e272a0..112b4746b6b 100644 --- a/pkg/tsdb/cloudwatch/log_sync_query_test.go +++ b/pkg/tsdb/cloudwatch/log_sync_query_test.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils" @@ -40,7 +41,7 @@ func Test_executeSyncLogQuery(t *testing.T) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) sess := fakeSessionCache{} - executor := newExecutor(im, &sess) + executor := newExecutor(im, &sess, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ Headers: map[string]string{headerFromAlert: "some value"}, @@ -67,7 +68,7 @@ func Test_executeSyncLogQuery(t *testing.T) { }) sess := fakeSessionCache{} - executor := newExecutor(im, &sess) + executor := newExecutor(im, &sess, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ Headers: map[string]string{headerFromAlert: "some value"}, PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -124,7 +125,7 @@ func Test_executeSyncLogQuery(t *testing.T) { }) sess := fakeSessionCache{} - executor := newExecutor(im, &sess) + executor := newExecutor(im, &sess, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ Headers: tc.headers, PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -167,7 +168,7 @@ func Test_executeSyncLogQuery(t *testing.T) { }) sess := fakeSessionCache{} - executor := newExecutor(im, &sess) + executor := newExecutor(im, &sess, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, Queries: []backend.DataQuery{ @@ -206,7 +207,7 @@ func Test_executeSyncLogQuery_handles_RefId_from_input_queries(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) res, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ Headers: map[string]string{headerFromAlert: "some value"}, @@ -235,7 +236,7 @@ func Test_executeSyncLogQuery_handles_RefId_from_input_queries(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) res, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ Headers: map[string]string{headerFromAlert: "some value"}, @@ -304,7 +305,7 @@ func Test_executeSyncLogQuery_handles_RefId_from_input_queries(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) res, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ Headers: map[string]string{headerFromAlert: "some value"}, @@ -349,7 +350,8 @@ func Test_executeSyncLogQuery_handles_RefId_from_input_queries(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{LogsTimeout: models.Duration{Duration: time.Millisecond}}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ Headers: map[string]string{headerFromAlert: "some value"}, @@ -381,7 +383,7 @@ func Test_executeSyncLogQuery_handles_RefId_from_input_queries(t *testing.T) { im := datasource.NewInstanceManager(func(ctx context.Context, s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) res, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ Headers: map[string]string{headerFromAlert: "some value"}, diff --git a/pkg/tsdb/cloudwatch/metric_data_input_builder.go b/pkg/tsdb/cloudwatch/metric_data_input_builder.go index ebb667c2610..1cbb848258b 100644 --- a/pkg/tsdb/cloudwatch/metric_data_input_builder.go +++ b/pkg/tsdb/cloudwatch/metric_data_input_builder.go @@ -6,11 +6,10 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cloudwatch" - "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" ) -func (e *cloudWatchExecutor) buildMetricDataInput(logger log.Logger, startTime time.Time, endTime time.Time, +func (e *cloudWatchExecutor) buildMetricDataInput(startTime time.Time, endTime time.Time, queries []*models.CloudWatchQuery) (*cloudwatch.GetMetricDataInput, error) { metricDataInput := &cloudwatch.GetMetricDataInput{ StartTime: aws.Time(startTime), @@ -27,7 +26,7 @@ func (e *cloudWatchExecutor) buildMetricDataInput(logger log.Logger, startTime t } for _, query := range queries { - metricDataQuery, err := e.buildMetricDataQuery(logger, query) + metricDataQuery, err := e.buildMetricDataQuery(query) if err != nil { return nil, &models.QueryError{Err: err, RefID: query.RefId} } diff --git a/pkg/tsdb/cloudwatch/metric_data_input_builder_test.go b/pkg/tsdb/cloudwatch/metric_data_input_builder_test.go index 6421c45d88c..eaa35e3931d 100644 --- a/pkg/tsdb/cloudwatch/metric_data_input_builder_test.go +++ b/pkg/tsdb/cloudwatch/metric_data_input_builder_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" ) @@ -26,13 +27,13 @@ func TestMetricDataInputBuilder(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := getBaseQuery() query.TimezoneUTCOffset = tc.timezoneUTCOffset from := now.Add(time.Hour * -2) to := now.Add(time.Hour * -1) - mdi, err := executor.buildMetricDataInput(logger, from, to, []*models.CloudWatchQuery{query}) + mdi, err := executor.buildMetricDataInput(from, to, []*models.CloudWatchQuery{query}) assert.NoError(t, err) require.NotNil(t, mdi) diff --git a/pkg/tsdb/cloudwatch/metric_data_query_builder.go b/pkg/tsdb/cloudwatch/metric_data_query_builder.go index 0a6fa90316b..aa30e28f5cb 100644 --- a/pkg/tsdb/cloudwatch/metric_data_query_builder.go +++ b/pkg/tsdb/cloudwatch/metric_data_query_builder.go @@ -9,11 +9,10 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cloudwatch" - "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" ) -func (e *cloudWatchExecutor) buildMetricDataQuery(logger log.Logger, query *models.CloudWatchQuery) (*cloudwatch.MetricDataQuery, error) { +func (e *cloudWatchExecutor) buildMetricDataQuery(query *models.CloudWatchQuery) (*cloudwatch.MetricDataQuery, error) { mdq := &cloudwatch.MetricDataQuery{ Id: aws.String(query.Id), ReturnData: aws.Bool(query.ReturnData), diff --git a/pkg/tsdb/cloudwatch/metric_data_query_builder_test.go b/pkg/tsdb/cloudwatch/metric_data_query_builder_test.go index 17fc80ebae4..e033481a308 100644 --- a/pkg/tsdb/cloudwatch/metric_data_query_builder_test.go +++ b/pkg/tsdb/cloudwatch/metric_data_query_builder_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -12,11 +13,11 @@ import ( func TestMetricDataQueryBuilder(t *testing.T) { t.Run("buildMetricDataQuery", func(t *testing.T) { t.Run("should use metric stat", func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := getBaseQuery() query.MetricEditorMode = models.MetricEditorModeBuilder query.MetricQueryType = models.MetricQueryTypeSearch - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) require.NoError(t, err) require.Empty(t, mdq.Expression) assert.Equal(t, query.MetricName, *mdq.MetricStat.Metric.MetricName) @@ -24,70 +25,70 @@ func TestMetricDataQueryBuilder(t *testing.T) { }) t.Run("should pass AccountId in metric stat query", func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := getBaseQuery() query.MetricEditorMode = models.MetricEditorModeBuilder query.MetricQueryType = models.MetricQueryTypeSearch query.AccountId = aws.String("some account id") - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) require.NoError(t, err) assert.Equal(t, "some account id", *mdq.AccountId) }) t.Run("should leave AccountId in metric stat query", func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := getBaseQuery() query.MetricEditorMode = models.MetricEditorModeBuilder query.MetricQueryType = models.MetricQueryTypeSearch - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) require.NoError(t, err) assert.Nil(t, mdq.AccountId) }) t.Run("should use custom built expression", func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := getBaseQuery() query.MetricEditorMode = models.MetricEditorModeBuilder query.MetricQueryType = models.MetricQueryTypeSearch query.MatchExact = false - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) require.NoError(t, err) require.Nil(t, mdq.MetricStat) assert.Equal(t, `REMOVE_EMPTY(SEARCH('Namespace="AWS/EC2" MetricName="CPUUtilization" "LoadBalancer"="lb1"', '', 300))`, *mdq.Expression) }) t.Run("should use sql expression", func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := getBaseQuery() query.MetricEditorMode = models.MetricEditorModeRaw query.MetricQueryType = models.MetricQueryTypeQuery query.SqlExpression = `SELECT SUM(CPUUTilization) FROM "AWS/EC2"` - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) require.NoError(t, err) require.Nil(t, mdq.MetricStat) assert.Equal(t, query.SqlExpression, *mdq.Expression) }) t.Run("should use user defined math expression", func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := getBaseQuery() query.MetricEditorMode = models.MetricEditorModeRaw query.MetricQueryType = models.MetricQueryTypeSearch query.Expression = `SUM(x+y)` - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) require.NoError(t, err) require.Nil(t, mdq.MetricStat) assert.Equal(t, query.Expression, *mdq.Expression) }) t.Run("should set period in user defined expression", func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := getBaseQuery() query.MetricEditorMode = models.MetricEditorModeRaw query.MetricQueryType = models.MetricQueryTypeSearch query.MatchExact = false query.Expression = `SUM([a,b])` - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) require.NoError(t, err) require.Nil(t, mdq.MetricStat) assert.Equal(t, int64(300), *mdq.Period) @@ -95,11 +96,11 @@ func TestMetricDataQueryBuilder(t *testing.T) { }) t.Run("should set label", func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := getBaseQuery() query.Label = "some label" - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) assert.NoError(t, err) require.NotNil(t, mdq.Label) @@ -107,18 +108,18 @@ func TestMetricDataQueryBuilder(t *testing.T) { }) t.Run("should not set label for empty string query label", func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := getBaseQuery() query.Label = "" - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) assert.NoError(t, err) assert.Nil(t, mdq.Label) }) t.Run(`should not specify accountId when it is "all"`, func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := &models.CloudWatchQuery{ Namespace: "AWS/EC2", MetricName: "CPUUtilization", @@ -128,7 +129,7 @@ func TestMetricDataQueryBuilder(t *testing.T) { AccountId: aws.String("all"), } - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) assert.NoError(t, err) require.Nil(t, mdq.MetricStat) @@ -136,7 +137,7 @@ func TestMetricDataQueryBuilder(t *testing.T) { }) t.Run("should set accountId when it is specified", func(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) query := &models.CloudWatchQuery{ Namespace: "AWS/EC2", MetricName: "CPUUtilization", @@ -146,7 +147,7 @@ func TestMetricDataQueryBuilder(t *testing.T) { AccountId: aws.String("12345"), } - mdq, err := executor.buildMetricDataQuery(logger, query) + mdq, err := executor.buildMetricDataQuery(query) assert.NoError(t, err) require.Nil(t, mdq.MetricStat) diff --git a/pkg/tsdb/cloudwatch/metric_find_query.go b/pkg/tsdb/cloudwatch/metric_find_query.go index 2960d78de80..cf1edd524a3 100644 --- a/pkg/tsdb/cloudwatch/metric_find_query.go +++ b/pkg/tsdb/cloudwatch/metric_find_query.go @@ -63,7 +63,7 @@ func (e *cloudWatchExecutor) handleGetRegions(ctx context.Context, pluginCtx bac ec2Regions, err := client.DescribeRegionsWithContext(ctx, &ec2.DescribeRegionsInput{}) if err != nil { // ignore error for backward compatibility - logger.Error("Failed to get regions", "error", err) + e.logger.FromContext(ctx).Error("Failed to get regions", "error", err) } else { mergeEC2RegionsAndConstantRegions(regions, ec2Regions.Regions) } diff --git a/pkg/tsdb/cloudwatch/metric_find_query_test.go b/pkg/tsdb/cloudwatch/metric_find_query_test.go index 822fd7b8107..a9172c1690d 100644 --- a/pkg/tsdb/cloudwatch/metric_find_query_test.go +++ b/pkg/tsdb/cloudwatch/metric_find_query_test.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/constants" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks" @@ -53,7 +54,7 @@ func TestQuery_Regions(t *testing.T) { }}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.handleGetRegions( context.Background(), backend.PluginContext{ @@ -115,7 +116,7 @@ func Test_handleGetRegions_regionCache(t *testing.T) { t.Run("AWS only called once for multiple calls to handleGetRegions", func(t *testing.T) { cli.On("DescribeRegionsWithContext", mock.Anything, mock.Anything).Return(&ec2.DescribeRegionsOutput{}, nil) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.handleGetRegions( context.Background(), backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, nil) @@ -171,7 +172,7 @@ func TestQuery_InstanceAttributes(t *testing.T) { filterJson, err := json.Marshal(filterMap) require.NoError(t, err) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.handleGetEc2InstanceAttribute( context.Background(), backend.PluginContext{ @@ -249,7 +250,7 @@ func TestQuery_EBSVolumeIDs(t *testing.T) { return DataSource{Settings: models.CloudWatchSettings{}}, nil }) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.handleGetEbsVolumeIds( context.Background(), backend.PluginContext{ @@ -316,7 +317,7 @@ func TestQuery_ResourceARNs(t *testing.T) { tagJson, err := json.Marshal(tagMap) require.NoError(t, err) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.handleGetResourceArns( context.Background(), backend.PluginContext{ diff --git a/pkg/tsdb/cloudwatch/models/api.go b/pkg/tsdb/cloudwatch/models/api.go index 00688e7abc3..c54c156b123 100644 --- a/pkg/tsdb/cloudwatch/models/api.go +++ b/pkg/tsdb/cloudwatch/models/api.go @@ -10,7 +10,7 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/oam" "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources" ) diff --git a/pkg/tsdb/cloudwatch/models/cloudwatch_query.go b/pkg/tsdb/cloudwatch/models/cloudwatch_query.go index ddf00f2b939..403ac843fc9 100644 --- a/pkg/tsdb/cloudwatch/models/cloudwatch_query.go +++ b/pkg/tsdb/cloudwatch/models/cloudwatch_query.go @@ -14,9 +14,9 @@ import ( "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/google/uuid" - "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery" ) diff --git a/pkg/tsdb/cloudwatch/models/cloudwatch_query_test.go b/pkg/tsdb/cloudwatch/models/cloudwatch_query_test.go index 3a5a885d3ea..7256d61c62f 100644 --- a/pkg/tsdb/cloudwatch/models/cloudwatch_query_test.go +++ b/pkg/tsdb/cloudwatch/models/cloudwatch_query_test.go @@ -10,15 +10,15 @@ import ( "github.com/grafana/kindsys" "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery" "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/utils" ) -var logger = &logtest.Fake{} +var logger = log.NewNullLogger() func TestCloudWatchQuery(t *testing.T) { t.Run("Deeplink", func(t *testing.T) { diff --git a/pkg/tsdb/cloudwatch/resource_handler.go b/pkg/tsdb/cloudwatch/resource_handler.go index bdaf304cc47..e950bd4d02c 100644 --- a/pkg/tsdb/cloudwatch/resource_handler.go +++ b/pkg/tsdb/cloudwatch/resource_handler.go @@ -8,62 +8,62 @@ import ( "net/url" "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/resource/httpadapter" - "github.com/grafana/grafana/pkg/tsdb/cloudwatch/routes" ) func (e *cloudWatchExecutor) newResourceMux() *http.ServeMux { mux := http.NewServeMux() - mux.HandleFunc("/ebs-volume-ids", handleResourceReq(e.handleGetEbsVolumeIds)) - mux.HandleFunc("/ec2-instance-attribute", handleResourceReq(e.handleGetEc2InstanceAttribute)) - mux.HandleFunc("/resource-arns", handleResourceReq(e.handleGetResourceArns)) - mux.HandleFunc("/log-groups", routes.ResourceRequestMiddleware(routes.LogGroupsHandler, logger, e.getRequestContext)) - mux.HandleFunc("/metrics", routes.ResourceRequestMiddleware(routes.MetricsHandler, logger, e.getRequestContext)) - mux.HandleFunc("/dimension-values", routes.ResourceRequestMiddleware(routes.DimensionValuesHandler, logger, e.getRequestContext)) - mux.HandleFunc("/dimension-keys", routes.ResourceRequestMiddleware(routes.DimensionKeysHandler, logger, e.getRequestContext)) - mux.HandleFunc("/accounts", routes.ResourceRequestMiddleware(routes.AccountsHandler, logger, e.getRequestContext)) - mux.HandleFunc("/namespaces", routes.ResourceRequestMiddleware(routes.NamespacesHandler, logger, e.getRequestContext)) - mux.HandleFunc("/log-group-fields", routes.ResourceRequestMiddleware(routes.LogGroupFieldsHandler, logger, e.getRequestContext)) - mux.HandleFunc("/external-id", routes.ResourceRequestMiddleware(routes.ExternalIdHandler, logger, e.getRequestContext)) - mux.HandleFunc("/regions", routes.ResourceRequestMiddleware(routes.RegionsHandler, logger, e.getRequestContext)) + mux.HandleFunc("/ebs-volume-ids", handleResourceReq(e.handleGetEbsVolumeIds, e.logger)) + mux.HandleFunc("/ec2-instance-attribute", handleResourceReq(e.handleGetEc2InstanceAttribute, e.logger)) + mux.HandleFunc("/resource-arns", handleResourceReq(e.handleGetResourceArns, e.logger)) + mux.HandleFunc("/log-groups", routes.ResourceRequestMiddleware(routes.LogGroupsHandler, e.logger, e.getRequestContext)) + mux.HandleFunc("/metrics", routes.ResourceRequestMiddleware(routes.MetricsHandler, e.logger, e.getRequestContext)) + mux.HandleFunc("/dimension-values", routes.ResourceRequestMiddleware(routes.DimensionValuesHandler, e.logger, e.getRequestContext)) + mux.HandleFunc("/dimension-keys", routes.ResourceRequestMiddleware(routes.DimensionKeysHandler, e.logger, e.getRequestContext)) + mux.HandleFunc("/accounts", routes.ResourceRequestMiddleware(routes.AccountsHandler, e.logger, e.getRequestContext)) + mux.HandleFunc("/namespaces", routes.ResourceRequestMiddleware(routes.NamespacesHandler, e.logger, e.getRequestContext)) + mux.HandleFunc("/log-group-fields", routes.ResourceRequestMiddleware(routes.LogGroupFieldsHandler, e.logger, e.getRequestContext)) + mux.HandleFunc("/external-id", routes.ResourceRequestMiddleware(routes.ExternalIdHandler, e.logger, e.getRequestContext)) + mux.HandleFunc("/regions", routes.ResourceRequestMiddleware(routes.RegionsHandler, e.logger, e.getRequestContext)) // remove this once AWS's Cross Account Observability is supported in GovCloud - mux.HandleFunc("/legacy-log-groups", handleResourceReq(e.handleGetLogGroups)) + mux.HandleFunc("/legacy-log-groups", handleResourceReq(e.handleGetLogGroups, e.logger)) return mux } type handleFn func(ctx context.Context, pluginCtx backend.PluginContext, parameters url.Values) ([]suggestData, error) -func handleResourceReq(handleFunc handleFn) func(rw http.ResponseWriter, req *http.Request) { +func handleResourceReq(handleFunc handleFn, logger log.Logger) func(rw http.ResponseWriter, req *http.Request) { return func(rw http.ResponseWriter, req *http.Request) { ctx := req.Context() pluginContext := httpadapter.PluginConfigFromContext(ctx) err := req.ParseForm() if err != nil { - writeResponse(rw, http.StatusBadRequest, fmt.Sprintf("unexpected error %v", err)) + writeResponse(rw, http.StatusBadRequest, fmt.Sprintf("unexpected error %v", err), logger.FromContext(ctx)) return } data, err := handleFunc(ctx, pluginContext, req.URL.Query()) if err != nil { - writeResponse(rw, http.StatusBadRequest, fmt.Sprintf("unexpected error %v", err)) + writeResponse(rw, http.StatusBadRequest, fmt.Sprintf("unexpected error %v", err), logger.FromContext(ctx)) return } body, err := json.Marshal(data) if err != nil { - writeResponse(rw, http.StatusBadRequest, fmt.Sprintf("unexpected error %v", err)) + writeResponse(rw, http.StatusBadRequest, fmt.Sprintf("unexpected error %v", err), logger.FromContext(ctx)) return } rw.WriteHeader(http.StatusOK) _, err = rw.Write(body) if err != nil { - logger.Error("Unable to write HTTP response", "error", err) + logger.FromContext(ctx).Error("Unable to write HTTP response", "error", err) return } } } -func writeResponse(rw http.ResponseWriter, code int, msg string) { +func writeResponse(rw http.ResponseWriter, code int, msg string, logger log.Logger) { rw.WriteHeader(code) _, err := rw.Write([]byte(msg)) if err != nil { diff --git a/pkg/tsdb/cloudwatch/routes/dimension_keys_test.go b/pkg/tsdb/cloudwatch/routes/dimension_keys_test.go index 42dd3b360ab..d48887142ce 100644 --- a/pkg/tsdb/cloudwatch/routes/dimension_keys_test.go +++ b/pkg/tsdb/cloudwatch/routes/dimension_keys_test.go @@ -9,18 +9,18 @@ import ( "testing" "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "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/models" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/services" ) -var logger = &logtest.Fake{} +var logger = log.NewNullLogger() func Test_DimensionKeys_Route(t *testing.T) { t.Run("calls FilterDimensionKeysRequest when a StandardDimensionKeysRequest is passed", func(t *testing.T) { diff --git a/pkg/tsdb/cloudwatch/routes/middleware.go b/pkg/tsdb/cloudwatch/routes/middleware.go index 3ab5ca08160..cf75a9cc3f3 100644 --- a/pkg/tsdb/cloudwatch/routes/middleware.go +++ b/pkg/tsdb/cloudwatch/routes/middleware.go @@ -3,9 +3,9 @@ package routes import ( "net/http" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter" - "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" ) @@ -20,7 +20,7 @@ func ResourceRequestMiddleware(handleFunc models.RouteHandlerFunc, logger log.Lo pluginContext := httpadapter.PluginConfigFromContext(ctx) json, httpError := handleFunc(ctx, pluginContext, reqCtxFactory, req.URL.Query()) if httpError != nil { - logger.Error("Error handling resource request", "error", httpError.Message) + logger.FromContext(ctx).Error("Error handling resource request", "error", httpError.Message) respondWithError(rw, httpError) return } @@ -28,7 +28,7 @@ func ResourceRequestMiddleware(handleFunc models.RouteHandlerFunc, logger log.Lo rw.Header().Set("Content-Type", "application/json") _, err := rw.Write(json) if err != nil { - logger.Error("Error handling resource request", "error", err) + logger.FromContext(ctx).Error("Error handling resource request", "error", err) respondWithError(rw, models.NewHttpError("error writing response in resource request middleware", http.StatusInternalServerError, err)) } } diff --git a/pkg/tsdb/cloudwatch/services/regions.go b/pkg/tsdb/cloudwatch/services/regions.go index 9a2f6244e00..2f8fc345e07 100644 --- a/pkg/tsdb/cloudwatch/services/regions.go +++ b/pkg/tsdb/cloudwatch/services/regions.go @@ -5,7 +5,7 @@ import ( "sort" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/constants" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources" diff --git a/pkg/tsdb/cloudwatch/services/regions_test.go b/pkg/tsdb/cloudwatch/services/regions_test.go index 7a3bb36a3d6..bb559ea5907 100644 --- a/pkg/tsdb/cloudwatch/services/regions_test.go +++ b/pkg/tsdb/cloudwatch/services/regions_test.go @@ -5,14 +5,14 @@ import ( "testing" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils" "github.com/stretchr/testify/assert" ) -var testLogger = log.New("test logger") +var testLogger = log.New().With("logger", "test.logger") func TestRegions(t *testing.T) { t.Run("returns regions from the api and merges them with default regions", func(t *testing.T) { diff --git a/pkg/tsdb/cloudwatch/time_series_query.go b/pkg/tsdb/cloudwatch/time_series_query.go index afb016917a5..eafb9b11a80 100644 --- a/pkg/tsdb/cloudwatch/time_series_query.go +++ b/pkg/tsdb/cloudwatch/time_series_query.go @@ -5,12 +5,12 @@ import ( "fmt" "regexp" - "github.com/grafana/grafana-plugin-sdk-go/backend" "golang.org/x/sync/errgroup" - "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/features" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" + "github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils" ) type responseWrapper struct { @@ -18,8 +18,8 @@ type responseWrapper struct { RefId string } -func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, logger log.Logger, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { - logger.Debug("Executing time series query") +func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { + e.logger.FromContext(ctx).Debug("Executing time series query") resp := backend.NewQueryDataResponse() if len(req.Queries) == 0 { @@ -37,7 +37,7 @@ func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, logger return nil, err } - requestQueries, err := models.ParseMetricDataQueries(req.Queries, startTime, endTime, instance.Settings.Region, logger, + requestQueries, err := models.ParseMetricDataQueries(req.Queries, startTime, endTime, instance.Settings.Region, e.logger.FromContext(ctx), features.IsEnabled(ctx, features.FlagCloudWatchCrossAccountQuerying)) if err != nil { return nil, err @@ -62,7 +62,7 @@ func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, logger batches := [][]*models.CloudWatchQuery{regionQueries} if features.IsEnabled(ctx, features.FlagCloudWatchBatchQueries) { - batches = getMetricQueryBatches(regionQueries, logger) + batches = getMetricQueryBatches(regionQueries, e.logger.FromContext(ctx)) } for _, batch := range batches { @@ -70,7 +70,7 @@ func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, logger eg.Go(func() error { defer func() { if err := recover(); err != nil { - logger.Error("Execute Get Metric Data Query Panic", "error", err, "stack", log.Stack(1)) + e.logger.FromContext(ctx).Error("Execute Get Metric Data Query Panic", "error", err, "stack", utils.Stack(1)) if theErr, ok := err.(error); ok { resultChan <- &responseWrapper{ DataResponse: &backend.DataResponse{ @@ -86,7 +86,7 @@ func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, logger return err } - metricDataInput, err := e.buildMetricDataInput(logger, startTime, endTime, requestQueries) + metricDataInput, err := e.buildMetricDataInput(startTime, endTime, requestQueries) if err != nil { return err } @@ -97,7 +97,7 @@ func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, logger } if features.IsEnabled(ctx, features.FlagCloudWatchWildCardDimensionValues) { - requestQueries, err = e.getDimensionValuesForWildcards(ctx, req.PluginContext, region, client, requestQueries, instance.tagValueCache, logger) + requestQueries, err = e.getDimensionValuesForWildcards(ctx, req.PluginContext, region, client, requestQueries, instance.tagValueCache) if err != nil { return err } diff --git a/pkg/tsdb/cloudwatch/time_series_query_test.go b/pkg/tsdb/cloudwatch/time_series_query_test.go index aba9d48fa20..9945211aefd 100644 --- a/pkg/tsdb/cloudwatch/time_series_query_test.go +++ b/pkg/tsdb/cloudwatch/time_series_query_test.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/stretchr/testify/mock" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/features" @@ -26,7 +27,7 @@ import ( ) func TestTimeSeriesQuery(t *testing.T) { - executor := newExecutor(nil, &fakeSessionCache{}) + executor := newExecutor(nil, &fakeSessionCache{}, log.NewNullLogger()) now := time.Now() origNewCWClient := NewCWClient @@ -52,7 +53,7 @@ func TestTimeSeriesQuery(t *testing.T) { im := defaultTestInstanceManager() - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) resp, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, @@ -117,7 +118,7 @@ func TestTimeSeriesQuery(t *testing.T) { }) t.Run("End time before start time should result in error", func(t *testing.T) { - _, err := executor.executeTimeSeriesQuery(context.Background(), logger, &backend.QueryDataRequest{Queries: []backend.DataQuery{{TimeRange: backend.TimeRange{ + _, err := executor.executeTimeSeriesQuery(context.Background(), &backend.QueryDataRequest{Queries: []backend.DataQuery{{TimeRange: backend.TimeRange{ From: now.Add(time.Hour * -1), To: now.Add(time.Hour * -2), }}}}) @@ -125,7 +126,7 @@ func TestTimeSeriesQuery(t *testing.T) { }) t.Run("End time equals start time should result in error", func(t *testing.T) { - _, err := executor.executeTimeSeriesQuery(context.Background(), logger, &backend.QueryDataRequest{Queries: []backend.DataQuery{{TimeRange: backend.TimeRange{ + _, err := executor.executeTimeSeriesQuery(context.Background(), &backend.QueryDataRequest{Queries: []backend.DataQuery{{TimeRange: backend.TimeRange{ From: now.Add(time.Hour * -1), To: now.Add(time.Hour * -1), }}}}) @@ -158,7 +159,7 @@ func Test_executeTimeSeriesQuery_getCWClient_is_called_once_per_region_and_GetMe mockMetricClient = mocks.MetricsAPI{} mockMetricClient.On("GetMetricDataWithContext", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil) - executor := newExecutor(im, mockSessionCache) + executor := newExecutor(im, mockSessionCache, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, @@ -209,7 +210,7 @@ func Test_executeTimeSeriesQuery_getCWClient_is_called_once_per_region_and_GetMe mockMetricClient = mocks.MetricsAPI{} mockMetricClient.On("GetMetricDataWithContext", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil) - executor := newExecutor(im, sessionCache) + executor := newExecutor(im, sessionCache, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, @@ -342,7 +343,7 @@ func Test_QueryData_timeSeriesQuery_GetMetricDataWithContext(t *testing.T) { t.Run("passes query label as GetMetricData label", func(t *testing.T) { api = mocks.MetricsAPI{} api.On("GetMetricDataWithContext", mock.Anything, mock.Anything, mock.Anything).Return(&cloudwatch.GetMetricDataOutput{}, nil) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) query := newTestQuery(t, queryParameters{ Label: aws.String("${PROP('Period')} some words ${PROP('Dim.InstanceId')}"), }) @@ -381,7 +382,7 @@ func Test_QueryData_timeSeriesQuery_GetMetricDataWithContext(t *testing.T) { t.Run(name, func(t *testing.T) { api = mocks.MetricsAPI{} api.On("GetMetricDataWithContext", mock.Anything, mock.Anything, mock.Anything).Return(&cloudwatch.GetMetricDataOutput{}, nil) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, @@ -432,7 +433,7 @@ func Test_QueryData_response_data_frame_name_is_always_response_label(t *testing }}, nil) im := defaultTestInstanceManager() - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) t.Run("where user defines search expression", func(t *testing.T) { query := newTestQuery(t, queryParameters{ @@ -589,7 +590,7 @@ func TestTimeSeriesQuery_CrossAccountQuerying(t *testing.T) { t.Run("should call GetMetricDataInput with AccountId nil when no AccountId is provided", func(t *testing.T) { api = mocks.MetricsAPI{} api.On("GetMetricDataWithContext", mock.Anything, mock.Anything, mock.Anything).Return(&cloudwatch.GetMetricDataOutput{}, nil) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(contextWithFeaturesEnabled(features.FlagCloudWatchCrossAccountQuerying), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ @@ -630,7 +631,7 @@ func TestTimeSeriesQuery_CrossAccountQuerying(t *testing.T) { t.Run("should call GetMetricDataInput with AccountId nil when feature flag is false", func(t *testing.T) { api = mocks.MetricsAPI{} api.On("GetMetricDataWithContext", mock.Anything, mock.Anything, mock.Anything).Return(&cloudwatch.GetMetricDataOutput{}, nil) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, @@ -671,7 +672,7 @@ func TestTimeSeriesQuery_CrossAccountQuerying(t *testing.T) { t.Run("should call GetMetricDataInput with AccountId in a MetricStat query", func(t *testing.T) { api = mocks.MetricsAPI{} api.On("GetMetricDataWithContext", mock.Anything, mock.Anything, mock.Anything).Return(&cloudwatch.GetMetricDataOutput{}, nil) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(contextWithFeaturesEnabled(features.FlagCloudWatchCrossAccountQuerying), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, @@ -712,7 +713,7 @@ func TestTimeSeriesQuery_CrossAccountQuerying(t *testing.T) { t.Run("should GetMetricDataInput with AccountId in an inferred search expression query", func(t *testing.T) { api = mocks.MetricsAPI{} api.On("GetMetricDataWithContext", mock.Anything, mock.Anything, mock.Anything).Return(&cloudwatch.GetMetricDataOutput{}, nil) - executor := newExecutor(im, &fakeSessionCache{}) + executor := newExecutor(im, &fakeSessionCache{}, log.NewNullLogger()) _, err := executor.QueryData(contextWithFeaturesEnabled(features.FlagCloudWatchCrossAccountQuerying), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, diff --git a/pkg/tsdb/cloudwatch/utils/utils.go b/pkg/tsdb/cloudwatch/utils/utils.go index 65a4cc8ba4d..55163896228 100644 --- a/pkg/tsdb/cloudwatch/utils/utils.go +++ b/pkg/tsdb/cloudwatch/utils/utils.go @@ -1,3 +1,13 @@ package utils +import "github.com/go-stack/stack" + func Pointer[T any](arg T) *T { return &arg } + +// Stack is copied from grafana/pkg/infra/log +// TODO: maybe this should live in grafana-plugin-sdk-go? +func Stack(skip int) string { + call := stack.Caller(skip) + s := stack.Trace().TrimBelow(call).TrimRuntime() + return s.String() +}