Skip to content

[Backport 2.x] Restore spans limit to 3000 in trace view #2357

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,8 @@ exports[`Trace Detail Render Flyout component render trace detail 1`] = `
openSpanFlyout={[Function]}
page="app"
payloadData=""
setSpanFiltersWithStorage={[Function]}
spanFilters={Array []}
traceId="mockTrace"
>
<EuiPanel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
import React, { useEffect, useMemo, useState } from 'react';
import { HttpStart } from '../../../../../../../src/core/public';
import { TraceAnalyticsMode } from '../../../../../common/types/trace_analytics';
import { TraceFilter } from '../../../trace_analytics/components/common/constants';
import { ServiceBreakdownPanel } from '../../../trace_analytics/components/traces/service_breakdown_panel';
import { SpanDetailPanel } from '../../../trace_analytics/components/traces/span_detail_panel';
import { handlePayloadRequest } from '../../../trace_analytics/requests/traces_request_handler';
import { getListItem } from '../../helpers/utils';
import {
getOverviewFields,
getServiceBreakdownData,
} from '../../../trace_analytics/components/traces/trace_view_helpers';
import { handlePayloadRequest } from '../../../trace_analytics/requests/traces_request_handler';
import { getListItem } from '../../helpers/utils';

interface TraceDetailRenderProps {
traceId: string;
Expand All @@ -31,11 +32,22 @@
mode,
dataSourceMDSId,
}: TraceDetailRenderProps) => {
const [fields, setFields] = useState<any>({});

Check warning on line 35 in public/components/application_analytics/components/flyout_components/trace_detail_render.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
const [serviceBreakdownData, setServiceBreakdownData] = useState([]);
const [payloadData, setPayloadData] = useState('');
const [colorMap, setColorMap] = useState({});

const storedFilters = sessionStorage.getItem('TraceAnalyticsSpanFilters');
const [spanFilters, setSpanFilters] = useState<TraceFilter[]>(() =>
storedFilters ? JSON.parse(storedFilters) : []
);

const setSpanFiltersWithStorage = (newFilters: TraceFilter[]) => {
handlePayloadRequest(traceId, http, payloadData, setPayloadData, mode);
setSpanFilters(newFilters);
sessionStorage.setItem('TraceAnalyticsSpanFilters', JSON.stringify(newFilters));
};

const renderContent = useMemo(() => {
if (!traceId) return <></>;
const overviewList = [
Expand Down Expand Up @@ -79,6 +91,8 @@
dataSourceMDSId={dataSourceMDSId}
isApplicationFlyout={true}
payloadData={payloadData}
spanFilters={spanFilters}
setSpanFiltersWithStorage={setSpanFiltersWithStorage}
/>
<EuiSpacer size="xs" />
<EuiHorizontalRule margin="s" />
Expand All @@ -93,11 +107,11 @@
) : null}
</>
);
}, [traceId, fields, serviceBreakdownData, colorMap, payloadData]);

Check warning on line 110 in public/components/application_analytics/components/flyout_components/trace_detail_render.tsx

View workflow job for this annotation

GitHub Actions / Lint

React Hook useMemo has missing dependencies: 'dataSourceMDSId', 'http', 'mode', 'openSpanFlyout', 'setSpanFiltersWithStorage', and 'spanFilters'. Either include them or remove the dependency array

useEffect(() => {
handlePayloadRequest(traceId, http, payloadData, setPayloadData, mode);
}, [traceId]);

Check warning on line 114 in public/components/application_analytics/components/flyout_components/trace_detail_render.tsx

View workflow job for this annotation

GitHub Actions / Lint

React Hook useEffect has missing dependencies: 'http', 'mode', and 'payloadData'. Either include them or remove the dependency array

useEffect(() => {
if (!payloadData) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
endTime: string;
durationInNanos: number;
serviceName: string;
events: any[];

Check warning on line 35 in public/components/trace_analytics/components/common/constants.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
links: any[];

Check warning on line 36 in public/components/trace_analytics/components/common/constants.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
droppedAttributesCount: number;
droppedEventsCount: number;
droppedLinksCount: number;
Expand All @@ -57,5 +57,10 @@
_id: string;
_score: number;
_source: Span;
sort?: any[];

Check warning on line 60 in public/components/trace_analytics/components/common/constants.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
}

export interface TraceFilter {
field: string;
value: any;

Check warning on line 65 in public/components/trace_analytics/components/common/constants.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
handleServiceMapRequest,
handleServiceViewRequest,
} from '../../requests/services_request_handler';
import { TraceFilter } from '../common/constants';
import { FilterType } from '../common/filters/filters';
import {
PanelTitle,
Expand All @@ -70,7 +71,7 @@

export function ServiceView(props: ServiceViewProps) {
const { mode, page, setCurrentSelectedService } = props;
const [fields, setFields] = useState<any>({});

Check warning on line 74 in public/components/trace_analytics/components/services/service_view.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
const [serviceMap, setServiceMap] = useState<ServiceObject>({});
const [serviceMapIdSelected, setServiceMapIdSelected] = useState<
'latency' | 'error_rate' | 'throughput'
Expand Down Expand Up @@ -442,12 +443,12 @@

const [currentSpan, setCurrentSpan] = useState('');
const storedFilters = sessionStorage.getItem('TraceAnalyticsSpanFilters');
const [spanFilters, setSpanFilters] = useState<Array<{ field: string; value: any }>>(
const [spanFilters, setSpanFilters] = useState<TraceFilter[]>(
storedFilters ? JSON.parse(storedFilters) : []
);
const [DSL, setDSL] = useState<any>({});

Check warning on line 449 in public/components/trace_analytics/components/services/service_view.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type

const setSpanFiltersWithStorage = (newFilters: Array<{ field: string; value: any }>) => {
const setSpanFiltersWithStorage = (newFilters: TraceFilter[]) => {
setSpanFilters(newFilters);
sessionStorage.setItem('TraceAnalyticsSpanFilters', JSON.stringify(newFilters));
};
Expand Down Expand Up @@ -485,7 +486,7 @@
setDSL(spanDSL);
}, [props.startTime, props.endTime, props.serviceName, spanFilters]);

const addSpanFilter = (field: string, value: any) => {

Check warning on line 489 in public/components/trace_analytics/components/services/service_view.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
const newFilters = [...spanFilters];
const index = newFilters.findIndex(({ field: filterField }) => field === filterField);
if (index === -1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ exports[`Trace view component renders trace view 1`] = `
payloadData=""
setGanttChartLoading={[Function]}
setGanttData={[Function]}
setSpanFiltersWithStorage={[Function]}
spanFilters={Array []}
traceId="test"
/>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ const mockProps = {
setData: mockSetData,
addSpanFilter: mockAddSpanFilter,
removeSpanFilter: jest.fn(),
spanFilters: [],
setSpanFiltersWithStorage: jest.fn(),
};

describe('SpanDetailPanel component', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import { HttpSetup } from '../../../../../../../src/core/public';
import { TraceAnalyticsMode } from '../../../../../common/types/trace_analytics';
import { coreRefs } from '../../../../framework/core_refs';
import { Plt } from '../../../visualizations/plotly/plot';
import { hitsToSpanDetailData } from '../../requests/traces_request_handler';
import { TraceFilter } from '../common/constants';
import { PanelTitle, parseHits } from '../common/helper_functions';
import { SpanDetailFlyout } from './span_detail_flyout';
import { SpanDetailTable, SpanDetailTableHierarchy } from './span_detail_table';
import { hitsToSpanDetailData } from '../../requests/traces_request_handler';

export function SpanDetailPanel(props: {
http: HttpSetup;
Expand All @@ -33,6 +34,8 @@ export function SpanDetailPanel(props: {
mode: TraceAnalyticsMode;
dataSourceMDSId: string;
dataSourceMDSLabel: string | undefined;
spanFilters: TraceFilter[];
setSpanFiltersWithStorage: (newFilters: TraceFilter[]) => void;
page?: string;
openSpanFlyout?: any;
data?: { gantt: any[]; table: any[]; ganttMaxX: number };
Expand All @@ -44,11 +47,8 @@ export function SpanDetailPanel(props: {
}) {
const { chrome } = coreRefs;
const { mode } = props;
const storedFilters = sessionStorage.getItem('TraceAnalyticsSpanFilters');
const fromApp = props.page === 'app';
const [spanFilters, setSpanFilters] = useState<Array<{ field: string; value: any }>>(
storedFilters ? JSON.parse(storedFilters) : []
);

let data: { gantt: any[]; table: any[]; ganttMaxX: number };
let setData: (data: { gantt: any[]; table: any[]; ganttMaxX: number }) => void;
const [localData, localSetData] = useState<{ gantt: any[]; table: any[]; ganttMaxX: number }>({
Expand Down Expand Up @@ -109,70 +109,34 @@ export function SpanDetailPanel(props: {
setSelectedRange(fullRange);
}, [data.ganttMaxX]);

const setSpanFiltersWithStorage = (newFilters: Array<{ field: string; value: any }>) => {
setSpanFilters(newFilters);
sessionStorage.setItem('TraceAnalyticsSpanFilters', JSON.stringify(newFilters));
};

const addSpanFilter = (field: string, value: any) => {
const newFilters = [...spanFilters];
const newFilters = [...props.spanFilters];
const index = newFilters.findIndex(({ field: filterField }) => field === filterField);
if (index === -1) {
newFilters.push({ field, value });
} else {
newFilters.splice(index, 1, { field, value });
}
setSpanFiltersWithStorage(newFilters);
props.setSpanFiltersWithStorage(newFilters);
};

const removeSpanFilter = (field: string) => {
const newFilters = [...spanFilters];
const newFilters = [...props.spanFilters];
const index = newFilters.findIndex(({ field: filterField }) => field === filterField);
if (index !== -1) {
newFilters.splice(index, 1);
setSpanFiltersWithStorage(newFilters);
}
};

const parseAndFilterHits = (
payloadData: string,
traceMode: string,
payloadSpanFilters: any[]
) => {
try {
let hits = parseHits(props.payloadData);

if (payloadSpanFilters.length > 0) {
hits = hits.filter((hit) => {
return payloadSpanFilters.every(({ field, value }) => {
const fieldValue = field.split('.').reduce((acc, part) => acc?.[part], hit._source);
return fieldValue === value;
});
});
}

hits = hits.filter((hit) => {
if (traceMode === 'jaeger') {
return Boolean(hit._source?.process?.serviceName);
} else {
return Boolean(hit._source?.serviceName);
}
});

return hits;
} catch (error) {
console.error('Error processing payloadData in parseAndFilterHits:', error);
return [];
props.setSpanFiltersWithStorage(newFilters);
}
};

useEffect(() => {
if (!props.payloadData) {
console.warn('No payloadData provided to SpanDetailPanel');
props.setGanttChartLoading?.(false);
console.error('No payloadData provided to SpanDetailPanel');
return;
}

const hits = parseAndFilterHits(props.payloadData, mode, spanFilters);
const hits = parseHits(props.payloadData);

if (hits.length === 0) {
return;
Expand All @@ -186,11 +150,9 @@ export function SpanDetailPanel(props: {
console.error('Error in hitsToSpanDetailData:', error);
})
.finally(() => {
if (props.setGanttChartLoading) {
props.setGanttChartLoading(false);
}
props.setGanttChartLoading?.(false);
});
}, [props.payloadData, props.colorMap, mode, spanFilters]);
}, [props.payloadData, props.colorMap, mode, props.spanFilters]);

const getSpanDetailLayout = (
plotTraces: Plotly.Data[],
Expand Down Expand Up @@ -317,7 +279,7 @@ export function SpanDetailPanel(props: {
);

const renderFilters = useMemo(() => {
return spanFilters.map(({ field, value }) => (
return props.spanFilters.map(({ field, value }) => (
<EuiFlexItem grow={false} key={`span-filter-badge-${field}`}>
<EuiBadge
iconType="cross"
Expand All @@ -329,7 +291,7 @@ export function SpanDetailPanel(props: {
</EuiBadge>
</EuiFlexItem>
));
}, [spanFilters]);
}, [props.spanFilters]);

const onHover = useCallback(() => {
const dragLayer = document.getElementsByClassName('nsewdrag')?.[0];
Expand Down Expand Up @@ -387,11 +349,11 @@ export function SpanDetailPanel(props: {
dataSourceMDSId={props.dataSourceMDSId}
availableWidth={dynamicLayoutAdjustment}
payloadData={props.payloadData}
filters={spanFilters}
filters={props.spanFilters}
/>
</div>
),
[setCurrentSpan, dynamicLayoutAdjustment, props.payloadData, spanFilters]
[setCurrentSpan, dynamicLayoutAdjustment, props.payloadData, props.spanFilters]
);

const spanDetailTableHierarchy = useMemo(
Expand All @@ -411,11 +373,11 @@ export function SpanDetailPanel(props: {
dataSourceMDSId={props.dataSourceMDSId}
availableWidth={dynamicLayoutAdjustment}
payloadData={props.payloadData}
filters={spanFilters}
filters={props.spanFilters}
/>
</div>
),
[setCurrentSpan, dynamicLayoutAdjustment, props.payloadData, spanFilters]
[setCurrentSpan, dynamicLayoutAdjustment, props.payloadData, props.spanFilters]
);

const ganttChart = useMemo(
Expand Down Expand Up @@ -491,7 +453,7 @@ export function SpanDetailPanel(props: {
</div>
) : (
<>
{spanFilters.length > 0 && (
{props.spanFilters.length > 0 && (
<EuiFlexItem grow={false}>
<EuiSpacer size="s" />
<EuiFlexGroup gutterSize="s" wrap>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { HttpSetup } from '../../../../../../../src/core/public';
import { TRACE_ANALYTICS_DATE_FORMAT } from '../../../../../common/constants/trace_analytics';
import { TraceAnalyticsMode } from '../../../../../common/types/trace_analytics';
import { handleSpansRequest } from '../../requests/traces_request_handler';
import { microToMilliSec, nanoToMilliSec, parseHits } from '../common/helper_functions';
import { RenderCustomDataGrid } from '../common/shared_components/custom_datagrid';
import { handleSpansRequest } from '../../requests/traces_request_handler';

interface SpanDetailTableProps {
http: HttpSetup;
Expand All @@ -25,7 +25,7 @@ interface SpanDetailTableProps {
dataSourceMDSId: string;
availableWidth?: number;
payloadData: string;
filters: Array<{ field: string; value: any }>;
filters: TraceFilter[];
}

interface Span {
Expand Down
Loading
Loading