Explore/Loki: Display live tailed logs in correct order (#18031)
Closes #18027
This commit is contained in:
@@ -324,10 +324,6 @@ export function logSeriesToLogsModel(logSeries: DataFrame[]): LogsModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortedRows = rows.sort((a, b) => {
|
|
||||||
return a.timestamp > b.timestamp ? -1 : 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Meta data to display in status
|
// Meta data to display in status
|
||||||
const meta: LogsMetaItem[] = [];
|
const meta: LogsMetaItem[] = [];
|
||||||
if (_.size(commonLabels) > 0) {
|
if (_.size(commonLabels) > 0) {
|
||||||
@@ -343,7 +339,7 @@ export function logSeriesToLogsModel(logSeries: DataFrame[]): LogsModel {
|
|||||||
if (limits.length > 0) {
|
if (limits.length > 0) {
|
||||||
meta.push({
|
meta.push({
|
||||||
label: 'Limit',
|
label: 'Limit',
|
||||||
value: `${limits[0].meta.limit} (${sortedRows.length} returned)`,
|
value: `${limits[0].meta.limit} (${rows.length} returned)`,
|
||||||
kind: LogsMetaKind.String,
|
kind: LogsMetaKind.String,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -351,7 +347,7 @@ export function logSeriesToLogsModel(logSeries: DataFrame[]): LogsModel {
|
|||||||
return {
|
return {
|
||||||
hasUniqueLabels,
|
hasUniqueLabels,
|
||||||
meta,
|
meta,
|
||||||
rows: sortedRows,
|
rows,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -418,13 +418,6 @@ describe('dataFrameToLogsModel', () => {
|
|||||||
expect(logsModel.hasUniqueLabels).toBeFalsy();
|
expect(logsModel.hasUniqueLabels).toBeFalsy();
|
||||||
expect(logsModel.rows).toHaveLength(2);
|
expect(logsModel.rows).toHaveLength(2);
|
||||||
expect(logsModel.rows).toMatchObject([
|
expect(logsModel.rows).toMatchObject([
|
||||||
{
|
|
||||||
timestamp: '2019-04-26T14:42:50.991981292Z',
|
|
||||||
entry: 't=2019-04-26T16:42:50+0200 lvl=eror msg="new token…t unhashed token=56d9fdc5c8b7400bd51b060eea8ca9d7',
|
|
||||||
labels: { filename: '/var/log/grafana/grafana.log', job: 'grafana' },
|
|
||||||
logLevel: 'error',
|
|
||||||
uniqueLabels: {},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
timestamp: '2019-04-26T09:28:11.352440161Z',
|
timestamp: '2019-04-26T09:28:11.352440161Z',
|
||||||
entry: 't=2019-04-26T11:05:28+0200 lvl=info msg="Initializing DatasourceCacheService" logger=server',
|
entry: 't=2019-04-26T11:05:28+0200 lvl=info msg="Initializing DatasourceCacheService" logger=server',
|
||||||
@@ -432,6 +425,13 @@ describe('dataFrameToLogsModel', () => {
|
|||||||
logLevel: 'info',
|
logLevel: 'info',
|
||||||
uniqueLabels: {},
|
uniqueLabels: {},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
timestamp: '2019-04-26T14:42:50.991981292Z',
|
||||||
|
entry: 't=2019-04-26T16:42:50+0200 lvl=eror msg="new token…t unhashed token=56d9fdc5c8b7400bd51b060eea8ca9d7',
|
||||||
|
labels: { filename: '/var/log/grafana/grafana.log', job: 'grafana' },
|
||||||
|
logLevel: 'error',
|
||||||
|
uniqueLabels: {},
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(logsModel.series).toHaveLength(2);
|
expect(logsModel.series).toHaveLength(2);
|
||||||
@@ -524,12 +524,6 @@ describe('dataFrameToLogsModel', () => {
|
|||||||
expect(logsModel.hasUniqueLabels).toBeTruthy();
|
expect(logsModel.hasUniqueLabels).toBeTruthy();
|
||||||
expect(logsModel.rows).toHaveLength(3);
|
expect(logsModel.rows).toHaveLength(3);
|
||||||
expect(logsModel.rows).toMatchObject([
|
expect(logsModel.rows).toMatchObject([
|
||||||
{
|
|
||||||
entry: 'INFO 2',
|
|
||||||
labels: { foo: 'bar', baz: '2' },
|
|
||||||
logLevel: LogLevel.error,
|
|
||||||
uniqueLabels: { baz: '2' },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
entry: 'WARN boooo',
|
entry: 'WARN boooo',
|
||||||
labels: { foo: 'bar', baz: '1' },
|
labels: { foo: 'bar', baz: '1' },
|
||||||
@@ -542,6 +536,12 @@ describe('dataFrameToLogsModel', () => {
|
|||||||
logLevel: LogLevel.error,
|
logLevel: LogLevel.error,
|
||||||
uniqueLabels: { baz: '2' },
|
uniqueLabels: { baz: '2' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
entry: 'INFO 2',
|
||||||
|
labels: { foo: 'bar', baz: '2' },
|
||||||
|
logLevel: LogLevel.error,
|
||||||
|
uniqueLabels: { baz: '2' },
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(logsModel.series).toHaveLength(2);
|
expect(logsModel.series).toHaveLength(2);
|
||||||
|
|||||||
@@ -487,11 +487,11 @@ export const getRefIds = (value: any): string[] => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const sortInAscendingOrder = (a: LogRowModel, b: LogRowModel) => {
|
const sortInAscendingOrder = (a: LogRowModel, b: LogRowModel) => {
|
||||||
if (a.timeEpochMs < b.timeEpochMs) {
|
if (a.timestamp < b.timestamp) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.timeEpochMs > b.timeEpochMs) {
|
if (a.timestamp > b.timestamp) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,11 +499,11 @@ const sortInAscendingOrder = (a: LogRowModel, b: LogRowModel) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const sortInDescendingOrder = (a: LogRowModel, b: LogRowModel) => {
|
const sortInDescendingOrder = (a: LogRowModel, b: LogRowModel) => {
|
||||||
if (a.timeEpochMs > b.timeEpochMs) {
|
if (a.timestamp > b.timestamp) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.timeEpochMs < b.timeEpochMs) {
|
if (a.timestamp < b.timestamp) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,9 +72,10 @@ export class ResultProcessor {
|
|||||||
const graphInterval = this.state.queryIntervals.intervalMs;
|
const graphInterval = this.state.queryIntervals.intervalMs;
|
||||||
const dataFrame = this.rawData.map(result => guessFieldTypes(toDataFrame(result)));
|
const dataFrame = this.rawData.map(result => guessFieldTypes(toDataFrame(result)));
|
||||||
const newResults = this.rawData ? dataFrameToLogsModel(dataFrame, graphInterval) : null;
|
const newResults = this.rawData ? dataFrameToLogsModel(dataFrame, graphInterval) : null;
|
||||||
|
const sortedNewResults = sortLogsResult(newResults, this.state.refreshInterval);
|
||||||
|
|
||||||
if (this.replacePreviousResults) {
|
if (this.replacePreviousResults) {
|
||||||
return newResults;
|
return sortedNewResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prevLogsResult: LogsModel = this.state.logsResult || { hasUniqueLabels: false, rows: [] };
|
const prevLogsResult: LogsModel = this.state.logsResult || { hasUniqueLabels: false, rows: [] };
|
||||||
@@ -86,17 +87,17 @@ export class ResultProcessor {
|
|||||||
for (const row of rowsInState) {
|
for (const row of rowsInState) {
|
||||||
processedRows.push({ ...row, fresh: false });
|
processedRows.push({ ...row, fresh: false });
|
||||||
}
|
}
|
||||||
for (const row of newResults.rows) {
|
for (const row of sortedNewResults.rows) {
|
||||||
processedRows.push({ ...row, fresh: true });
|
processedRows.push({ ...row, fresh: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
const processedSeries = this.mergeGraphResults(newResults.series, seriesInState);
|
const processedSeries = this.mergeGraphResults(sortedNewResults.series, seriesInState);
|
||||||
|
|
||||||
const slice = -1000;
|
const slice = -1000;
|
||||||
const rows = processedRows.slice(slice);
|
const rows = processedRows.slice(slice);
|
||||||
const series = processedSeries.slice(slice);
|
const series = processedSeries.slice(slice);
|
||||||
|
|
||||||
return { ...newResults, rows, series };
|
return { ...sortedNewResults, rows, series };
|
||||||
};
|
};
|
||||||
|
|
||||||
private makeTimeSeriesList = (rawData: any[]) => {
|
private makeTimeSeriesList = (rawData: any[]) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user