From dd5cb03d1e23d6014ea3657d9bf4f43a7807e711 Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Wed, 19 Nov 2025 15:32:55 -0800 Subject: [PATCH 1/2] fix(aci): Hide failure rate and hide string options for p50 - hides failure rate and failure count options from metric monitors - hides string tags for aggregate functions like p50, p90 --- .../components/forms/metric/visualize.tsx | 52 +++++++++++++++---- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/static/app/views/detectors/components/forms/metric/visualize.tsx b/static/app/views/detectors/components/forms/metric/visualize.tsx index 16bb8bd8925774..91de7b1f8c40a2 100644 --- a/static/app/views/detectors/components/forms/metric/visualize.tsx +++ b/static/app/views/detectors/components/forms/metric/visualize.tsx @@ -15,6 +15,8 @@ import {parseFunction} from 'sentry/utils/discover/fields'; import { AggregationKey, ALLOWED_EXPLORE_VISUALIZE_AGGREGATES, + FieldValueType, + getFieldDefinition, prettifyTagKey, } from 'sentry/utils/fields'; import {unreachable} from 'sentry/utils/unreachable'; @@ -91,13 +93,24 @@ function renderTag(kind: FieldValueKind): React.ReactNode { return {text}; } +const SPAN_LOGS_NOT_ALLOWED_AGGREGATES = [ + AggregationKey.FAILURE_RATE, + AggregationKey.FAILURE_COUNT, +]; + +function getEAPAllowedAggregates(): Array<[string, string]> { + return ALLOWED_EXPLORE_VISUALIZE_AGGREGATES.filter( + aggregate => !SPAN_LOGS_NOT_ALLOWED_AGGREGATES.includes(aggregate) + ).map(aggregate => [aggregate, aggregate]); +} + function getAggregateOptions( dataset: DetectorDataset, tableFieldOptions: Record> ): Array<[string, string]> { // For spans dataset, use the predefined aggregates if (dataset === DetectorDataset.SPANS || dataset === DetectorDataset.LOGS) { - return ALLOWED_EXPLORE_VISUALIZE_AGGREGATES.map(aggregate => [aggregate, aggregate]); + return getEAPAllowedAggregates(); } // For other datasets, extract function-type options from tableFieldOptions @@ -107,7 +120,7 @@ function getAggregateOptions( // If no function options available, fall back to the predefined aggregates if (functionOptions.length === 0) { - return ALLOWED_EXPLORE_VISUALIZE_AGGREGATES.map(aggregate => [aggregate, aggregate]); + return getEAPAllowedAggregates(); } return functionOptions.sort((a, b) => a[1].localeCompare(b[1])); @@ -218,15 +231,32 @@ export function Visualize() { const fieldOptions = useMemo(() => { // For Spans dataset, use span-specific options from the provider if (dataset === DetectorDataset.SPANS || dataset === DetectorDataset.LOGS) { + // Use field definition to determine what options should be displayed + const fieldDefinition = getFieldDefinition( + aggregate, + dataset === DetectorDataset.SPANS ? 'span' : 'log' + ); + let isTypeAllowed = (_valueType: FieldValueType) => true; + if (fieldDefinition?.parameters?.[0]?.kind === 'column') { + const columnTypes = fieldDefinition?.parameters[0]?.columnTypes; + isTypeAllowed = (valueType: FieldValueType) => + typeof columnTypes === 'function' + ? columnTypes({key: '', valueType}) + : columnTypes.includes(valueType); + } const spanColumnOptions: Array<[string, string]> = [ - ...Object.values(stringSpanTags).map((tag): [string, string] => [ - tag.key, - prettifyTagKey(tag.name), - ]), - ...Object.values(numericSpanTags).map((tag): [string, string] => [ - tag.key, - prettifyTagKey(tag.name), - ]), + ...(isTypeAllowed(FieldValueType.STRING) + ? Object.values(stringSpanTags).map((tag): [string, string] => [ + tag.key, + prettifyTagKey(tag.name), + ]) + : []), + ...(isTypeAllowed(FieldValueType.NUMBER) + ? Object.values(numericSpanTags).map((tag): [string, string] => [ + tag.key, + prettifyTagKey(tag.name), + ]) + : []), ]; return spanColumnOptions.sort((a, b) => a[1].localeCompare(b[1])); } @@ -239,7 +269,7 @@ export function Visualize() { ) .map((option): [string, string] => [option.value.meta.name, option.value.meta.name]) .sort((a, b) => a[1].localeCompare(b[1])); - }, [dataset, stringSpanTags, numericSpanTags, aggregateOptions]); + }, [dataset, stringSpanTags, numericSpanTags, aggregateOptions, aggregate]); const fieldOptionsDropdown = useMemo(() => { return fieldOptions.map(([value, label]) => ({ From 6e9ced793be1771f42d44ab51950289f762cb005 Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Thu, 20 Nov 2025 11:15:16 -0800 Subject: [PATCH 2/2] only disallow aggregates for logs --- .../components/forms/metric/visualize.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/static/app/views/detectors/components/forms/metric/visualize.tsx b/static/app/views/detectors/components/forms/metric/visualize.tsx index 91de7b1f8c40a2..57f3f245e31e52 100644 --- a/static/app/views/detectors/components/forms/metric/visualize.tsx +++ b/static/app/views/detectors/components/forms/metric/visualize.tsx @@ -93,15 +93,18 @@ function renderTag(kind: FieldValueKind): React.ReactNode { return {text}; } -const SPAN_LOGS_NOT_ALLOWED_AGGREGATES = [ +const LOGS_NOT_ALLOWED_AGGREGATES = [ AggregationKey.FAILURE_RATE, AggregationKey.FAILURE_COUNT, ]; -function getEAPAllowedAggregates(): Array<[string, string]> { - return ALLOWED_EXPLORE_VISUALIZE_AGGREGATES.filter( - aggregate => !SPAN_LOGS_NOT_ALLOWED_AGGREGATES.includes(aggregate) - ).map(aggregate => [aggregate, aggregate]); +function getEAPAllowedAggregates(dataset: DetectorDataset): Array<[string, string]> { + return ALLOWED_EXPLORE_VISUALIZE_AGGREGATES.filter(aggregate => { + if (dataset === DetectorDataset.LOGS) { + return !LOGS_NOT_ALLOWED_AGGREGATES.includes(aggregate); + } + return true; + }).map(aggregate => [aggregate, aggregate]); } function getAggregateOptions( @@ -110,7 +113,7 @@ function getAggregateOptions( ): Array<[string, string]> { // For spans dataset, use the predefined aggregates if (dataset === DetectorDataset.SPANS || dataset === DetectorDataset.LOGS) { - return getEAPAllowedAggregates(); + return getEAPAllowedAggregates(dataset); } // For other datasets, extract function-type options from tableFieldOptions @@ -120,7 +123,7 @@ function getAggregateOptions( // If no function options available, fall back to the predefined aggregates if (functionOptions.length === 0) { - return getEAPAllowedAggregates(); + return getEAPAllowedAggregates(dataset); } return functionOptions.sort((a, b) => a[1].localeCompare(b[1]));