diff --git a/public/app/plugins/datasource/loki/live_streams.test.ts b/public/app/plugins/datasource/loki/live_streams.test.ts index aab43195de7..249a3758e64 100644 --- a/public/app/plugins/datasource/loki/live_streams.test.ts +++ b/public/app/plugins/datasource/loki/live_streams.test.ts @@ -48,7 +48,7 @@ describe('Live Stream Tests', () => { expect(last).toEqual({ ts: '2019-08-28T20:50:40.118Z', tsNs: '1567025440118944705', - id: '8c50d09800ce8dda69a2ff25405c9f65', + id: '8c50d09800ce8dda69a2ff25405c9f65_A', line: 'Kittens', labels: { filename: '/var/log/sntpc.log' }, }); diff --git a/public/app/plugins/datasource/loki/live_streams.ts b/public/app/plugins/datasource/loki/live_streams.ts index 482b1602fb0..d286ddce86b 100644 --- a/public/app/plugins/datasource/loki/live_streams.ts +++ b/public/app/plugins/datasource/loki/live_streams.ts @@ -36,6 +36,7 @@ export class LiveStreams { data.addField({ name: 'labels', type: FieldType.other }); // The labels for each line data.addField({ name: 'id', type: FieldType.string }); data.meta = { ...data.meta, preferredVisualisationType: 'logs' }; + data.refId = target.refId; stream = webSocket(target.url).pipe( map((response: LokiTailResponse) => { diff --git a/public/app/plugins/datasource/loki/result_transformer.test.ts b/public/app/plugins/datasource/loki/result_transformer.test.ts index 26961d0d793..17cb50f6b50 100644 --- a/public/app/plugins/datasource/loki/result_transformer.test.ts +++ b/public/app/plugins/datasource/loki/result_transformer.test.ts @@ -109,6 +109,13 @@ describe('loki result transformer', () => { expect(data[0].fields[2].values.get(3)).toEqual('65cee200875f58ee1430d8bd2e8b74e7_2'); expect(data[1].fields[2].values.get(0)).not.toEqual('65cee200875f58ee1430d8bd2e8b74e7_3'); }); + + it('should append refId to the unique ids if refId is provided', () => { + const data = streamResult.map((stream) => ResultTransformer.lokiStreamResultToDataFrame(stream, false, 'B')); + expect(data.length).toBe(2); + expect(data[0].fields[2].values.get(0)).toEqual('2b431b8a98b80b3b2c2f4cd2444ae6cb_B'); + expect(data[1].fields[2].values.get(0)).toEqual('75d73d66cff40f9d1a1f2d5a0bf295d0_B'); + }); }); describe('lokiStreamsToDataFrames', () => { @@ -196,14 +203,15 @@ describe('loki result transformer', () => { data.addField({ name: 'line', type: FieldType.string }).labels = { job: 'grafana' }; data.addField({ name: 'labels', type: FieldType.other }); data.addField({ name: 'id', type: FieldType.string }); + data.refId = 'C'; ResultTransformer.appendResponseToBufferedData(tailResponse, data); - expect(data.get(0).id).toEqual('870e4d105741bdfc2c67904ee480d4f3'); - expect(data.get(1).id).toEqual('870e4d105741bdfc2c67904ee480d4f3_1'); - expect(data.get(2).id).toEqual('707e4ec2b842f389dbb993438505856d'); - expect(data.get(3).id).toEqual('78f044015a58fad3e257a855b167d85e'); - expect(data.get(4).id).toEqual('870e4d105741bdfc2c67904ee480d4f3_2'); - expect(data.get(5).id).toEqual('707e4ec2b842f389dbb993438505856d_1'); + expect(data.get(0).id).toEqual('870e4d105741bdfc2c67904ee480d4f3_C'); + expect(data.get(1).id).toEqual('870e4d105741bdfc2c67904ee480d4f3_1_C'); + expect(data.get(2).id).toEqual('707e4ec2b842f389dbb993438505856d_C'); + expect(data.get(3).id).toEqual('78f044015a58fad3e257a855b167d85e_C'); + expect(data.get(4).id).toEqual('870e4d105741bdfc2c67904ee480d4f3_2_C'); + expect(data.get(5).id).toEqual('707e4ec2b842f389dbb993438505856d_1_C'); }); }); diff --git a/public/app/plugins/datasource/loki/result_transformer.ts b/public/app/plugins/datasource/loki/result_transformer.ts index c60e0ffce30..04d5e901091 100644 --- a/public/app/plugins/datasource/loki/result_transformer.ts +++ b/public/app/plugins/datasource/loki/result_transformer.ts @@ -61,7 +61,7 @@ export function lokiStreamResultToDataFrame(stream: LokiStreamResult, reverse?: times.add(new Date(parseInt(ts.substr(0, ts.length - 6), 10)).toISOString()); timesNs.add(ts); lines.add(line); - uids.add(createUid(ts, labelsString, line, usedUids)); + uids.add(createUid(ts, labelsString, line, usedUids, refId)); } return constructDataFrame(times, timesNs, lines, uids, labels, reverse, refId); @@ -148,12 +148,12 @@ export function appendResponseToBufferedData(response: LokiTailResponse, data: M tsNsField.values.add(ts); lineField.values.add(line); labelsField.values.add(unique); - idField.values.add(createUid(ts, allLabelsString, line, usedUids)); + idField.values.add(createUid(ts, allLabelsString, line, usedUids, data.refId)); } } } -function createUid(ts: string, labelsString: string, line: string, usedUids: any): string { +function createUid(ts: string, labelsString: string, line: string, usedUids: any, refId?: string): string { // Generate id as hashed nanosecond timestamp, labels and line (this does not have to be unique) let id = md5(`${ts}_${labelsString}_${line}`); @@ -170,6 +170,9 @@ function createUid(ts: string, labelsString: string, line: string, usedUids: any usedUids[id] = 0; } // Return unique id + if (refId) { + return `${id}_${refId}`; + } return id; } @@ -354,7 +357,7 @@ export function lokiStreamsToDataFrames( }; const series: DataFrame[] = data.map((stream) => { - const dataFrame = lokiStreamResultToDataFrame(stream, reverse); + const dataFrame = lokiStreamResultToDataFrame(stream, reverse, target.refId); enhanceDataFrame(dataFrame, config); if (meta.custom && dataFrame.fields.some((f) => f.labels && Object.keys(f.labels).some((l) => l === '__error__'))) {