Loki Query Chunking: Group queries by resolution (#65353)

* Loki chunking: group queries by resolution

* Update unit tests

* Add chunked + grouped test case
This commit is contained in:
Matias Chomicki 2023-03-30 10:29:19 +02:00 committed by GitHub
parent c77aa11545
commit fc16fb0407
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 20 deletions

View File

@ -260,4 +260,73 @@ describe('runQueryInChunks()', () => {
});
});
});
describe('Splitting targets based on resolution', () => {
const range1d = {
from: dateTime('2023-02-08T05:00:00.000Z'),
to: dateTime('2023-02-09T05:00:00.000Z'),
raw: {
from: dateTime('2023-02-08T05:00:00.000Z'),
to: dateTime('2023-02-09T05:00:00.000Z'),
},
};
test('Groups logs queries by resolution', async () => {
const request = getQueryOptions<LokiQuery>({
targets: [
{ expr: '{a="b"}', refId: 'A', resolution: 3 },
{ expr: '{a="b"}', refId: 'B', resolution: 5 },
],
range: range1d,
});
await expect(runQueryInChunks(datasource, request)).toEmitValuesWith(() => {
// A, B
expect(datasource.runQuery).toHaveBeenCalledTimes(2);
});
});
test('Groups metric queries by resolution', async () => {
const request = getQueryOptions<LokiQuery>({
targets: [
{ expr: 'count_over_time({a="b"}[1m])', refId: 'A', resolution: 3 },
{ expr: 'count_over_time{a="b"}[1m])', refId: 'B', resolution: 5 },
],
range: range1d,
});
await expect(runQueryInChunks(datasource, request)).toEmitValuesWith(() => {
// A, B
expect(datasource.runQuery).toHaveBeenCalledTimes(2);
});
});
test('Groups mixed queries by resolution', async () => {
const request = getQueryOptions<LokiQuery>({
targets: [
{ expr: '{a="b"}', refId: 'A', resolution: 3 },
{ expr: '{a="b"}', refId: 'B', resolution: 5 },
{ expr: 'count_over_time({a="b"}[1m])', refId: 'C', resolution: 3 },
{ expr: 'count_over_time{a="b"}[1m])', refId: 'D', resolution: 5 },
{ expr: '{a="b"}', refId: 'E', resolution: 5, queryType: LokiQueryType.Instant },
],
range: range1d,
});
await expect(runQueryInChunks(datasource, request)).toEmitValuesWith(() => {
// A, B, C, D, E
expect(datasource.runQuery).toHaveBeenCalledTimes(5);
});
});
test('Chunked groups mixed queries by resolution', async () => {
const request = getQueryOptions<LokiQuery>({
targets: [
{ expr: '{a="b"}', refId: 'A', resolution: 3 },
{ expr: '{a="b"}', refId: 'B', resolution: 5 },
{ expr: 'count_over_time({a="b"}[1m])', refId: 'C', resolution: 3 },
{ expr: 'count_over_time{a="b"}[1m])', refId: 'D', resolution: 5 },
{ expr: '{a="b"}', refId: 'E', resolution: 5, queryType: LokiQueryType.Instant },
],
range, // 3 days
});
await expect(runQueryInChunks(datasource, request)).toEmitValuesWith(() => {
// 3 * A, 3 * B, 3 * C, 3 * D, 1 * E
expect(datasource.runQuery).toHaveBeenCalledTimes(13);
});
});
});
});

View File

@ -184,29 +184,35 @@ export function runQueryInChunks(datasource: LokiDatasource, request: DataQueryR
const requests: LokiGroupedRequest = [];
for (const [chunkRangeMs, queries] of Object.entries(rangePartitionedLogQueries)) {
requests.push({
request: { ...request, targets: queries },
partition: partitionTimeRange(
true,
request.range,
request.intervalMs,
queries[0].resolution ?? 1,
Number(chunkRangeMs)
),
});
const resolutionPartition = groupBy(queries, (query) => query.resolution || 1);
for (const resolution in resolutionPartition) {
requests.push({
request: { ...request, targets: resolutionPartition[resolution] },
partition: partitionTimeRange(
true,
request.range,
request.intervalMs,
Number(resolution),
Number(chunkRangeMs)
),
});
}
}
for (const [chunkRangeMs, queries] of Object.entries(rangePartitionedMetricQueries)) {
requests.push({
request: { ...request, targets: queries },
partition: partitionTimeRange(
false,
request.range,
request.intervalMs,
queries[0].resolution ?? 1,
Number(chunkRangeMs)
),
});
const resolutionPartition = groupBy(queries, (query) => query.resolution || 1);
for (const resolution in resolutionPartition) {
requests.push({
request: { ...request, targets: resolutionPartition[resolution] },
partition: partitionTimeRange(
false,
request.range,
request.intervalMs,
Number(resolution),
Number(chunkRangeMs)
),
});
}
}
if (instantQueries.length) {