diff --git a/pkg/tsdb/cloudwatch/response_parser.go b/pkg/tsdb/cloudwatch/response_parser.go index bde11158555..be530a7fb2e 100644 --- a/pkg/tsdb/cloudwatch/response_parser.go +++ b/pkg/tsdb/cloudwatch/response_parser.go @@ -162,13 +162,6 @@ func buildDataFrames(startTime time.Time, endTime time.Time, aggregatedResponse timestamps := []*time.Time{} points := []*float64{} for j, t := range metric.Timestamps { - if j > 0 { - expectedTimestamp := metric.Timestamps[j-1].Add(time.Duration(query.Period) * time.Second) - if expectedTimestamp.Before(*t) { - timestamps = append(timestamps, &expectedTimestamp) - points = append(points, nil) - } - } val := metric.Values[j] timestamps = append(timestamps, t) points = append(points, val) diff --git a/pkg/tsdb/cloudwatch/response_parser_test.go b/pkg/tsdb/cloudwatch/response_parser_test.go index 3079092ccb3..16195076e6f 100644 --- a/pkg/tsdb/cloudwatch/response_parser_test.go +++ b/pkg/tsdb/cloudwatch/response_parser_test.go @@ -422,8 +422,7 @@ func TestCloudWatchResponseParser(t *testing.T) { assert.Equal(t, "lb", frame.Fields[1].Labels["LoadBalancer"]) assert.Equal(t, 10.0, *frame.Fields[1].At(0).(*float64)) assert.Equal(t, 20.0, *frame.Fields[1].At(1).(*float64)) - assert.Nil(t, frame.Fields[1].At(2)) - assert.Equal(t, 30.0, *frame.Fields[1].At(3).(*float64)) + assert.Equal(t, 30.0, *frame.Fields[1].At(2).(*float64)) assert.Equal(t, "Value", frame.Fields[1].Name) assert.Equal(t, "", frame.Fields[1].Config.DisplayName) }) diff --git a/public/app/plugins/datasource/cloudwatch/datasource.test.ts b/public/app/plugins/datasource/cloudwatch/datasource.test.ts index ecf94527947..591e95dcee6 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.test.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.test.ts @@ -225,6 +225,36 @@ describe('datasource', () => { expect(response.data.length).toEqual(2); }); }); + + it('sets fields.config.interval based on period', async () => { + const { datasource } = setupMockedDataSource({ + data: { + results: { + a: { + refId: 'a', + series: [{ name: 'cpu', points: [1, 2], meta: { custom: { period: 60 } } }], + }, + b: { + refId: 'b', + series: [{ name: 'cpu', points: [1, 2], meta: { custom: { period: 120 } } }], + }, + }, + }, + }); + + const observable = datasource.performTimeSeriesQuery( + { + queries: [{ datasourceId: 1, refId: 'a' }], + } as any, + { from: dateTime(), to: dateTime() } as any + ); + + await expect(observable).toEmitValuesWith((received) => { + const response = received[0]; + expect(response.data[0].fields[0].config.interval).toEqual(60000); + expect(response.data[1].fields[0].config.interval).toEqual(120000); + }); + }); }); describe('describeLogGroup', () => { diff --git a/public/app/plugins/datasource/cloudwatch/datasource.ts b/public/app/plugins/datasource/cloudwatch/datasource.ts index 71e9decdc79..660ca54ddfb 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.ts @@ -13,6 +13,7 @@ import { DataSourceInstanceSettings, DataSourceWithLogsContextSupport, dateMath, + FieldType, LoadingState, LogRowModel, rangeUtil, @@ -506,6 +507,15 @@ export class CloudWatchDatasource const lastError = findLast(res.results, (v) => !!v.error); + dataframes.forEach((frame) => { + frame.fields.forEach((field) => { + if (field.type === FieldType.time) { + // field.config.interval is populated in order for Grafana to fill in null values at frame intervals + field.config.interval = frame.meta?.custom?.period * 1000; + } + }); + }); + return { data: dataframes, error: lastError ? { message: lastError.error } : null,