Skip to content

Commit ec32170

Browse files
authored
ref(insights): Add meta to useSpanMetricsTopNSeries response (#89657)
Right now that hook doesn't return the response meta at all, so we can't use it for the new charts, since they need meta. I had to replace the inards to fetch data using `useGenericDiscoverQuery` because the previous approach doesn't propagate `meta` at all! Luckily this hook is only used in just one place. Closes [DAIN-217: Return `meta` from `useSpanMetricsTopNSeries`](https://linear.app/getsentry/issue/DAIN-217/return-meta-from-usespanmetricstopnseries)
1 parent 4e9538c commit ec32170

File tree

4 files changed

+103
-40
lines changed

4 files changed

+103
-40
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import moment from 'moment-timezone';
2+
3+
import type {DiscoverSeries} from './useDiscoverSeries';
4+
5+
const DATE_FORMAT = 'YYYY-MM-DDTHH:mm:ssZ';
6+
7+
export function convertDiscoverTimeseriesResponse(data: any[]): DiscoverSeries['data'] {
8+
return data.map(([timestamp, [{count: value}]]) => {
9+
return {
10+
name: moment(parseInt(timestamp, 10) * 1000).format(DATE_FORMAT),
11+
value,
12+
};
13+
});
14+
}

static/app/views/insights/common/queries/useDiscoverSeries.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import moment from 'moment-timezone';
2-
31
import type {PageFilters} from 'sentry/types/core';
42
import type {Series} from 'sentry/types/echarts';
53
import {encodeSort, type EventsMetaType} from 'sentry/utils/discover/eventView';
@@ -27,7 +25,7 @@ import type {
2725
SpanMetricsProperty,
2826
} from 'sentry/views/insights/types';
2927

30-
import {DATE_FORMAT} from './useSpansQuery';
28+
import {convertDiscoverTimeseriesResponse} from './convertDiscoverTimeseriesResponse';
3129

3230
export interface MetricTimeseriesRow {
3331
[key: string]: number;
@@ -190,12 +188,3 @@ const useDiscoverSeries = <T extends string[]>(
190188

191189
return {...result, data: parsedData as Record<T[number], DiscoverSeries>};
192190
};
193-
194-
function convertDiscoverTimeseriesResponse(data: any[]): DiscoverSeries['data'] {
195-
return data.map(([timestamp, [{count: value}]]) => {
196-
return {
197-
name: moment(parseInt(timestamp, 10) * 1000).format(DATE_FORMAT),
198-
value,
199-
};
200-
});
201-
}

static/app/views/insights/common/queries/useSpanMetricsTopNSeries.spec.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,32 @@ describe('useSpanMetricsTopNSeries', () => {
6363
[1699907700, [{count: 117}]],
6464
[1699908000, [{count: 199}]],
6565
],
66+
meta: {
67+
fields: {
68+
'span.group': 'string',
69+
'count()': 'integer',
70+
},
71+
units: {
72+
'span.group': null,
73+
'count()': null,
74+
},
75+
},
6676
},
6777
'304': {
6878
data: [
6979
[1699907700, [{count: 12}]],
7080
[1699908000, [{count: 13}]],
7181
],
82+
meta: {
83+
fields: {
84+
'span.group': 'string',
85+
'count()': 'integer',
86+
},
87+
units: {
88+
'span.group': null,
89+
'count()': null,
90+
},
91+
},
7292
},
7393
},
7494
});
@@ -120,13 +140,33 @@ describe('useSpanMetricsTopNSeries', () => {
120140
{name: '2023-11-13T20:40:00+00:00', value: 199},
121141
],
122142
seriesName: '200',
143+
meta: {
144+
fields: {
145+
'span.group': 'string',
146+
'count()': 'integer',
147+
},
148+
units: {
149+
'span.group': null,
150+
'count()': null,
151+
},
152+
},
123153
},
124154
'304': {
125155
data: [
126156
{name: '2023-11-13T20:35:00+00:00', value: 12},
127157
{name: '2023-11-13T20:40:00+00:00', value: 13},
128158
],
129159
seriesName: '304',
160+
meta: {
161+
fields: {
162+
'span.group': 'string',
163+
'count()': 'integer',
164+
},
165+
units: {
166+
'span.group': null,
167+
'count()': null,
168+
},
169+
},
130170
},
131171
});
132172
});
Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1-
import type {Series} from 'sentry/types/echarts';
1+
import type {MultiSeriesEventsStats} from 'sentry/types/organization';
2+
import {encodeSort, type EventsMetaType} from 'sentry/utils/discover/eventView';
23
import type {Sort} from 'sentry/utils/discover/fields';
4+
import {
5+
type DiscoverQueryProps,
6+
useGenericDiscoverQuery,
7+
} from 'sentry/utils/discover/genericDiscoverQuery';
38
import type {MutableSearch} from 'sentry/utils/tokenizeSearch';
9+
import {useLocation} from 'sentry/utils/useLocation';
10+
import useOrganization from 'sentry/utils/useOrganization';
411
import usePageFilters from 'sentry/utils/usePageFilters';
512
import {getSeriesEventView} from 'sentry/views/insights/common/queries/getSeriesEventView';
6-
import {useWrappedDiscoverTimeseriesQuery} from 'sentry/views/insights/common/queries/useSpansQuery';
13+
import {
14+
getRetryDelay,
15+
shouldRetryHandler,
16+
} from 'sentry/views/insights/common/utils/retryHandlers';
717
import type {SpanMetricsProperty} from 'sentry/views/insights/types';
818

9-
interface SpanMetricTimeseriesRow {
10-
[key: string]: number;
11-
interval: number;
12-
}
19+
import {convertDiscoverTimeseriesResponse} from './convertDiscoverTimeseriesResponse';
20+
import type {DiscoverSeries} from './useDiscoverSeries';
1321

1422
interface UseSpanMetricsSeriesOptions<Fields> {
1523
topEvents: number;
@@ -27,6 +35,7 @@ export const useSpanMetricsTopNSeries = <Fields extends SpanMetricsProperty[]>(
2735
const {
2836
search = undefined,
2937
fields = [],
38+
enabled,
3039
yAxis = [],
3140
topEvents,
3241
sorts = [],
@@ -39,6 +48,8 @@ export const useSpanMetricsTopNSeries = <Fields extends SpanMetricsProperty[]>(
3948
);
4049
}
4150

51+
const location = useLocation();
52+
const organization = useOrganization();
4253
const pageFilters = usePageFilters();
4354

4455
const eventView = getSeriesEventView(
@@ -53,37 +64,46 @@ export const useSpanMetricsTopNSeries = <Fields extends SpanMetricsProperty[]>(
5364
eventView.sorts = sorts;
5465
}
5566

56-
const result = useWrappedDiscoverTimeseriesQuery<SpanMetricTimeseriesRow[]>({
67+
const result = useGenericDiscoverQuery<MultiSeriesEventsStats, DiscoverQueryProps>({
68+
route: 'events-stats',
5769
eventView,
58-
initialData: [],
70+
location,
71+
orgSlug: organization.slug,
72+
getRequestPayload: () => ({
73+
...eventView.getEventsAPIPayload(location),
74+
yAxis: eventView.yAxis,
75+
topEvents: eventView.topEvents,
76+
excludeOther: 0,
77+
partial: 1,
78+
orderby: eventView.sorts?.[0] ? encodeSort(eventView.sorts?.[0]) : undefined,
79+
interval: eventView.interval,
80+
}),
81+
options: {
82+
enabled: enabled && pageFilters.isReady,
83+
refetchOnWindowFocus: false,
84+
retry: shouldRetryHandler,
85+
retryDelay: getRetryDelay,
86+
},
5987
referrer,
60-
enabled: options.enabled,
6188
});
6289

63-
const seriesByKey: Record<string, Series> = {};
90+
const parsedData: Record<string, DiscoverSeries> = {};
91+
92+
const data = result.data ?? {};
6493

65-
(result?.data ?? []).forEach(datum => {
66-
// `interval` is the timestamp of the data point. Every other key is the value of a requested or found timeseries. `groups` is used to disambiguate top-N multi-axis series, which aren't supported here so the value is useless
67-
const {interval, group: _group, ...data} = datum;
94+
Object.keys(data).forEach(seriesName => {
95+
const dataSeries = data[seriesName]!;
6896

69-
Object.keys(data).forEach(key => {
70-
const value = {
71-
name: interval,
72-
value: datum[key]!,
73-
};
97+
const convertedSeries: DiscoverSeries = {
98+
seriesName,
99+
data: convertDiscoverTimeseriesResponse(dataSeries.data),
100+
meta: dataSeries?.meta as EventsMetaType,
101+
};
74102

75-
if (seriesByKey[key]) {
76-
seriesByKey[key].data.push(value);
77-
} else {
78-
seriesByKey[key] = {
79-
seriesName: key,
80-
data: [value],
81-
};
82-
}
83-
});
103+
parsedData[seriesName] = convertedSeries;
84104
});
85105

86-
return {...result, data: seriesByKey};
106+
return {...result, data: parsedData};
87107
};
88108

89109
const DEFAULT_EVENT_COUNT = 5;

0 commit comments

Comments
 (0)