Cloudwatch: Use generic null-insertion mechanism (#43507)

* Cloudwatch: Fix nil values for a period gap in metrics

* Use fields periods for intervals
This commit is contained in:
Shirley 2022-02-10 10:17:45 +01:00 committed by GitHub
parent 5ded070aab
commit 5edcc2e795
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 9 deletions

View File

@ -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)

View File

@ -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)
})

View File

@ -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', () => {

View File

@ -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,