Skip to content

Commit 10c883f

Browse files
authored
feat(agents-insights): traces table (#92306)
1 parent 31d5125 commit 10c883f

File tree

2 files changed

+77
-39
lines changed

2 files changed

+77
-39
lines changed

static/app/views/insights/agentMonitoring/components/tracesTable.tsx

Lines changed: 73 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,74 @@
1-
import {Fragment, memo, useCallback} from 'react';
1+
import {Fragment, memo, useCallback, useMemo} from 'react';
22
import styled from '@emotion/styled';
33

44
import GridEditable, {
55
COL_WIDTH_UNDEFINED,
66
type GridColumnHeader,
77
type GridColumnOrder,
88
} from 'sentry/components/gridEditable';
9+
import ProjectBadge from 'sentry/components/idBadge/projectBadge';
10+
import Link from 'sentry/components/links/link';
911
import Pagination from 'sentry/components/pagination';
12+
import TimeSince from 'sentry/components/timeSince';
1013
import {t} from 'sentry/locale';
1114
import {space} from 'sentry/styles/space';
12-
import {useNavigate} from 'sentry/utils/useNavigate';
15+
import {DiscoverDatasets} from 'sentry/utils/discover/types';
16+
import getDuration from 'sentry/utils/duration/getDuration';
17+
import {useLocation} from 'sentry/utils/useLocation';
18+
import useOrganization from 'sentry/utils/useOrganization';
19+
import usePageFilters from 'sentry/utils/usePageFilters';
20+
import useProjects from 'sentry/utils/useProjects';
21+
import {useTraces} from 'sentry/views/explore/hooks/useTraces';
1322
import {HeadSortCell} from 'sentry/views/insights/agentMonitoring/components/headSortCell';
1423
import {useColumnOrder} from 'sentry/views/insights/agentMonitoring/hooks/useColumnOrder';
24+
import {getAITracesFilter} from 'sentry/views/insights/agentMonitoring/utils/query';
25+
import {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceHeader/breadcrumbs';
26+
import {getTraceDetailsUrl} from 'sentry/views/performance/traceDetails/utils';
1527

1628
interface TableData {
1729
agentFlow: string;
1830
duration: number;
1931
errors: number;
20-
timestamp: string;
21-
tokens: string;
22-
tools: number;
32+
project: string;
33+
timestamp: number;
2334
traceId: string;
24-
user: string;
2535
}
2636

2737
const EMPTY_ARRAY: never[] = [];
2838

2939
const defaultColumnOrder: Array<GridColumnOrder<string>> = [
3040
{key: 'traceId', name: t('Trace ID'), width: 120},
41+
{key: 'project', name: t('Project'), width: 180},
3142
{key: 'agentFlow', name: t('Agent Flow'), width: COL_WIDTH_UNDEFINED},
3243
{key: 'duration', name: t('Duration'), width: 100},
3344
{key: 'errors', name: t('Errors'), width: 100},
34-
{key: 'tokens', name: t('Tokens used'), width: 140},
35-
{key: 'tools', name: t('Tool calls'), width: 120},
36-
{key: 'user', name: t('User'), width: 120},
3745
{key: 'timestamp', name: t('Timestamp'), width: 120},
3846
];
3947

4048
export function TracesTable() {
41-
const navigate = useNavigate();
4249
const {columnOrder, onResizeColumn} = useColumnOrder(defaultColumnOrder);
4350

44-
// TODO: Replace with actual request
45-
const tracesRequest = {
46-
data: [],
47-
isPending: false,
48-
error: false,
49-
pageLinks: null,
50-
isPlaceholderData: false,
51-
};
51+
const tracesRequest = useTraces({
52+
dataset: DiscoverDatasets.SPANS_EAP,
53+
query: `${getAITracesFilter()}`,
54+
sort: '-timestamp',
55+
limit: 10,
56+
});
5257

53-
const tableData = tracesRequest.data;
58+
const tableData = useMemo(() => {
59+
if (!tracesRequest.data) {
60+
return [];
61+
}
62+
63+
return tracesRequest.data.data.map(span => ({
64+
traceId: span.trace,
65+
project: span.project ?? '',
66+
agentFlow: span.name ?? '',
67+
duration: span.duration,
68+
errors: span.numErrors,
69+
timestamp: span.start,
70+
}));
71+
}, [tracesRequest.data]);
5472

5573
const renderHeadCell = useCallback((column: GridColumnHeader<string>) => {
5674
return (
@@ -86,18 +104,7 @@ export function TracesTable() {
86104
/>
87105
{tracesRequest.isPlaceholderData && <LoadingOverlay />}
88106
</GridEditableContainer>
89-
<Pagination
90-
pageLinks={tracesRequest.pageLinks}
91-
onCursor={(cursor, path, currentQuery) => {
92-
navigate(
93-
{
94-
pathname: path,
95-
query: {...currentQuery, pathsCursor: cursor},
96-
},
97-
{replace: true, preventScrollReset: true}
98-
);
99-
}}
100-
/>
107+
<Pagination pageLinks={'#'} />
101108
</Fragment>
102109
);
103110
}
@@ -109,21 +116,48 @@ const BodyCell = memo(function BodyCell({
109116
column: GridColumnHeader<string>;
110117
dataRow: TableData;
111118
}) {
119+
const location = useLocation();
120+
const organization = useOrganization();
121+
const {selection} = usePageFilters();
122+
const {projects} = useProjects();
123+
124+
const project = useMemo(
125+
() => projects.find(p => p.slug === dataRow.project),
126+
[projects, dataRow.project]
127+
);
128+
129+
const traceViewTarget = getTraceDetailsUrl({
130+
eventId: dataRow.traceId,
131+
timestamp: dataRow.timestamp,
132+
source: TraceViewSources.SCREEN_LOADS_MODULE,
133+
organization,
134+
location,
135+
traceSlug: dataRow.traceId,
136+
dateSelection: {
137+
start: selection.datetime.start,
138+
end: selection.datetime.end,
139+
statsPeriod: selection.datetime.period,
140+
},
141+
});
142+
112143
switch (column.key) {
113144
case 'traceId':
114-
return dataRow.traceId;
145+
return <Link to={traceViewTarget}>{dataRow.traceId.slice(0, 8)}</Link>;
146+
case 'project':
147+
return project ? (
148+
<ProjectBadge project={project} avatarSize={16} />
149+
) : (
150+
<ProjectBadge project={{slug: dataRow.project}} avatarSize={16} />
151+
);
152+
115153
case 'agentFlow':
116154
return dataRow.agentFlow;
117155
case 'duration':
118-
return dataRow.duration;
156+
return getDuration(dataRow.duration / 1000, 2, true);
119157
case 'errors':
120158
return dataRow.errors;
121-
case 'tokens':
122-
return dataRow.tokens;
123-
case 'tools':
124-
return dataRow.tools;
125-
case 'user':
126-
return dataRow.user;
159+
case 'timestamp':
160+
return <TimeSince unitStyle="extraShort" date={new Date(dataRow.timestamp)} />;
127161
default:
128162
return null;
129163
}

static/app/views/insights/agentMonitoring/utils/query.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,7 @@ export const getLLMGenerationsFilter = () => {
4747
export const getAIToolCallsFilter = () => {
4848
return `span.description:[${AI_TOOL_CALL_OPS.join(',')}]`;
4949
};
50+
51+
export const getAITracesFilter = () => {
52+
return `has:${AI_MODEL_ID_ATTRIBUTE}`;
53+
};

0 commit comments

Comments
 (0)