Skip to content

Commit aa1dfa9

Browse files
authored
feat(tracemetrics): Enable aggregate panel to show equation result (#112966)
Right now the aggregate panel is gated on stuff like `traceMetric.name` being selected. This only applies to visualize functions and not equations, so this PR updates a bunch of the call sites to branch on the function-specific logic and add in equation logic (e.g. checking if the expression text is not empty)
1 parent 40011ed commit aa1dfa9

File tree

3 files changed

+64
-25
lines changed

3 files changed

+64
-25
lines changed

static/app/views/explore/metrics/hooks/useMetricAggregatesTable.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@ import {
1111
type RPCQueryExtras,
1212
} from 'sentry/views/explore/hooks/useProgressiveQuery';
1313
import type {TraceMetric} from 'sentry/views/explore/metrics/metricQuery';
14-
import {useMetricVisualizes} from 'sentry/views/explore/metrics/metricsQueryParams';
14+
import {
15+
useMetricVisualize,
16+
useMetricVisualizes,
17+
} from 'sentry/views/explore/metrics/metricsQueryParams';
1518
import {TraceMetricKnownFieldKey} from 'sentry/views/explore/metrics/types';
1619
import {makeMetricsAggregate} from 'sentry/views/explore/metrics/utils';
1720
import {
1821
useQueryParamsAggregateSortBys,
1922
useQueryParamsGroupBys,
2023
useQueryParamsQuery,
2124
} from 'sentry/views/explore/queryParams/context';
25+
import {isVisualizeEquation} from 'sentry/views/explore/queryParams/visualize';
2226
import {useSpansQuery} from 'sentry/views/insights/common/queries/useSpansQuery';
2327

2428
interface UseMetricAggregatesTableOptions {
@@ -48,8 +52,12 @@ export function useMetricAggregatesTable({
4852
traceMetric,
4953
queryExtras,
5054
}: UseMetricAggregatesTableOptions) {
55+
const visualize = useMetricVisualize();
5156
const canTriggerHighAccuracy = useCallback(
5257
(result: ReturnType<typeof useMetricAggregatesTableImp>['result']) => {
58+
if (isVisualizeEquation(visualize)) {
59+
return false;
60+
}
5361
const countAggregate = makeCountAggregate(traceMetric);
5462
const canGoToHigherAccuracyTier = result.meta?.dataScanned === 'partial';
5563
const hasData =
@@ -58,7 +66,7 @@ export function useMetricAggregatesTable({
5866
(result.data.length === 1 && Boolean(result.data[0][countAggregate])));
5967
return !hasData && canGoToHigherAccuracyTier;
6068
},
61-
[traceMetric]
69+
[traceMetric, visualize]
6270
);
6371
return useProgressiveQuery<typeof useMetricAggregatesTableImp>({
6472
queryHookImplementation: useMetricAggregatesTableImp,
@@ -87,6 +95,8 @@ function useMetricAggregatesTableImp({
8795
const query = useQueryParamsQuery();
8896
const sortBys = useQueryParamsAggregateSortBys();
8997

98+
const isEquation = visualizes.every(isVisualizeEquation);
99+
90100
const fields = useMemo(() => {
91101
const allFields: string[] = [];
92102

@@ -111,18 +121,25 @@ function useMetricAggregatesTableImp({
111121
const discoverQuery: NewQuery = {
112122
id: undefined,
113123
name: 'Explore - Metric Aggregates',
114-
fields: [...fields, makeCountAggregate(traceMetric)],
124+
fields: [...fields, ...(isEquation ? [] : [makeCountAggregate(traceMetric)])],
115125
orderby: sortBys.map(formatSort),
116126
query,
117127
version: 2,
118128
dataset: DiscoverDatasets.TRACEMETRICS,
119129
};
120130

121131
return EventView.fromNewQueryWithPageFilters(discoverQuery, selection);
122-
}, [fields, query, selection, sortBys, traceMetric]);
132+
}, [fields, query, selection, sortBys, traceMetric, isEquation]);
123133

124134
const result = useSpansQuery({
125-
enabled: enabled && Boolean(traceMetric.name) && fields.length > 0,
135+
enabled:
136+
enabled &&
137+
fields.length > 0 &&
138+
(isEquation
139+
? visualizes.every(
140+
visualize => isVisualizeEquation(visualize) && visualize.expression.text
141+
)
142+
: Boolean(traceMetric.name)),
126143
eventView,
127144
initialData: [],
128145
limit,

static/app/views/explore/metrics/metricInfoTabs/aggregatesTab.tsx

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {COL_WIDTH_UNDEFINED} from 'sentry/components/tables/gridEditable';
1010
import {SimpleTable} from 'sentry/components/tables/simpleTable';
1111
import {IconWarning} from 'sentry/icons/iconWarning';
1212
import {t} from 'sentry/locale';
13-
import {parseFunction} from 'sentry/utils/discover/fields';
13+
import {isEquation, parseFunction} from 'sentry/utils/discover/fields';
1414
import {prettifyTagKey} from 'sentry/utils/fields';
1515
import {useOrganization} from 'sentry/utils/useOrganization';
1616
import type {TableColumn} from 'sentry/views/discover/table/types';
@@ -29,6 +29,7 @@ import {
2929
} from 'sentry/views/explore/metrics/metricInfoTabs/metricInfoTabStyles';
3030
import type {TraceMetric} from 'sentry/views/explore/metrics/metricQuery';
3131
import {canUseMetricsUIRefresh} from 'sentry/views/explore/metrics/metricsFlags';
32+
import {useMetricVisualize} from 'sentry/views/explore/metrics/metricsQueryParams';
3233
import {TraceMetricKnownFieldKey} from 'sentry/views/explore/metrics/types';
3334
import {
3435
createTraceMetricFilter,
@@ -39,6 +40,10 @@ import {
3940
useQueryParamsGroupBys,
4041
useSetQueryParamsAggregateSortBys,
4142
} from 'sentry/views/explore/queryParams/context';
43+
import {
44+
isVisualizeEquation,
45+
isVisualizeFunction,
46+
} from 'sentry/views/explore/queryParams/visualize';
4247
import {FieldRenderer} from 'sentry/views/explore/tables/fieldRenderer';
4348
import {TraceItemDataset} from 'sentry/views/explore/types';
4449
import {GenericWidgetEmptyStateWarning} from 'sentry/views/performance/landing/widgets/components/selectableList';
@@ -67,9 +72,12 @@ export function AggregatesTab({traceMetric, isMetricOptionsEmpty}: AggregatesTab
6772
const hasMetricsUIRefresh = canUseMetricsUIRefresh(organization);
6873
const topEvents = useTopEvents();
6974
const tableRef = useRef<HTMLDivElement>(null);
75+
const visualize = useMetricVisualize();
7076

7177
const {result, eventView, fields} = useMetricAggregatesTable({
72-
enabled: Boolean(traceMetric.name) && !isMetricOptionsEmpty,
78+
enabled: isVisualizeFunction(visualize)
79+
? Boolean(traceMetric.name) && !isMetricOptionsEmpty
80+
: isVisualizeEquation(visualize) && Boolean(visualize.expression.text),
7381
limit: RESULT_LIMIT,
7482
traceMetric,
7583
});
@@ -107,21 +115,22 @@ export function AggregatesTab({traceMetric, isMetricOptionsEmpty}: AggregatesTab
107115

108116
// When no group bys are selected, prepend the metric name as a virtual group-by column
109117
const displayFields = useMemo(() => {
110-
if (groupBys.length === 0) {
118+
if (groupBys.length === 0 && isVisualizeFunction(visualize)) {
111119
return [TraceMetricKnownFieldKey.METRIC_NAME, ...fields];
112120
}
113121
return fields;
114-
}, [groupBys.length, fields]);
122+
}, [groupBys.length, fields, visualize]);
115123

116124
const displayColumns = useMemo(() => {
117-
if (groupBys.length === 0) {
125+
if (groupBys.length === 0 && isVisualizeFunction(visualize)) {
118126
return [METRIC_NAME_COLUMN, ...columns];
119127
}
120128
return columns;
121-
}, [groupBys.length, columns]);
129+
}, [groupBys.length, columns, visualize]);
122130

123131
// Include the virtual metric name column in the group-by count so grid/divider logic works
124-
const groupByFieldCount = groupBys.length === 0 ? 1 : groupBys.length;
132+
const groupByFieldCount =
133+
groupBys.length === 0 && isVisualizeFunction(visualize) ? 1 : groupBys.length;
125134
const aggregateFieldCount = displayFields.length - groupByFieldCount;
126135

127136
const tableStyle = useMemo(() => {
@@ -233,12 +242,16 @@ export function AggregatesTab({traceMetric, isMetricOptionsEmpty}: AggregatesTab
233242
label = `${func.name}(…)`;
234243
} else if (tag) {
235244
label = tag.name;
245+
} else if (isEquation(field)) {
246+
// TODO: This should say the reference format of equations
247+
label = t('Result');
236248
} else {
237249
label = prettifyTagKey(field);
238250
}
239251

240252
const direction = sorts.find(s => s.field === field)?.kind;
241-
const canSort = displayColumns[i]?.isSortable !== false;
253+
const canSort =
254+
displayColumns.find(column => column.key === field)?.isSortable !== false;
242255

243256
function updateSort() {
244257
const kind = direction === 'desc' ? 'asc' : 'desc';
@@ -250,7 +263,9 @@ export function AggregatesTab({traceMetric, isMetricOptionsEmpty}: AggregatesTab
250263
key={i}
251264
divider={shouldShowDivider(i)}
252265
data-sticky-column={isLastColumn(i) ? 'true' : 'false'}
253-
isAggregate={Boolean(func)}
266+
isAggregate={
267+
Boolean(func) || (isVisualizeEquation(visualize) && isEquation(field))
268+
}
254269
isSticky={isLastColumn(i)}
255270
sort={direction}
256271
handleSortClick={canSort ? updateSort : undefined}
@@ -289,7 +304,7 @@ export function AggregatesTab({traceMetric, isMetricOptionsEmpty}: AggregatesTab
289304
offset={j === 0 ? firstColumnOffset : undefined}
290305
>
291306
<FieldRenderer
292-
column={displayColumns[j]}
307+
column={displayColumns.find(column => column.key === field)}
293308
data={displayRow}
294309
unit={getMetricsUnit(meta, field)}
295310
meta={meta}

static/app/views/explore/metrics/metricPanel/index.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ import {
3232
useQueryParamsMode,
3333
useQueryParamsSortBys,
3434
} from 'sentry/views/explore/queryParams/context';
35-
import {isVisualizeEquation} from 'sentry/views/explore/queryParams/visualize';
35+
import {
36+
isVisualizeEquation,
37+
isVisualizeFunction,
38+
} from 'sentry/views/explore/queryParams/visualize';
3639

3740
const RESULT_LIMIT = 50;
3841
const TWO_MINUTE_DELAY = 120;
@@ -76,27 +79,31 @@ export function MetricPanel({
7679
const hasMetricsUIRefresh = canUseMetricsUIRefresh(organization);
7780
const fields = getTraceSamplesTableFields(TraceSamplesTableColumns);
7881

82+
const mode = useQueryParamsMode();
83+
const sortBys = useQueryParamsSortBys();
84+
const aggregateSortBys = useQueryParamsAggregateSortBys();
85+
const [interval] = useChartInterval();
86+
const topEvents = useTopEvents();
87+
const visualize = useMetricVisualize();
88+
89+
const areQueriesEnabled = isVisualizeFunction(visualize)
90+
? Boolean(traceMetric.name) && !isMetricOptionsEmpty
91+
: isVisualizeEquation(visualize) && Boolean(visualize.expression.text);
92+
7993
const metricSamplesTableResult = useMetricSamplesTable({
80-
disabled: !traceMetric?.name || isMetricOptionsEmpty,
94+
disabled: !areQueriesEnabled,
8195
limit: RESULT_LIMIT,
8296
traceMetric,
8397
fields,
8498
ingestionDelaySeconds: TWO_MINUTE_DELAY,
8599
});
86100

87101
const metricAggregatesTableResult = useMetricAggregatesTable({
88-
enabled: Boolean(traceMetric.name) && !isMetricOptionsEmpty,
102+
enabled: areQueriesEnabled,
89103
limit: RESULT_LIMIT,
90104
traceMetric,
91105
});
92106

93-
const mode = useQueryParamsMode();
94-
const sortBys = useQueryParamsSortBys();
95-
const aggregateSortBys = useQueryParamsAggregateSortBys();
96-
const [interval] = useChartInterval();
97-
const topEvents = useTopEvents();
98-
const visualize = useMetricVisualize();
99-
100107
const {result: timeseriesResult} = useMetricTimeseries({
101108
traceMetric,
102109
enabled:

0 commit comments

Comments
 (0)