loki: backend-mode: add nanosecond-timestamps (#45963)

This commit is contained in:
Gábor Farkas 2022-03-04 09:42:18 +01:00 committed by GitHub
parent efe9eed758
commit c4404982dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 157 additions and 27 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt"
"sort"
"strings"
"time"
"github.com/grafana/grafana-plugin-sdk-go/data"
)
@ -51,9 +52,31 @@ func adjustFrame(frame *data.Frame, query *lokiQuery) *data.Frame {
field.Config.DisplayNameFromDS = name
}
// for streams-dataframes, we need to send to the browser the nanosecond-precision timestamp too.
// usually timestamps become javascript-date-objects in the browser automatically, which only
// have millisecond-precision.
// so we send a separate timestamp-as-string field too.
if !isMetricFrame {
stringTimeField := makeStringTimeField(timeFields[0])
frame.Fields = append(frame.Fields, stringTimeField)
}
return frame
}
func makeStringTimeField(field *data.Field) *data.Field {
length := field.Len()
stringTimestamps := make([]string, length)
for i := 0; i < length; i++ {
if v, ok := field.ConcreteAt(i); ok {
nsNumber := v.(time.Time).UnixNano()
stringTimestamps[i] = fmt.Sprintf("%d", nsNumber)
}
}
return data.NewField("tsNs", field.Labels.Copy(), stringTimestamps)
}
func formatNamePrometheusStyle(labels map[string]string) string {
var parts []string

View File

@ -4,14 +4,14 @@ Frame[0] {
"executedQueryString": "Expr: query1"
}
Name: {level="error", location="moon"}
Dimensions: 2 Fields by 1 Rows
+----------------------------------------+------------------------------------+
| Name: time | Name: value |
| Labels: | Labels: level=error, location=moon |
| Type: []time.Time | Type: []string |
+----------------------------------------+------------------------------------+
| 2022-02-16 16:50:44.81075712 +0000 UTC | log line error 1 |
+----------------------------------------+------------------------------------+
Dimensions: 3 Fields by 1 Rows
+----------------------------------------+------------------------------------+---------------------+
| Name: time | Name: value | Name: tsNs |
| Labels: | Labels: level=error, location=moon | Labels: |
| Type: []time.Time | Type: []string | Type: []string |
+----------------------------------------+------------------------------------+---------------------+
| 2022-02-16 16:50:44.81075712 +0000 UTC | log line error 1 | 1645030244810757120 |
+----------------------------------------+------------------------------------+---------------------+
@ -19,19 +19,19 @@ Frame[1] {
"executedQueryString": "Expr: query1"
}
Name: {level="info", location="moon"}
Dimensions: 2 Fields by 4 Rows
+-----------------------------------------+-----------------------------------+
| Name: time | Name: value |
| Labels: | Labels: level=info, location=moon |
| Type: []time.Time | Type: []string |
+-----------------------------------------+-----------------------------------+
| 2022-02-16 16:50:47.02773504 +0000 UTC | log line info 1 |
| 2022-02-16 16:50:46.277587968 +0000 UTC | log line info 2 |
| 2022-02-16 16:50:45.539423744 +0000 UTC | log line info 3 |
| 2022-02-16 16:50:44.091700992 +0000 UTC | log line info 4 |
+-----------------------------------------+-----------------------------------+
Dimensions: 3 Fields by 4 Rows
+-----------------------------------------+-----------------------------------+---------------------+
| Name: time | Name: value | Name: tsNs |
| Labels: | Labels: level=info, location=moon | Labels: |
| Type: []time.Time | Type: []string | Type: []string |
+-----------------------------------------+-----------------------------------+---------------------+
| 2022-02-16 16:50:47.02773504 +0000 UTC | log line info 1 | 1645030247027735040 |
| 2022-02-16 16:50:46.277587968 +0000 UTC | log line info 2 | 1645030246277587968 |
| 2022-02-16 16:50:45.539423744 +0000 UTC | log line info 3 | 1645030245539423744 |
| 2022-02-16 16:50:44.091700992 +0000 UTC | log line info 4 | 1645030244091700992 |
+-----------------------------------------+-----------------------------------+---------------------+
====== TEST DATA RESPONSE (arrow base64) ======
FRAME=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
FRAME=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
FRAME=QVJST1cxAAD/////8AIAABAAAAAAAAoADgAMAAsABAAKAAAAFAAAAAAAAAEEAAoADAAAAAgABAAKAAAACAAAALgAAAADAAAAbAAAACgAAAAEAAAAoP3//wgAAAAMAAAAAAAAAAAAAAAFAAAAcmVmSWQAAADA/f//CAAAACwAAAAgAAAAe2xldmVsPSJlcnJvciIsIGxvY2F0aW9uPSJtb29uIn0AAAAABAAAAG5hbWUAAAAAAP7//wgAAAAwAAAAJgAAAHsiZXhlY3V0ZWRRdWVyeVN0cmluZyI6IkV4cHI6IHF1ZXJ5MSJ9AAAEAAAAbWV0YQAAAAADAAAAmAEAAIQAAAAEAAAAhv7//xQAAABgAAAAYAAAAAAAAAVcAAAAAgAAACwAAAAEAAAAeP7//wgAAAAQAAAABAAAAHRzTnMAAAAABAAAAG5hbWUAAAAAnP7//wgAAAAMAAAAAgAAAHt9AAAGAAAAbGFiZWxzAAAAAAAABP///wQAAAB0c05zAAAAAAL///8UAAAA4AAAAOQAAAAAAAAF4AAAAAMAAABwAAAALAAAAAQAAAD4/v//CAAAABAAAAAFAAAAdmFsdWUAAAAEAAAAbmFtZQAAAAAc////CAAAACwAAAAjAAAAeyJsZXZlbCI6ImVycm9yIiwibG9jYXRpb24iOiJtb29uIn0ABgAAAGxhYmVscwAAXP///wgAAABIAAAAPAAAAHsiZGlzcGxheU5hbWVGcm9tRFMiOiJ7bGV2ZWw9XCJlcnJvclwiLCBsb2NhdGlvbj1cIm1vb25cIn0ifQAAAAAGAAAAY29uZmlnAAAAAAAABAAEAAQAAAAFAAAAdmFsdWUAEgAYABQAAAATAAwAAAAIAAQAEgAAABQAAABEAAAATAAAAAAAAApMAAAAAQAAAAwAAAAIAAwACAAEAAgAAAAIAAAAEAAAAAQAAAB0aW1lAAAAAAQAAABuYW1lAAAAAAAAAAAAAAYACAAGAAYAAAAAAAMABAAAAHRpbWUAAAAA/////wgBAAAUAAAAAAAAAAwAFgAUABMADAAEAAwAAABAAAAAAAAAABQAAAAAAAADBAAKABgADAAIAAQACgAAABQAAACYAAAAAQAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAACAAAAAAAAAAoAAAAAAAAABMAAAAAAAAAAAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAFLi6SlLUFgAAAAAQAAAAbG9nIGxpbmUgZXJyb3IgMQAAAAATAAAAMTY0NTAzMDI0NDgxMDc1NzEyMAAAAAAAEAAAAAwAFAASAAwACAAEAAwAAAAQAAAALAAAADwAAAAAAAQAAQAAAAADAAAAAAAAEAEAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAMAAAACAAEAAoAAAAIAAAAuAAAAAMAAABsAAAAKAAAAAQAAACg/f//CAAAAAwAAAAAAAAAAAAAAAUAAAByZWZJZAAAAMD9//8IAAAALAAAACAAAAB7bGV2ZWw9ImVycm9yIiwgbG9jYXRpb249Im1vb24ifQAAAAAEAAAAbmFtZQAAAAAA/v//CAAAADAAAAAmAAAAeyJleGVjdXRlZFF1ZXJ5U3RyaW5nIjoiRXhwcjogcXVlcnkxIn0AAAQAAABtZXRhAAAAAAMAAACYAQAAhAAAAAQAAACG/v//FAAAAGAAAABgAAAAAAAABVwAAAACAAAALAAAAAQAAAB4/v//CAAAABAAAAAEAAAAdHNOcwAAAAAEAAAAbmFtZQAAAACc/v//CAAAAAwAAAACAAAAe30AAAYAAABsYWJlbHMAAAAAAAAE////BAAAAHRzTnMAAAAAAv///xQAAADgAAAA5AAAAAAAAAXgAAAAAwAAAHAAAAAsAAAABAAAAPj+//8IAAAAEAAAAAUAAAB2YWx1ZQAAAAQAAABuYW1lAAAAABz///8IAAAALAAAACMAAAB7ImxldmVsIjoiZXJyb3IiLCJsb2NhdGlvbiI6Im1vb24ifQAGAAAAbGFiZWxzAABc////CAAAAEgAAAA8AAAAeyJkaXNwbGF5TmFtZUZyb21EUyI6IntsZXZlbD1cImVycm9yXCIsIGxvY2F0aW9uPVwibW9vblwifSJ9AAAAAAYAAABjb25maWcAAAAAAAAEAAQABAAAAAUAAAB2YWx1ZQASABgAFAAAABMADAAAAAgABAASAAAAFAAAAEQAAABMAAAAAAAACkwAAAABAAAADAAAAAgADAAIAAQACAAAAAgAAAAQAAAABAAAAHRpbWUAAAAABAAAAG5hbWUAAAAAAAAAAAAABgAIAAYABgAAAAAAAwAEAAAAdGltZQAAAAAgAwAAQVJST1cx
FRAME=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

View File

@ -0,0 +1,87 @@
import { ArrayVector, CoreApp, DataFrame, DataQueryRequest, DataQueryResponse, FieldType, toUtc } from '@grafana/data';
import { cloneDeep } from 'lodash';
import { transformBackendResult } from './backendResultTransformer';
import { LokiQuery } from './types';
const frame: DataFrame = {
name: 'frame1',
refId: 'A',
meta: {
executedQueryString: 'something1',
},
fields: [
{
name: 'Time',
type: FieldType.time,
config: {},
values: new ArrayVector([1645029699311, 1645029699312, 1645029699313]),
},
{
name: 'Value',
type: FieldType.string,
labels: {
level: 'error',
location: 'moon',
protocol: 'http',
},
config: {
displayNameFromDS: '{level="error", location="moon", protocol="http"}',
},
values: new ArrayVector(['line1', 'line2', 'line3']),
},
{
name: 'tsNs',
type: FieldType.string,
config: {},
values: new ArrayVector(['1645029699311000500', '1645029699312000500', '1645029699313000500']),
},
],
length: 1,
};
function makeRequest(expr: string): DataQueryRequest<LokiQuery> {
return {
requestId: 'test1',
interval: '1s',
intervalMs: 1000,
range: {
from: toUtc('2022-02-22T13:14:15'),
to: toUtc('2022-02-22T13:15:15'),
raw: {
from: toUtc('2022-02-22T13:14:15'),
to: toUtc('2022-02-22T13:15:15'),
},
},
scopedVars: {},
targets: [
{
refId: 'A',
expr,
},
],
timezone: 'UTC',
app: CoreApp.Explore,
startTime: 0,
};
}
describe('loki backendResultTransformer', () => {
it('processes a logs-dataframe correctly', () => {
const response: DataQueryResponse = { data: [cloneDeep(frame)] };
const request = makeRequest('{level="info"} |= "thing1"');
const expectedFrame = cloneDeep(frame);
expectedFrame.meta = {
executedQueryString: 'something1',
preferredVisualisationType: 'logs',
searchWords: ['thing1'],
};
expectedFrame.fields[2].type = FieldType.time;
const expected: DataQueryResponse = { data: [expectedFrame] };
const result = transformBackendResult(response, request);
expect(result).toEqual(expected);
});
});

View File

@ -18,14 +18,34 @@ function setFrameMeta(frame: DataFrame, meta: QueryResultMeta): DataFrame {
};
}
function processStreamFrame(frame: DataFrame, query: LokiQuery | undefined): DataFrame {
const meta: QueryResultMeta = {
preferredVisualisationType: 'logs',
searchWords: query !== undefined ? getHighlighterExpressionsFromQuery(formatQuery(query.expr)) : undefined,
};
const newFrame = setFrameMeta(frame, meta);
const newFields = frame.fields.map((field) => {
// the nanosecond-timestamp field must have a type-time
if (field.name === 'tsNs') {
return {
...field,
type: FieldType.time,
};
} else {
return field;
}
});
return {
...newFrame,
fields: newFields,
};
}
function processStreamsFrames(frames: DataFrame[], queryMap: Map<string, LokiQuery>): DataFrame[] {
return frames.map((frame) => {
const query = frame.refId !== undefined ? queryMap.get(frame.refId) : undefined;
const meta: QueryResultMeta = {
preferredVisualisationType: 'logs',
searchWords: query !== undefined ? getHighlighterExpressionsFromQuery(formatQuery(query.expr)) : undefined,
};
return setFrameMeta(frame, meta);
return processStreamFrame(frame, query);
});
}

View File

@ -133,7 +133,7 @@ const outputMulti = [
},
];
describe('loki backendResultTransformer', () => {
describe('loki makeTableFrames', () => {
it('converts a single instant metric dataframe to table dataframe', () => {
const result = makeTableFrames([frame1]);
expect(result).toEqual(outputSingle);