mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tempo: Show error if transformTrace() is passed bad data to parse to JSON (#44684)
* Surface errors if transformTrace() is passed bad data to parse
This commit is contained in:
parent
1f4fdf31df
commit
a86d7a5a90
@ -1,14 +1,45 @@
|
|||||||
import { FieldType, MutableDataFrame, PluginType, DataSourceInstanceSettings, dateTime } from '@grafana/data';
|
import {
|
||||||
|
ArrayVector,
|
||||||
|
FieldType,
|
||||||
|
MutableDataFrame,
|
||||||
|
PluginType,
|
||||||
|
DataSourceInstanceSettings,
|
||||||
|
dateTime,
|
||||||
|
} from '@grafana/data';
|
||||||
import {
|
import {
|
||||||
SearchResponse,
|
SearchResponse,
|
||||||
createTableFrame,
|
createTableFrame,
|
||||||
transformToOTLP,
|
transformToOTLP,
|
||||||
transformFromOTLP,
|
transformFromOTLP,
|
||||||
|
transformTrace,
|
||||||
createTableFrameFromSearch,
|
createTableFrameFromSearch,
|
||||||
} from './resultTransformer';
|
} from './resultTransformer';
|
||||||
import { otlpDataFrameToResponse, otlpDataFrameFromResponse, otlpResponse, tempoSearchResponse } from './testResponse';
|
import {
|
||||||
|
badOTLPResponse,
|
||||||
|
otlpDataFrameToResponse,
|
||||||
|
otlpDataFrameFromResponse,
|
||||||
|
otlpResponse,
|
||||||
|
tempoSearchResponse,
|
||||||
|
} from './testResponse';
|
||||||
import { collectorTypes } from '@opentelemetry/exporter-collector';
|
import { collectorTypes } from '@opentelemetry/exporter-collector';
|
||||||
|
|
||||||
|
const defaultSettings: DataSourceInstanceSettings = {
|
||||||
|
id: 0,
|
||||||
|
uid: '0',
|
||||||
|
type: 'tracing',
|
||||||
|
name: 'tempo',
|
||||||
|
access: 'proxy',
|
||||||
|
meta: {
|
||||||
|
id: 'tempo',
|
||||||
|
name: 'tempo',
|
||||||
|
type: PluginType.datasource,
|
||||||
|
info: {} as any,
|
||||||
|
module: '',
|
||||||
|
baseUrl: '',
|
||||||
|
},
|
||||||
|
jsonData: {},
|
||||||
|
};
|
||||||
|
|
||||||
describe('transformTraceList()', () => {
|
describe('transformTraceList()', () => {
|
||||||
const lokiDataFrame = new MutableDataFrame({
|
const lokiDataFrame = new MutableDataFrame({
|
||||||
fields: [
|
fields: [
|
||||||
@ -84,19 +115,73 @@ describe('createTableFrameFromSearch()', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultSettings: DataSourceInstanceSettings = {
|
describe('transformFromOTLP()', () => {
|
||||||
id: 0,
|
// Mock the console error so that running the test suite doesnt throw the error
|
||||||
uid: '0',
|
const origError = console.error;
|
||||||
type: 'tracing',
|
const consoleErrorMock = jest.fn();
|
||||||
name: 'tempo',
|
afterEach(() => (console.error = origError));
|
||||||
access: 'proxy',
|
beforeEach(() => (console.error = consoleErrorMock));
|
||||||
meta: {
|
|
||||||
id: 'tempo',
|
test('if passed bad data, will surface an error', () => {
|
||||||
name: 'tempo',
|
const res = transformFromOTLP(
|
||||||
type: PluginType.datasource,
|
(badOTLPResponse.batches as unknown) as collectorTypes.opentelemetryProto.trace.v1.ResourceSpans[],
|
||||||
info: {} as any,
|
false
|
||||||
module: '',
|
);
|
||||||
baseUrl: '',
|
|
||||||
|
expect(res.data[0]).toBeFalsy();
|
||||||
|
expect(res.error?.message).toBeTruthy();
|
||||||
|
// if it does have resources, no error will be thrown
|
||||||
|
expect({
|
||||||
|
...res.data[0],
|
||||||
|
resources: {
|
||||||
|
attributes: [
|
||||||
|
{ key: 'service.name', value: { stringValue: 'db' } },
|
||||||
|
{ key: 'job', value: { stringValue: 'tns/db' } },
|
||||||
|
{ key: 'opencensus.exporterversion', value: { stringValue: 'Jaeger-Go-2.22.1' } },
|
||||||
|
{ key: 'host.name', value: { stringValue: '63d16772b4a2' } },
|
||||||
|
{ key: 'ip', value: { stringValue: '0.0.0.0' } },
|
||||||
|
{ key: 'client-uuid', value: { stringValue: '39fb01637a579639' } },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
jsonData: {},
|
}).not.toBeFalsy();
|
||||||
};
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('transformTrace()', () => {
|
||||||
|
// Mock the console error so that running the test suite doesnt throw the error
|
||||||
|
const origError = console.error;
|
||||||
|
const consoleErrorMock = jest.fn();
|
||||||
|
afterEach(() => (console.error = origError));
|
||||||
|
beforeEach(() => (console.error = consoleErrorMock));
|
||||||
|
|
||||||
|
const badFrame = new MutableDataFrame({
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'serviceTags',
|
||||||
|
values: new ArrayVector([undefined]),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const goodFrame = new MutableDataFrame({
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'serviceTags',
|
||||||
|
values: new ArrayVector(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
test('if passed bad data, will surface an error', () => {
|
||||||
|
const response = transformTrace({ data: [badFrame] }, false);
|
||||||
|
expect(response.data[0]).toBeFalsy();
|
||||||
|
expect(response.error?.message).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('if passed good data, will parse successfully', () => {
|
||||||
|
const response2 = transformTrace({ data: [goodFrame] }, false);
|
||||||
|
expect(response2.data[0]).toBeTruthy();
|
||||||
|
expect(response2.data[0]).toMatchObject(goodFrame);
|
||||||
|
expect(response2.error).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -491,7 +491,12 @@ export function transformTrace(response: DataQueryResponse, nodeGraph = false):
|
|||||||
return emptyDataQueryResponse;
|
return emptyDataQueryResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
parseJsonFields(frame);
|
parseJsonFields(frame);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return { error: { message: 'Unable to parse trace response: ' + error }, data: [] };
|
||||||
|
}
|
||||||
|
|
||||||
let data = [...response.data];
|
let data = [...response.data];
|
||||||
if (nodeGraph) {
|
if (nodeGraph) {
|
||||||
|
@ -2223,3 +2223,32 @@ export const tempoSearchResponse = {
|
|||||||
inspectedBytes: '83720',
|
inspectedBytes: '83720',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const badOTLPResponse = {
|
||||||
|
batches: [
|
||||||
|
{
|
||||||
|
resource: {},
|
||||||
|
instrumentationLibrarySpans: [
|
||||||
|
{
|
||||||
|
spans: [
|
||||||
|
{
|
||||||
|
traceId: 'AAAAAAAAAABguiq7RPE+rg==',
|
||||||
|
spanId: 'cmteMBAvwNA=',
|
||||||
|
parentSpanId: 'OY8PIaPbma4=',
|
||||||
|
name: 'HTTP GET - root',
|
||||||
|
kind: 'SPAN_KIND_CLIENT',
|
||||||
|
startTimeUnixNano: 1627471657255809000,
|
||||||
|
endTimeUnixNano: 1627471657256268000,
|
||||||
|
attributes: [
|
||||||
|
{ key: 'http.status_code', value: { intValue: 200 } },
|
||||||
|
{ key: 'http.method', value: { stringValue: 'GET' } },
|
||||||
|
{ key: 'http.url', value: { stringValue: '/' } },
|
||||||
|
{ key: 'component', value: { stringValue: 'net/http' } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user