From a1f90521a0b247613cd5721f70b1b7fb4c7bb9fb Mon Sep 17 00:00:00 2001 From: kay delaney <45561153+kaydelaney@users.noreply.github.com> Date: Wed, 19 Aug 2020 15:18:04 +0100 Subject: [PATCH] CloudWatch Logs: Move query response stats to appropriate FrameMeta property (#26732) * CloudWatch Logs: Move query response stats to appropriate FrameMeta property --- pkg/tsdb/cloudwatch/log_actions_test.go | 17 +++++-- pkg/tsdb/cloudwatch/log_query.go | 44 +++++++++++++++++-- pkg/tsdb/cloudwatch/log_query_test.go | 17 +++++-- .../datasource/cloudwatch/datasource.ts | 3 +- .../cloudwatch/specs/datasource.test.ts | 17 ++++--- 5 files changed, 80 insertions(+), 18 deletions(-) diff --git a/pkg/tsdb/cloudwatch/log_actions_test.go b/pkg/tsdb/cloudwatch/log_actions_test.go index 755ecf3903f..223dfa1721a 100644 --- a/pkg/tsdb/cloudwatch/log_actions_test.go +++ b/pkg/tsdb/cloudwatch/log_actions_test.go @@ -489,10 +489,19 @@ func TestQuery_GetQueryResults(t *testing.T) { expFrame.Meta = &data.FrameMeta{ Custom: map[string]interface{}{ "Status": "Complete", - "Statistics": cloudwatchlogs.QueryStatistics{ - BytesScanned: aws.Float64(512), - RecordsMatched: aws.Float64(256), - RecordsScanned: aws.Float64(1024), + }, + Stats: []data.QueryStat{ + { + FieldConfig: data.FieldConfig{DisplayName: "Bytes scanned"}, + Value: 512, + }, + { + FieldConfig: data.FieldConfig{DisplayName: "Records scanned"}, + Value: 1024, + }, + { + FieldConfig: data.FieldConfig{DisplayName: "Records matched"}, + Value: 256, }, }, PreferredVisualization: "logs", diff --git a/pkg/tsdb/cloudwatch/log_query.go b/pkg/tsdb/cloudwatch/log_query.go index 218018f65ba..3f8941184d0 100644 --- a/pkg/tsdb/cloudwatch/log_query.go +++ b/pkg/tsdb/cloudwatch/log_query.go @@ -12,6 +12,10 @@ import ( ) func logsResultsToDataframes(response *cloudwatchlogs.GetQueryResultsOutput) (*data.Frame, error) { + if response == nil { + return nil, fmt.Errorf("response is nil, cannot convert log results to data frames") + } + nonEmptyRows := make([][]*cloudwatchlogs.ResultField, 0) // Sometimes CloudWatch can send empty rows for _, row := range response.Results { @@ -94,12 +98,44 @@ func logsResultsToDataframes(response *cloudwatchlogs.GetQueryResultsOutput) (*d } } + queryStats := make([]data.QueryStat, 0) + if response.Statistics != nil { + if response.Statistics.BytesScanned != nil { + queryStats = append(queryStats, data.QueryStat{ + FieldConfig: data.FieldConfig{DisplayName: "Bytes scanned"}, + Value: *response.Statistics.BytesScanned, + }) + } + + if response.Statistics.RecordsScanned != nil { + queryStats = append(queryStats, data.QueryStat{ + FieldConfig: data.FieldConfig{DisplayName: "Records scanned"}, + Value: *response.Statistics.RecordsScanned, + }) + } + + if response.Statistics.RecordsMatched != nil { + queryStats = append(queryStats, data.QueryStat{ + FieldConfig: data.FieldConfig{DisplayName: "Records matched"}, + Value: *response.Statistics.RecordsMatched, + }) + } + } + frame := data.NewFrame("CloudWatchLogsResponse", newFields...) frame.Meta = &data.FrameMeta{ - Custom: map[string]interface{}{ - "Status": *response.Status, - "Statistics": *response.Statistics, - }, + Stats: nil, + Custom: nil, + } + + if len(queryStats) > 0 { + frame.Meta.Stats = queryStats + } + + if response.Status != nil { + frame.Meta.Custom = map[string]interface{}{ + "Status": *response.Status, + } } // Results aren't guaranteed to come ordered by time (ascending), so we need to sort diff --git a/pkg/tsdb/cloudwatch/log_query_test.go b/pkg/tsdb/cloudwatch/log_query_test.go index 3b2fa119cbd..ca61ac7ac23 100644 --- a/pkg/tsdb/cloudwatch/log_query_test.go +++ b/pkg/tsdb/cloudwatch/log_query_test.go @@ -195,10 +195,19 @@ func TestLogsResultsToDataframes(t *testing.T) { Meta: &data.FrameMeta{ Custom: map[string]interface{}{ "Status": "ok", - "Statistics": cloudwatchlogs.QueryStatistics{ - BytesScanned: aws.Float64(2000), - RecordsMatched: aws.Float64(3), - RecordsScanned: aws.Float64(5000), + }, + Stats: []data.QueryStat{ + { + FieldConfig: data.FieldConfig{DisplayName: "Bytes scanned"}, + Value: 2000, + }, + { + FieldConfig: data.FieldConfig{DisplayName: "Records scanned"}, + Value: 5000, + }, + { + FieldConfig: data.FieldConfig{DisplayName: "Records matched"}, + Value: 3, }, }, }, diff --git a/public/app/plugins/datasource/cloudwatch/datasource.ts b/public/app/plugins/datasource/cloudwatch/datasource.ts index 81dcfaa3f8f..ebd66f0bc17 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.ts @@ -248,7 +248,8 @@ export class CloudWatchDatasource extends DataSourceApi { let moreRecordsMatched = false; for (const frame of frames) { - const recordsMatched = frame.meta?.custom?.['Statistics']['RecordsMatched']; + const recordsMatched = frame.meta?.stats?.find(stat => stat.displayName === 'Records matched') + ?.value!; if (recordsMatched > (prevRecordsMatched[frame.refId!] ?? 0)) { moreRecordsMatched = true; } diff --git a/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts b/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts index b44133ccbe0..d65ab8b3eb9 100644 --- a/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts +++ b/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts @@ -167,8 +167,11 @@ describe('CloudWatchDatasource', () => { it('should stop querying when no more data retrieved past max attempts', async () => { const fakeFrames = genMockFrames(10); for (let i = 7; i < fakeFrames.length; i++) { - fakeFrames[i].meta!.custom!['Statistics']['RecordsMatched'] = fakeFrames[6].meta!.custom!['Statistics'][ - 'RecordsMatched' + fakeFrames[i].meta!.stats = [ + { + displayName: 'Records matched', + value: fakeFrames[6].meta!.stats?.find(stat => stat.displayName === 'Records matched')?.value!, + }, ]; } @@ -193,6 +196,7 @@ describe('CloudWatchDatasource', () => { ...fakeFrames[MAX_ATTEMPTS - 1].meta!.custom, Status: 'Complete', }, + stats: fakeFrames[MAX_ATTEMPTS - 1].meta!.stats, }, }, ]; @@ -1101,10 +1105,13 @@ function genMockFrames(numResponses: number): DataFrame[] { meta: { custom: { Status: i === numResponses - 1 ? CloudWatchLogsQueryStatus.Complete : CloudWatchLogsQueryStatus.Running, - Statistics: { - RecordsMatched: (i + 1) * recordIncrement, - }, }, + stats: [ + { + displayName: 'Records matched', + value: (i + 1) * recordIncrement, + }, + ], }, length: 0, });