loki: query splitting: labels-based frame matching (#66677)

This commit is contained in:
Gábor Farkas
2023-04-18 12:04:51 +02:00
committed by GitHub
parent 5d4bf19efb
commit bf3ac0ff18
3 changed files with 64 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
import { import {
ArrayVector, ArrayVector,
DataFrame, DataFrame,
DataFrameType,
DataSourceInstanceSettings, DataSourceInstanceSettings,
DataSourceSettings, DataSourceSettings,
FieldType, FieldType,
@@ -151,6 +152,9 @@ export function getMockFrames() {
}, },
], ],
meta: { meta: {
custom: {
frameType: 'LabeledTimeValues',
},
stats: [ stats: [
{ displayName: 'Summary: total bytes processed', unit: 'decbytes', value: 11 }, { displayName: 'Summary: total bytes processed', unit: 'decbytes', value: 11 },
{ displayName: 'Ingester: total reached', value: 1 }, { displayName: 'Ingester: total reached', value: 1 },
@@ -198,6 +202,9 @@ export function getMockFrames() {
}, },
], ],
meta: { meta: {
custom: {
frameType: 'LabeledTimeValues',
},
stats: [ stats: [
{ displayName: 'Summary: total bytes processed', unit: 'decbytes', value: 22 }, { displayName: 'Summary: total bytes processed', unit: 'decbytes', value: 22 },
{ displayName: 'Ingester: total reached', value: 2 }, { displayName: 'Ingester: total reached', value: 2 },
@@ -220,9 +227,13 @@ export function getMockFrames() {
type: FieldType.number, type: FieldType.number,
config: {}, config: {},
values: new ArrayVector([5, 4]), values: new ArrayVector([5, 4]),
labels: {
level: 'debug',
},
}, },
], ],
meta: { meta: {
type: DataFrameType.TimeSeriesMulti,
stats: [ stats: [
{ displayName: 'Ingester: total reached', value: 1 }, { displayName: 'Ingester: total reached', value: 1 },
{ displayName: 'Summary: total bytes processed', unit: 'decbytes', value: 11 }, { displayName: 'Summary: total bytes processed', unit: 'decbytes', value: 11 },
@@ -245,9 +256,13 @@ export function getMockFrames() {
type: FieldType.number, type: FieldType.number,
config: {}, config: {},
values: new ArrayVector([6, 7]), values: new ArrayVector([6, 7]),
labels: {
level: 'debug',
},
}, },
], ],
meta: { meta: {
type: DataFrameType.TimeSeriesMulti,
stats: [ stats: [
{ displayName: 'Ingester: total reached', value: 2 }, { displayName: 'Ingester: total reached', value: 2 },
{ displayName: 'Summary: total bytes processed', unit: 'decbytes', value: 22 }, { displayName: 'Summary: total bytes processed', unit: 'decbytes', value: 22 },
@@ -271,9 +286,13 @@ export function getMockFrames() {
type: FieldType.number, type: FieldType.number,
config: {}, config: {},
values: new ArrayVector([6, 7]), values: new ArrayVector([6, 7]),
labels: {
level: 'error',
},
}, },
], ],
meta: { meta: {
type: DataFrameType.TimeSeriesMulti,
stats: [ stats: [
{ displayName: 'Ingester: total reached', value: 2 }, { displayName: 'Ingester: total reached', value: 2 },
{ displayName: 'Summary: total bytes processed', unit: 'decbytes', value: 33 }, { displayName: 'Summary: total bytes processed', unit: 'decbytes', value: 33 },

View File

@@ -191,6 +191,9 @@ describe('combineResponses', () => {
], ],
length: 4, length: 4,
meta: { meta: {
custom: {
frameType: 'LabeledTimeValues',
},
stats: [ stats: [
{ {
displayName: 'Summary: total bytes processed', displayName: 'Summary: total bytes processed',
@@ -228,10 +231,14 @@ describe('combineResponses', () => {
name: 'Value', name: 'Value',
type: 'number', type: 'number',
values: new ArrayVector([6, 7, 5, 4]), values: new ArrayVector([6, 7, 5, 4]),
labels: {
level: 'debug',
},
}, },
], ],
length: 4, length: 4,
meta: { meta: {
type: 'timeseries-multi',
stats: [ stats: [
{ {
displayName: 'Summary: total bytes processed', displayName: 'Summary: total bytes processed',
@@ -269,10 +276,14 @@ describe('combineResponses', () => {
name: 'Value', name: 'Value',
type: 'number', type: 'number',
values: new ArrayVector([6, 7, 5, 4]), values: new ArrayVector([6, 7, 5, 4]),
labels: {
level: 'debug',
},
}, },
], ],
length: 4, length: 4,
meta: { meta: {
type: 'timeseries-multi',
stats: [ stats: [
{ {
displayName: 'Summary: total bytes processed', displayName: 'Summary: total bytes processed',

View File

@@ -1,6 +1,7 @@
import { import {
ArrayVector, ArrayVector,
DataFrame, DataFrame,
DataFrameType,
DataQueryResponse, DataQueryResponse,
DataQueryResponseData, DataQueryResponseData,
Field, Field,
@@ -8,6 +9,7 @@ import {
isValidGoDuration, isValidGoDuration,
Labels, Labels,
QueryResultMetaStat, QueryResultMetaStat,
shallowCompare,
} from '@grafana/data'; } from '@grafana/data';
import { isBytesString } from './languageUtils'; import { isBytesString } from './languageUtils';
@@ -123,7 +125,38 @@ function shouldCombine(frame1: DataFrame, frame2: DataFrame): boolean {
return false; return false;
} }
return frame1.name === frame2.name; const frameType1 = frame1.meta?.type;
const frameType2 = frame2.meta?.type;
if (frameType1 !== frameType2) {
// we do not join things that have a different type
return false;
}
// metric range query data
if (frameType1 === DataFrameType.TimeSeriesMulti) {
const field1 = frame1.fields.find((f) => f.type === FieldType.number);
const field2 = frame2.fields.find((f) => f.type === FieldType.number);
if (field1 === undefined || field2 === undefined) {
// should never happen
return false;
}
return shallowCompare(field1.labels ?? {}, field2.labels ?? {});
}
// logs query data
// logs use a special attribute in the dataframe's "custom" section
// because we do not have a good "frametype" value for them yet.
const customType1 = frame1.meta?.custom?.frameType;
const customType2 = frame2.meta?.custom?.frameType;
if (customType1 === 'LabeledTimeValues' && customType2 === 'LabeledTimeValues') {
return true;
}
// should never reach here
return false;
} }
export function combineResponses(currentResult: DataQueryResponse | null, newResult: DataQueryResponse) { export function combineResponses(currentResult: DataQueryResponse | null, newResult: DataQueryResponse) {