Explore/Loki: Display live tailed logs in correct order (#18031)

Closes #18027
pull/18039/head
kay delaney 7 years ago committed by GitHub
parent ffa9429c68
commit bf7fb67f73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      public/app/core/logs_model.ts
  2. 24
      public/app/core/specs/logs_model.test.ts
  3. 8
      public/app/core/utils/explore.ts
  4. 9
      public/app/features/explore/utils/ResultProcessor.ts

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

@ -419,17 +419,17 @@ describe('dataFrameToLogsModel', () => {
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', timestamp: '2019-04-26T09:28:11.352440161Z',
entry: 't=2019-04-26T16:42:50+0200 lvl=eror msg="new token…t unhashed token=56d9fdc5c8b7400bd51b060eea8ca9d7', entry: 't=2019-04-26T11:05:28+0200 lvl=info msg="Initializing DatasourceCacheService" logger=server',
labels: { filename: '/var/log/grafana/grafana.log', job: 'grafana' }, labels: { filename: '/var/log/grafana/grafana.log', job: 'grafana' },
logLevel: 'error', logLevel: 'info',
uniqueLabels: {}, uniqueLabels: {},
}, },
{ {
timestamp: '2019-04-26T09:28:11.352440161Z', timestamp: '2019-04-26T14:42:50.991981292Z',
entry: 't=2019-04-26T11:05:28+0200 lvl=info msg="Initializing DatasourceCacheService" logger=server', 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' }, labels: { filename: '/var/log/grafana/grafana.log', job: 'grafana' },
logLevel: 'info', logLevel: 'error',
uniqueLabels: {}, uniqueLabels: {},
}, },
]); ]);
@ -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[]) => {

Loading…
Cancel
Save