mirror of
https://github.com/grafana/grafana.git
synced 2025-09-25 16:03:46 +08:00
Loki: add backend-forward mode to queries, update log-row-context (#47726)
* loki: add helper function to sort dataframe by time * loki: add direction-attribute to queries * loki: make log-row-context code backward-compatible * better comment Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> * fixed test * simplified code Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
This commit is contained in:
70
public/app/plugins/datasource/loki/sortDataFrame.ts
Normal file
70
public/app/plugins/datasource/loki/sortDataFrame.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import { DataFrame, Field, SortedVector } from '@grafana/data';
|
||||
|
||||
type SortDirection = 'ASCENDING' | 'DESCENDING';
|
||||
|
||||
// creates the `index` for the sorting.
|
||||
// this is needed by the `SortedVector`.
|
||||
// the index is an array of numbers, and it defines an order.
|
||||
// at every slot in the index the values is the position of
|
||||
// the sorted item.
|
||||
// for example, an index of [3,1,2] means that
|
||||
// in the dataframe, that has 3 rows, after sorting:
|
||||
// - the third row will become the first
|
||||
// - the first row will become the second
|
||||
// - the second row will become the third
|
||||
function makeIndex(field: Field<string>, dir: SortDirection): number[] {
|
||||
const fieldValues: string[] = field.values.toArray();
|
||||
|
||||
// we first build an array which is [0,1,2,3....]
|
||||
const index = Array(fieldValues.length);
|
||||
for (let i = 0; i < index.length; i++) {
|
||||
index[i] = i;
|
||||
}
|
||||
|
||||
const isAsc = dir === 'ASCENDING';
|
||||
|
||||
index.sort((a: number, b: number): number => {
|
||||
// we need to answer this question:
|
||||
// in the field-used-for-sorting, how would we compare value-at-index-a to value-at-index-b?
|
||||
const valA = fieldValues[a];
|
||||
const valB = fieldValues[b];
|
||||
if (valA < valB) {
|
||||
return isAsc ? -1 : 1;
|
||||
}
|
||||
|
||||
if (valA > valB) {
|
||||
return isAsc ? 1 : -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
// sort a dataframe that is in the Loki format ascending or descending,
|
||||
// based on the nanosecond-timestamp
|
||||
export function sortDataFrameByTime(frame: DataFrame, dir: SortDirection): DataFrame {
|
||||
const { fields, ...rest } = frame;
|
||||
|
||||
// we use the approach used in @grafana/data/sortDataframe.
|
||||
// we cannot use it directly, because our tsNs field has a type=time,
|
||||
// so we have to build the `index` manually.
|
||||
|
||||
const tsNsField = fields.find((field) => field.name === 'tsNs');
|
||||
if (tsNsField === undefined) {
|
||||
throw new Error('missing nanosecond-timestamp field. should never happen');
|
||||
}
|
||||
|
||||
const index = makeIndex(tsNsField, dir);
|
||||
|
||||
return {
|
||||
...rest,
|
||||
fields: fields.map((field) => ({
|
||||
...field,
|
||||
values: new SortedVector(field.values, index),
|
||||
})),
|
||||
};
|
||||
|
||||
return frame;
|
||||
}
|
Reference in New Issue
Block a user