Skip to content

Commit 84fbc2f

Browse files
authored
Restore spans limit to 3000 in trace view (#2353)
* restore spans max value to 3000 in trace view Signed-off-by: Shenoy Pratik <[email protected]> * update filtering mechanism for span payloads Signed-off-by: Shenoy Pratik <[email protected]> * avoid parsing again on re-render in trace view Signed-off-by: Shenoy Pratik <[email protected]> --------- Signed-off-by: Shenoy Pratik <[email protected]>
1 parent 8ed2e69 commit 84fbc2f

File tree

12 files changed

+119
-73
lines changed

12 files changed

+119
-73
lines changed

public/components/application_analytics/__tests__/__snapshots__/flyout.test.tsx.snap

+2
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,8 @@ exports[`Trace Detail Render Flyout component render trace detail 1`] = `
751751
openSpanFlyout={[Function]}
752752
page="app"
753753
payloadData=""
754+
setSpanFiltersWithStorage={[Function]}
755+
spanFilters={Array []}
754756
traceId="mockTrace"
755757
>
756758
<EuiPanel

public/components/application_analytics/components/flyout_components/trace_detail_render.tsx

+16-2
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ import { EuiCodeBlock, EuiHorizontalRule, EuiSpacer, EuiText } from '@elastic/eu
77
import React, { useEffect, useMemo, useState } from 'react';
88
import { HttpStart } from '../../../../../../../src/core/public';
99
import { TraceAnalyticsMode } from '../../../../../common/types/trace_analytics';
10+
import { TraceFilter } from '../../../trace_analytics/components/common/constants';
1011
import { ServiceBreakdownPanel } from '../../../trace_analytics/components/traces/service_breakdown_panel';
1112
import { SpanDetailPanel } from '../../../trace_analytics/components/traces/span_detail_panel';
12-
import { handlePayloadRequest } from '../../../trace_analytics/requests/traces_request_handler';
13-
import { getListItem } from '../../helpers/utils';
1413
import {
1514
getOverviewFields,
1615
getServiceBreakdownData,
1716
} from '../../../trace_analytics/components/traces/trace_view_helpers';
17+
import { handlePayloadRequest } from '../../../trace_analytics/requests/traces_request_handler';
18+
import { getListItem } from '../../helpers/utils';
1819

1920
interface TraceDetailRenderProps {
2021
traceId: string;
@@ -36,6 +37,17 @@ export const TraceDetailRender = ({
3637
const [payloadData, setPayloadData] = useState('');
3738
const [colorMap, setColorMap] = useState({});
3839

40+
const storedFilters = sessionStorage.getItem('TraceAnalyticsSpanFilters');
41+
const [spanFilters, setSpanFilters] = useState<TraceFilter[]>(() =>
42+
storedFilters ? JSON.parse(storedFilters) : []
43+
);
44+
45+
const setSpanFiltersWithStorage = (newFilters: TraceFilter[]) => {
46+
handlePayloadRequest(traceId, http, payloadData, setPayloadData, mode);
47+
setSpanFilters(newFilters);
48+
sessionStorage.setItem('TraceAnalyticsSpanFilters', JSON.stringify(newFilters));
49+
};
50+
3951
const renderContent = useMemo(() => {
4052
if (!traceId) return <></>;
4153
const overviewList = [
@@ -79,6 +91,8 @@ export const TraceDetailRender = ({
7991
dataSourceMDSId={dataSourceMDSId}
8092
isApplicationFlyout={true}
8193
payloadData={payloadData}
94+
spanFilters={spanFilters}
95+
setSpanFiltersWithStorage={setSpanFiltersWithStorage}
8296
/>
8397
<EuiSpacer size="xs" />
8498
<EuiHorizontalRule margin="s" />

public/components/trace_analytics/components/common/constants.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,8 @@ export interface ParsedHit {
5959
_source: Span;
6060
sort?: any[];
6161
}
62+
63+
export interface TraceFilter {
64+
field: string;
65+
value: any;
66+
}

public/components/trace_analytics/components/services/service_view.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
handleServiceMapRequest,
4646
handleServiceViewRequest,
4747
} from '../../requests/services_request_handler';
48+
import { TraceFilter } from '../common/constants';
4849
import { FilterType } from '../common/filters/filters';
4950
import {
5051
PanelTitle,
@@ -442,12 +443,12 @@ export function ServiceView(props: ServiceViewProps) {
442443

443444
const [currentSpan, setCurrentSpan] = useState('');
444445
const storedFilters = sessionStorage.getItem('TraceAnalyticsSpanFilters');
445-
const [spanFilters, setSpanFilters] = useState<Array<{ field: string; value: any }>>(
446+
const [spanFilters, setSpanFilters] = useState<TraceFilter[]>(
446447
storedFilters ? JSON.parse(storedFilters) : []
447448
);
448449
const [DSL, setDSL] = useState<any>({});
449450

450-
const setSpanFiltersWithStorage = (newFilters: Array<{ field: string; value: any }>) => {
451+
const setSpanFiltersWithStorage = (newFilters: TraceFilter[]) => {
451452
setSpanFilters(newFilters);
452453
sessionStorage.setItem('TraceAnalyticsSpanFilters', JSON.stringify(newFilters));
453454
};

public/components/trace_analytics/components/traces/__tests__/__snapshots__/trace_view.test.tsx.snap

+2
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ exports[`Trace view component renders trace view 1`] = `
147147
payloadData=""
148148
setGanttChartLoading={[Function]}
149149
setGanttData={[Function]}
150+
setSpanFiltersWithStorage={[Function]}
151+
spanFilters={Array []}
150152
traceId="test"
151153
/>
152154
</EuiFlexItem>

public/components/trace_analytics/components/traces/__tests__/span_detail_panel.test.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ const mockProps = {
7979
setData: mockSetData,
8080
addSpanFilter: mockAddSpanFilter,
8181
removeSpanFilter: jest.fn(),
82+
spanFilters: [],
83+
setSpanFiltersWithStorage: jest.fn(),
8284
};
8385

8486
describe('SpanDetailPanel component', () => {

public/components/trace_analytics/components/traces/span_detail_panel.tsx

+21-59
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ import { HttpSetup } from '../../../../../../../src/core/public';
2121
import { TraceAnalyticsMode } from '../../../../../common/types/trace_analytics';
2222
import { coreRefs } from '../../../../framework/core_refs';
2323
import { Plt } from '../../../visualizations/plotly/plot';
24+
import { hitsToSpanDetailData } from '../../requests/traces_request_handler';
25+
import { TraceFilter } from '../common/constants';
2426
import { PanelTitle, parseHits } from '../common/helper_functions';
2527
import { SpanDetailFlyout } from './span_detail_flyout';
2628
import { SpanDetailTable, SpanDetailTableHierarchy } from './span_detail_table';
27-
import { hitsToSpanDetailData } from '../../requests/traces_request_handler';
2829

2930
export function SpanDetailPanel(props: {
3031
http: HttpSetup;
@@ -33,6 +34,8 @@ export function SpanDetailPanel(props: {
3334
mode: TraceAnalyticsMode;
3435
dataSourceMDSId: string;
3536
dataSourceMDSLabel: string | undefined;
37+
spanFilters: TraceFilter[];
38+
setSpanFiltersWithStorage: (newFilters: TraceFilter[]) => void;
3639
page?: string;
3740
openSpanFlyout?: any;
3841
data?: { gantt: any[]; table: any[]; ganttMaxX: number };
@@ -44,11 +47,8 @@ export function SpanDetailPanel(props: {
4447
}) {
4548
const { chrome } = coreRefs;
4649
const { mode } = props;
47-
const storedFilters = sessionStorage.getItem('TraceAnalyticsSpanFilters');
4850
const fromApp = props.page === 'app';
49-
const [spanFilters, setSpanFilters] = useState<Array<{ field: string; value: any }>>(
50-
storedFilters ? JSON.parse(storedFilters) : []
51-
);
51+
5252
let data: { gantt: any[]; table: any[]; ganttMaxX: number };
5353
let setData: (data: { gantt: any[]; table: any[]; ganttMaxX: number }) => void;
5454
const [localData, localSetData] = useState<{ gantt: any[]; table: any[]; ganttMaxX: number }>({
@@ -109,70 +109,34 @@ export function SpanDetailPanel(props: {
109109
setSelectedRange(fullRange);
110110
}, [data.ganttMaxX]);
111111

112-
const setSpanFiltersWithStorage = (newFilters: Array<{ field: string; value: any }>) => {
113-
setSpanFilters(newFilters);
114-
sessionStorage.setItem('TraceAnalyticsSpanFilters', JSON.stringify(newFilters));
115-
};
116-
117112
const addSpanFilter = (field: string, value: any) => {
118-
const newFilters = [...spanFilters];
113+
const newFilters = [...props.spanFilters];
119114
const index = newFilters.findIndex(({ field: filterField }) => field === filterField);
120115
if (index === -1) {
121116
newFilters.push({ field, value });
122117
} else {
123118
newFilters.splice(index, 1, { field, value });
124119
}
125-
setSpanFiltersWithStorage(newFilters);
120+
props.setSpanFiltersWithStorage(newFilters);
126121
};
127122

128123
const removeSpanFilter = (field: string) => {
129-
const newFilters = [...spanFilters];
124+
const newFilters = [...props.spanFilters];
130125
const index = newFilters.findIndex(({ field: filterField }) => field === filterField);
131126
if (index !== -1) {
132127
newFilters.splice(index, 1);
133-
setSpanFiltersWithStorage(newFilters);
134-
}
135-
};
136-
137-
const parseAndFilterHits = (
138-
payloadData: string,
139-
traceMode: string,
140-
payloadSpanFilters: any[]
141-
) => {
142-
try {
143-
let hits = parseHits(props.payloadData);
144-
145-
if (payloadSpanFilters.length > 0) {
146-
hits = hits.filter((hit) => {
147-
return payloadSpanFilters.every(({ field, value }) => {
148-
const fieldValue = field.split('.').reduce((acc, part) => acc?.[part], hit._source);
149-
return fieldValue === value;
150-
});
151-
});
152-
}
153-
154-
hits = hits.filter((hit) => {
155-
if (traceMode === 'jaeger') {
156-
return Boolean(hit._source?.process?.serviceName);
157-
} else {
158-
return Boolean(hit._source?.serviceName);
159-
}
160-
});
161-
162-
return hits;
163-
} catch (error) {
164-
console.error('Error processing payloadData in parseAndFilterHits:', error);
165-
return [];
128+
props.setSpanFiltersWithStorage(newFilters);
166129
}
167130
};
168131

169132
useEffect(() => {
170133
if (!props.payloadData) {
171-
console.warn('No payloadData provided to SpanDetailPanel');
134+
props.setGanttChartLoading?.(false);
135+
console.error('No payloadData provided to SpanDetailPanel');
172136
return;
173137
}
174138

175-
const hits = parseAndFilterHits(props.payloadData, mode, spanFilters);
139+
const hits = parseHits(props.payloadData);
176140

177141
if (hits.length === 0) {
178142
return;
@@ -186,11 +150,9 @@ export function SpanDetailPanel(props: {
186150
console.error('Error in hitsToSpanDetailData:', error);
187151
})
188152
.finally(() => {
189-
if (props.setGanttChartLoading) {
190-
props.setGanttChartLoading(false);
191-
}
153+
props.setGanttChartLoading?.(false);
192154
});
193-
}, [props.payloadData, props.colorMap, mode, spanFilters]);
155+
}, [props.payloadData, props.colorMap, mode, props.spanFilters]);
194156

195157
const getSpanDetailLayout = (
196158
plotTraces: Plotly.Data[],
@@ -317,7 +279,7 @@ export function SpanDetailPanel(props: {
317279
);
318280

319281
const renderFilters = useMemo(() => {
320-
return spanFilters.map(({ field, value }) => (
282+
return props.spanFilters.map(({ field, value }) => (
321283
<EuiFlexItem grow={false} key={`span-filter-badge-${field}`}>
322284
<EuiBadge
323285
iconType="cross"
@@ -329,7 +291,7 @@ export function SpanDetailPanel(props: {
329291
</EuiBadge>
330292
</EuiFlexItem>
331293
));
332-
}, [spanFilters]);
294+
}, [props.spanFilters]);
333295

334296
const onHover = useCallback(() => {
335297
const dragLayer = document.getElementsByClassName('nsewdrag')?.[0];
@@ -387,11 +349,11 @@ export function SpanDetailPanel(props: {
387349
dataSourceMDSId={props.dataSourceMDSId}
388350
availableWidth={dynamicLayoutAdjustment}
389351
payloadData={props.payloadData}
390-
filters={spanFilters}
352+
filters={props.spanFilters}
391353
/>
392354
</div>
393355
),
394-
[setCurrentSpan, dynamicLayoutAdjustment, props.payloadData, spanFilters]
356+
[setCurrentSpan, dynamicLayoutAdjustment, props.payloadData, props.spanFilters]
395357
);
396358

397359
const spanDetailTableHierarchy = useMemo(
@@ -411,11 +373,11 @@ export function SpanDetailPanel(props: {
411373
dataSourceMDSId={props.dataSourceMDSId}
412374
availableWidth={dynamicLayoutAdjustment}
413375
payloadData={props.payloadData}
414-
filters={spanFilters}
376+
filters={props.spanFilters}
415377
/>
416378
</div>
417379
),
418-
[setCurrentSpan, dynamicLayoutAdjustment, props.payloadData, spanFilters]
380+
[setCurrentSpan, dynamicLayoutAdjustment, props.payloadData, props.spanFilters]
419381
);
420382

421383
const ganttChart = useMemo(
@@ -491,7 +453,7 @@ export function SpanDetailPanel(props: {
491453
</div>
492454
) : (
493455
<>
494-
{spanFilters.length > 0 && (
456+
{props.spanFilters.length > 0 && (
495457
<EuiFlexItem grow={false}>
496458
<EuiSpacer size="s" />
497459
<EuiFlexGroup gutterSize="s" wrap>

public/components/trace_analytics/components/traces/span_detail_table.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
1111
import { HttpSetup } from '../../../../../../../src/core/public';
1212
import { TRACE_ANALYTICS_DATE_FORMAT } from '../../../../../common/constants/trace_analytics';
1313
import { TraceAnalyticsMode } from '../../../../../common/types/trace_analytics';
14+
import { handleSpansRequest } from '../../requests/traces_request_handler';
1415
import { microToMilliSec, nanoToMilliSec, parseHits } from '../common/helper_functions';
1516
import { RenderCustomDataGrid } from '../common/shared_components/custom_datagrid';
16-
import { handleSpansRequest } from '../../requests/traces_request_handler';
1717

1818
interface SpanDetailTableProps {
1919
http: HttpSetup;
@@ -25,7 +25,7 @@ interface SpanDetailTableProps {
2525
dataSourceMDSId: string;
2626
availableWidth?: number;
2727
payloadData: string;
28-
filters: Array<{ field: string; value: any }>;
28+
filters: TraceFilter[];
2929
}
3030

3131
interface Span {

public/components/trace_analytics/components/traces/trace_view.tsx

+38-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ import {
1919
EuiSpacer,
2020
EuiText,
2121
} from '@elastic/eui';
22+
import { i18n } from '@osd/i18n';
2223
import round from 'lodash/round';
2324
import React, { useEffect, useState } from 'react';
24-
import { i18n } from '@osd/i18n';
2525
import { MountPoint } from '../../../../../../../src/core/public';
2626
import { DataSourceManagementPluginSetup } from '../../../../../../../src/plugins/data_source_management/public';
2727
import { DataSourceOption } from '../../../../../../../src/plugins/data_source_management/public/components/data_source_menu/types';
@@ -31,11 +31,12 @@ import { coreRefs } from '../../../../framework/core_refs';
3131
import { TraceAnalyticsCoreDeps } from '../../home';
3232
import { handleServiceMapRequest } from '../../requests/services_request_handler';
3333
import { handlePayloadRequest } from '../../requests/traces_request_handler';
34+
import { TraceFilter } from '../common/constants';
3435
import { PanelTitle, filtersToDsl, processTimeStamp } from '../common/helper_functions';
3536
import { ServiceMap, ServiceObject } from '../common/plots/service_map';
3637
import { ServiceBreakdownPanel } from './service_breakdown_panel';
3738
import { SpanDetailPanel } from './span_detail_panel';
38-
import { getOverviewFields, getServiceBreakdownData } from './trace_view_helpers';
39+
import { getOverviewFields, getServiceBreakdownData, spanFiltersToDSL } from './trace_view_helpers';
3940

4041
const newNavigation = coreRefs.chrome?.navGroup.getNavGroupEnabled();
4142

@@ -85,6 +86,12 @@ export function TraceView(props: TraceViewProps) {
8586
const [isServicesPieChartLoading, setIsServicesPieChartLoading] = useState(false);
8687
const [isGanttChartLoading, setIsGanttChartLoading] = useState(false);
8788

89+
const storedFilters = sessionStorage.getItem('TraceAnalyticsSpanFilters');
90+
const [spanFilters, setSpanFilters] = useState<TraceFilter[]>(() =>
91+
storedFilters ? JSON.parse(storedFilters) : []
92+
);
93+
const [filteredPayload, setFilteredPayload] = useState('');
94+
8895
const renderOverview = (overviewFields: any) => {
8996
return (
9097
<EuiPanel>
@@ -224,10 +231,36 @@ export function TraceView(props: TraceViewProps) {
224231
).finally(() => setIsServicesDataLoading(false));
225232
};
226233

234+
const setSpanFiltersWithStorage = (newFilters: TraceFilter[]) => {
235+
refreshFilteredPayload(newFilters);
236+
setSpanFilters(newFilters);
237+
sessionStorage.setItem('TraceAnalyticsSpanFilters', JSON.stringify(newFilters));
238+
};
239+
240+
const refreshFilteredPayload = async (newFilters: TraceFilter[]) => {
241+
const spanDSL = spanFiltersToDSL(newFilters);
242+
setIsGanttChartLoading(true);
243+
handlePayloadRequest(
244+
props.traceId,
245+
props.http,
246+
spanDSL,
247+
setFilteredPayload,
248+
mode,
249+
props.dataSourceMDSId[0].id
250+
);
251+
};
252+
227253
useEffect(() => {
228254
if (!payloadData) return;
229255

230256
try {
257+
if (spanFilters.length > 0) {
258+
refreshFilteredPayload(spanFilters);
259+
} else {
260+
setFilteredPayload(payloadData);
261+
}
262+
263+
setFilteredPayload(payloadData);
231264
const parsedPayload = JSON.parse(payloadData);
232265
const overview = getOverviewFields(parsedPayload, mode);
233266
if (overview) {
@@ -330,9 +363,11 @@ export function TraceView(props: TraceViewProps) {
330363
setGanttData={setGanttData}
331364
dataSourceMDSId={props.dataSourceMDSId[0].id}
332365
dataSourceMDSLabel={props.dataSourceMDSId[0].label}
333-
payloadData={payloadData}
366+
payloadData={filteredPayload}
334367
isGanttChartLoading={isGanttChartLoading}
335368
setGanttChartLoading={setIsGanttChartLoading}
369+
spanFilters={spanFilters}
370+
setSpanFiltersWithStorage={setSpanFiltersWithStorage}
336371
/>
337372
</EuiFlexItem>
338373
</EuiFlexGroup>

0 commit comments

Comments
 (0)