spanOpSelector.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import {CompactSelect} from 'sentry/components/compactSelect';
  2. import {t} from 'sentry/locale';
  3. import type {NewQuery} from 'sentry/types/organization';
  4. import {trackAnalytics} from 'sentry/utils/analytics';
  5. import {browserHistory} from 'sentry/utils/browserHistory';
  6. import EventView from 'sentry/utils/discover/eventView';
  7. import {DiscoverDatasets} from 'sentry/utils/discover/types';
  8. import {decodeScalar} from 'sentry/utils/queryString';
  9. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  10. import {useLocation} from 'sentry/utils/useLocation';
  11. import useOrganization from 'sentry/utils/useOrganization';
  12. import usePageFilters from 'sentry/utils/usePageFilters';
  13. import {appendReleaseFilters} from 'sentry/views/insights/common/utils/releaseComparison';
  14. import {COLD_START_TYPE} from 'sentry/views/insights/mobile/appStarts/components/startTypeSelector';
  15. import useCrossPlatformProject from 'sentry/views/insights/mobile/common/queries/useCrossPlatformProject';
  16. import {TTID_CONTRIBUTING_SPAN_OPS} from 'sentry/views/insights/mobile/screenload/components/spanOpSelector';
  17. import {useTableQuery} from 'sentry/views/insights/mobile/screenload/components/tables/screensTable';
  18. import {MobileCursors} from 'sentry/views/insights/mobile/screenload/constants';
  19. import {SpanMetricsField} from 'sentry/views/insights/types';
  20. export const APP_START_SPANS = [
  21. ...TTID_CONTRIBUTING_SPAN_OPS,
  22. 'app.start.cold',
  23. 'app.start.warm',
  24. 'contentprovider.load',
  25. 'application.load',
  26. 'activity.load',
  27. 'process.load',
  28. ];
  29. type Props = {
  30. primaryRelease?: string;
  31. secondaryRelease?: string;
  32. transaction?: string;
  33. };
  34. export function SpanOpSelector({transaction, primaryRelease, secondaryRelease}: Props) {
  35. const location = useLocation();
  36. const organization = useOrganization();
  37. const {selection} = usePageFilters();
  38. const {isProjectCrossPlatform, selectedPlatform} = useCrossPlatformProject();
  39. const value = decodeScalar(location.query[SpanMetricsField.SPAN_OP]) ?? '';
  40. const appStartType =
  41. decodeScalar(location.query[SpanMetricsField.APP_START_TYPE]) ?? COLD_START_TYPE;
  42. const searchQuery = new MutableSearch([
  43. // Exclude root level spans because they're comprised of nested operations
  44. '!span.description:"Cold Start"',
  45. '!span.description:"Warm Start"',
  46. // Exclude this span because we can get TTID contributing spans instead
  47. '!span.description:"Initial Frame Render"',
  48. 'has:span.description',
  49. 'transaction.op:ui.load',
  50. `transaction:${transaction}`,
  51. `has:ttid`,
  52. `span.op:[${APP_START_SPANS.join(',')}]`,
  53. `app_start_type:${appStartType}`,
  54. ]);
  55. if (isProjectCrossPlatform) {
  56. searchQuery.addFilterValue('os.name', selectedPlatform);
  57. }
  58. const queryStringPrimary = appendReleaseFilters(
  59. searchQuery,
  60. primaryRelease,
  61. secondaryRelease
  62. );
  63. const newQuery: NewQuery = {
  64. name: '',
  65. fields: [SpanMetricsField.SPAN_OP, 'count()'],
  66. query: queryStringPrimary,
  67. dataset: DiscoverDatasets.SPANS_METRICS,
  68. version: 2,
  69. projects: selection.projects,
  70. };
  71. const eventView = EventView.fromNewQueryWithLocation(newQuery, location);
  72. const {data} = useTableQuery({
  73. eventView,
  74. enabled: true,
  75. limit: 25,
  76. referrer: 'api.starfish.get-span-operations',
  77. });
  78. const options = [
  79. {value: '', label: t('All')},
  80. ...(data?.data ?? [])
  81. .filter(datum => Boolean(datum[SpanMetricsField.SPAN_OP]))
  82. .map(datum => {
  83. return {
  84. value: datum[SpanMetricsField.SPAN_OP],
  85. label: datum[SpanMetricsField.SPAN_OP],
  86. };
  87. }),
  88. ];
  89. return (
  90. <CompactSelect
  91. triggerProps={{prefix: t('Operation')}}
  92. value={value}
  93. options={options ?? []}
  94. onChange={newValue => {
  95. trackAnalytics('insight.app_start.spans.filter_by_operation', {
  96. organization,
  97. filter: newValue.value as string,
  98. });
  99. browserHistory.push({
  100. ...location,
  101. query: {
  102. ...location.query,
  103. [SpanMetricsField.SPAN_OP]: newValue.value,
  104. [MobileCursors.SPANS_TABLE]: undefined,
  105. },
  106. });
  107. }}
  108. />
  109. );
  110. }