Skip to content

Commit d6b5ede

Browse files
authored
Allow templated legend via attribute keys and values from query results (#57)
A few changes were made to the Time Series Value fields: - Labels are appended to the field it self. This will use default formatting and removes the need for our createFieldName function. - Name is changed to use the TIME_SERIES_VALUE_FIELD which has logic to remove the name if there is no displayNameFromDS set and use default label formatting. - Query Name allows for variable names in simple mustache like syntax {{var1}} which is similar to the Prometheus / Loki datasource - If an attribute value doesn't exist in the results set, then the value will be set to <undefined>
1 parent 7219563 commit d6b5ede

File tree

6 files changed

+301
-158
lines changed

6 files changed

+301
-158
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/preprocessors/__snapshots__/index.test.js.snap

Lines changed: 148 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`preprocesses logs successfully 1`] = `
3+
exports[`logs preprocesses successfully 1`] = `
44
{
55
"fields": [
66
{
@@ -91,3 +91,150 @@ exports[`preprocesses logs successfully 1`] = `
9191
"refId": "a",
9292
}
9393
`;
94+
95+
exports[`preprocesses Timeseries successfully should set displayNameDS with legend formatter 1`] = `
96+
{
97+
"fields": [
98+
{
99+
"config": {},
100+
"labels": undefined,
101+
"name": "Time",
102+
"type": "time",
103+
"values": [
104+
0,
105+
1,
106+
2,
107+
],
108+
},
109+
{
110+
"config": {
111+
"displayNameFromDS": "/get",
112+
"links": [
113+
{
114+
"targetBlank": true,
115+
"title": "Create a Notebook in Lightstep",
116+
"url": "https://notebooks",
117+
},
118+
],
119+
},
120+
"labels": {
121+
"operation": "/get",
122+
},
123+
"name": "Value",
124+
"type": "number",
125+
"values": [
126+
1,
127+
7,
128+
1,
129+
],
130+
},
131+
{
132+
"config": {
133+
"displayNameFromDS": "/load",
134+
"links": [
135+
{
136+
"targetBlank": true,
137+
"title": "Create a Notebook in Lightstep",
138+
"url": "https://notebooks",
139+
},
140+
],
141+
},
142+
"labels": {
143+
"operation": "/load",
144+
},
145+
"name": "Value",
146+
"type": "number",
147+
"values": [
148+
6,
149+
5,
150+
9,
151+
],
152+
},
153+
],
154+
"meta": undefined,
155+
"name": undefined,
156+
"refId": undefined,
157+
}
158+
`;
159+
160+
exports[`preprocesses Timeseries successfully should work if there are no labels 1`] = `
161+
{
162+
"fields": [
163+
{
164+
"config": {},
165+
"labels": undefined,
166+
"name": "Time",
167+
"type": "time",
168+
"values": [
169+
0,
170+
1,
171+
2,
172+
],
173+
},
174+
{
175+
"config": {
176+
"displayNameFromDS": "<undefined>",
177+
"links": [
178+
{
179+
"targetBlank": true,
180+
"title": "Create a Notebook in Lightstep",
181+
"url": "https://notebooks",
182+
},
183+
],
184+
},
185+
"labels": {},
186+
"name": "Value",
187+
"type": "number",
188+
"values": [
189+
1,
190+
7,
191+
1,
192+
],
193+
},
194+
],
195+
"meta": undefined,
196+
"name": undefined,
197+
"refId": undefined,
198+
}
199+
`;
200+
201+
exports[`preprocesses Timeseries successfully should work if there are no labels and no legend 1`] = `
202+
{
203+
"fields": [
204+
{
205+
"config": {},
206+
"labels": undefined,
207+
"name": "Time",
208+
"type": "time",
209+
"values": [
210+
0,
211+
1,
212+
2,
213+
],
214+
},
215+
{
216+
"config": {
217+
"displayNameFromDS": "",
218+
"links": [
219+
{
220+
"targetBlank": true,
221+
"title": "Create a Notebook in Lightstep",
222+
"url": "https://notebooks",
223+
},
224+
],
225+
},
226+
"labels": {},
227+
"name": "Value",
228+
"type": "number",
229+
"values": [
230+
1,
231+
7,
232+
1,
233+
],
234+
},
235+
],
236+
"meta": undefined,
237+
"name": undefined,
238+
"refId": undefined,
239+
}
240+
`;

src/preprocessors/index.test.js

Lines changed: 108 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,118 @@
11
import { preprocessData } from './index';
22

3-
test('preprocesses logs successfully', () => {
4-
const logsDataFrame = preprocessData(
5-
{
6-
data: {
7-
attributes: {
8-
logs: [
9-
[
10-
1691409972788,
11-
{
12-
event: 'one',
13-
severity: 'ErrorSeverity',
14-
tags: {
15-
'http.status_code': 200,
16-
large_batch: true,
17-
trace_id: 'd29a3fa8fb446ec65eb691a3259a541e',
3+
describe('logs', () => {
4+
it('preprocesses successfully', () => {
5+
const logsDataFrame = preprocessData(
6+
{
7+
data: {
8+
attributes: {
9+
logs: [
10+
[
11+
1691409972788,
12+
{
13+
event: 'one',
14+
severity: 'ErrorSeverity',
15+
tags: {
16+
'http.status_code': 200,
17+
large_batch: true,
18+
trace_id: 'd29a3fa8fb446ec65eb691a3259a541e',
19+
},
1820
},
19-
},
20-
],
21-
[
22-
1691409971908,
23-
{
24-
event: 'two',
25-
severity: 'InfoSeverity',
26-
tags: {
27-
customer: 'hipcore',
28-
large_batch: false,
29-
trace_id: 'd0fa420269652931236c94bc54d2233e',
21+
],
22+
[
23+
1691409971908,
24+
{
25+
event: 'two',
26+
severity: 'InfoSeverity',
27+
tags: {
28+
customer: 'hipcore',
29+
large_batch: false,
30+
trace_id: 'd0fa420269652931236c94bc54d2233e',
31+
},
32+
k8s_environment: 'production',
33+
k8s_namespace: 'default',
34+
k8s_pod: 'hipcore-pod',
3035
},
31-
k8s_environment: 'production',
32-
k8s_namespace: 'default',
33-
k8s_pod: 'hipcore-pod',
34-
},
36+
],
3537
],
38+
},
39+
},
40+
},
41+
{ refId: 'a' },
42+
''
43+
);
44+
45+
expect(logsDataFrame.toJSON()).toMatchSnapshot();
46+
});
47+
});
48+
49+
describe('preprocesses Timeseries successfully', () => {
50+
it('should set displayNameDS with legend formatter', () => {
51+
const res = {
52+
data: {
53+
attributes: {
54+
series: [
55+
{
56+
'group-labels': ['operation=/get'],
57+
points: [
58+
[0, 1],
59+
[1, 7],
60+
[2, 1],
61+
],
62+
},
63+
{
64+
'group-labels': ['operation=/load'],
65+
points: [
66+
[0, 6],
67+
[1, 5],
68+
[2, 9],
69+
],
70+
},
3671
],
3772
},
3873
},
39-
},
40-
{ refId: 'a' },
41-
''
42-
);
74+
};
75+
const query = { projectName: 'demo', format: '{{operation}}' };
76+
expect(preprocessData(res, query, 'https://notebooks')).toMatchSnapshot();
77+
});
4378

44-
expect(logsDataFrame.toJSON()).toMatchSnapshot();
79+
it('should work if there are no labels', () => {
80+
const res = {
81+
data: {
82+
attributes: {
83+
series: [
84+
{
85+
points: [
86+
[0, 1],
87+
[1, 7],
88+
[2, 1],
89+
],
90+
},
91+
],
92+
},
93+
},
94+
};
95+
const query = { projectName: 'demo', format: '{{operation}}' };
96+
expect(preprocessData(res, query, 'https://notebooks')).toMatchSnapshot();
97+
});
98+
99+
it('should work if there are no labels and no legend', () => {
100+
const res = {
101+
data: {
102+
attributes: {
103+
series: [
104+
{
105+
points: [
106+
[0, 1],
107+
[1, 7],
108+
[2, 1],
109+
],
110+
},
111+
],
112+
},
113+
},
114+
};
115+
const query = { projectName: 'demo', format: undefined };
116+
expect(preprocessData(res, query, 'https://notebooks')).toMatchSnapshot();
117+
});
45118
});

0 commit comments

Comments
 (0)