getMetricRuleDiscoverUrl.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import type {NewQuery, Project} from 'sentry/types';
  2. import EventView from 'sentry/utils/discover/eventView';
  3. import {getAggregateAlias} from 'sentry/utils/discover/fields';
  4. import type {TimePeriodType} from 'sentry/views/alerts/rules/metric/details/constants';
  5. import {Dataset, MetricRule, TimePeriod} from 'sentry/views/alerts/rules/metric/types';
  6. import {DEFAULT_PROJECT_THRESHOLD} from 'sentry/views/performance/data';
  7. interface MetricRuleDiscoverUrlOptions {
  8. orgSlug: string;
  9. projects: Project[];
  10. timePeriod: Omit<TimePeriodType, 'display' | 'label'>;
  11. extraQueryParams?: Partial<NewQuery>;
  12. query?: string;
  13. rule?: MetricRule;
  14. }
  15. /**
  16. * Gets the URL for a discover view of the rule with the following default
  17. * parameters:
  18. *
  19. * - Ordered by the rule aggregate, descending
  20. * - yAxis maps to the aggregate
  21. * - Start and end are the period's values selected in the chart header
  22. */
  23. export function getMetricRuleDiscoverUrl({
  24. orgSlug,
  25. ...rest
  26. }: MetricRuleDiscoverUrlOptions) {
  27. const discoverView = getMetricRuleDiscoverQuery(rest);
  28. if (!discoverView || !rest.rule) {
  29. return '';
  30. }
  31. const {query, ...toObject} = discoverView.getResultsViewUrlTarget(orgSlug);
  32. const timeWindowString = `${rest.rule.timeWindow}m`;
  33. return {
  34. query: {...query, interval: timeWindowString},
  35. ...toObject,
  36. };
  37. }
  38. export function getMetricRuleDiscoverQuery({
  39. projects,
  40. rule,
  41. timePeriod,
  42. query,
  43. extraQueryParams,
  44. }: Omit<MetricRuleDiscoverUrlOptions, 'orgSlug'>) {
  45. if (!projects || !projects.length || !rule) {
  46. return null;
  47. }
  48. const aggregateAlias = getAggregateAlias(rule.aggregate);
  49. const timePeriodFields = timePeriod.usingPeriod
  50. ? {range: timePeriod.period === TimePeriod.SEVEN_DAYS ? '7d' : timePeriod.period}
  51. : {start: timePeriod.start, end: timePeriod.end};
  52. const fields =
  53. rule.dataset === Dataset.ERRORS
  54. ? ['issue', 'count()', 'count_unique(user)']
  55. : [
  56. 'transaction',
  57. 'project',
  58. `${rule.aggregate}`,
  59. 'count_unique(user)',
  60. `user_misery(${DEFAULT_PROJECT_THRESHOLD})`,
  61. ];
  62. const eventQuery: NewQuery = {
  63. id: undefined,
  64. name: (rule && rule.name) || 'Transactions',
  65. fields,
  66. orderby: `-${aggregateAlias}`,
  67. query: query ?? rule.query ?? '',
  68. version: 2,
  69. projects: projects
  70. .filter(({slug}) => rule.projects.includes(slug))
  71. .map(project => Number(project.id)),
  72. environment: rule.environment ? [rule.environment] : undefined,
  73. ...timePeriodFields,
  74. ...extraQueryParams,
  75. };
  76. return EventView.fromSavedQuery(eventQuery);
  77. }