options.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import {t} from 'sentry/locale';
  2. import {Organization} from 'sentry/types';
  3. import {
  4. Dataset,
  5. EventTypes,
  6. SessionsAggregate,
  7. } from 'sentry/views/alerts/rules/metric/types';
  8. export type AlertType =
  9. | 'issues'
  10. | 'num_errors'
  11. | 'users_experiencing_errors'
  12. | 'throughput'
  13. | 'trans_duration'
  14. | 'apdex'
  15. | 'failure_rate'
  16. | 'lcp'
  17. | 'fid'
  18. | 'cls'
  19. | 'custom'
  20. | 'crash_free_sessions'
  21. | 'crash_free_users';
  22. export type MetricAlertType = Exclude<AlertType, 'issues'>;
  23. export const AlertWizardAlertNames: Record<AlertType, string> = {
  24. issues: t('Issues'),
  25. num_errors: t('Number of Errors'),
  26. users_experiencing_errors: t('Users Experiencing Errors'),
  27. throughput: t('Throughput'),
  28. trans_duration: t('Transaction Duration'),
  29. apdex: t('Apdex'),
  30. failure_rate: t('Failure Rate'),
  31. lcp: t('Largest Contentful Paint'),
  32. fid: t('First Input Delay'),
  33. cls: t('Cumulative Layout Shift'),
  34. custom: t('Custom Metric'),
  35. crash_free_sessions: t('Crash Free Session Rate'),
  36. crash_free_users: t('Crash Free User Rate'),
  37. };
  38. type AlertWizardCategory = {
  39. categoryHeading: string;
  40. options: AlertType[];
  41. };
  42. export const getAlertWizardCategories = (org: Organization): AlertWizardCategory[] => [
  43. {
  44. categoryHeading: t('Errors'),
  45. options: ['issues', 'num_errors', 'users_experiencing_errors'],
  46. },
  47. ...(org.features.includes('crash-rate-alerts')
  48. ? [
  49. {
  50. categoryHeading: t('Sessions'),
  51. options: ['crash_free_sessions', 'crash_free_users'] as AlertType[],
  52. },
  53. ]
  54. : []),
  55. {
  56. categoryHeading: t('Performance'),
  57. options: [
  58. 'throughput',
  59. 'trans_duration',
  60. 'apdex',
  61. 'failure_rate',
  62. 'lcp',
  63. 'fid',
  64. 'cls',
  65. ],
  66. },
  67. {
  68. categoryHeading: t('Other'),
  69. options: ['custom'],
  70. },
  71. ];
  72. export type WizardRuleTemplate = {
  73. aggregate: string;
  74. dataset: Dataset;
  75. eventTypes: EventTypes;
  76. };
  77. export const AlertWizardRuleTemplates: Record<
  78. MetricAlertType,
  79. Readonly<WizardRuleTemplate>
  80. > = {
  81. num_errors: {
  82. aggregate: 'count()',
  83. dataset: Dataset.ERRORS,
  84. eventTypes: EventTypes.ERROR,
  85. },
  86. users_experiencing_errors: {
  87. aggregate: 'count_unique(user)',
  88. dataset: Dataset.ERRORS,
  89. eventTypes: EventTypes.ERROR,
  90. },
  91. throughput: {
  92. aggregate: 'count()',
  93. dataset: Dataset.TRANSACTIONS,
  94. eventTypes: EventTypes.TRANSACTION,
  95. },
  96. trans_duration: {
  97. aggregate: 'p95(transaction.duration)',
  98. dataset: Dataset.TRANSACTIONS,
  99. eventTypes: EventTypes.TRANSACTION,
  100. },
  101. apdex: {
  102. aggregate: 'apdex(300)',
  103. dataset: Dataset.TRANSACTIONS,
  104. eventTypes: EventTypes.TRANSACTION,
  105. },
  106. failure_rate: {
  107. aggregate: 'failure_rate()',
  108. dataset: Dataset.TRANSACTIONS,
  109. eventTypes: EventTypes.TRANSACTION,
  110. },
  111. lcp: {
  112. aggregate: 'p95(measurements.lcp)',
  113. dataset: Dataset.TRANSACTIONS,
  114. eventTypes: EventTypes.TRANSACTION,
  115. },
  116. fid: {
  117. aggregate: 'p95(measurements.fid)',
  118. dataset: Dataset.TRANSACTIONS,
  119. eventTypes: EventTypes.TRANSACTION,
  120. },
  121. cls: {
  122. aggregate: 'p95(measurements.cls)',
  123. dataset: Dataset.TRANSACTIONS,
  124. eventTypes: EventTypes.TRANSACTION,
  125. },
  126. custom: {
  127. aggregate: 'p95(measurements.fp)',
  128. dataset: Dataset.TRANSACTIONS,
  129. eventTypes: EventTypes.TRANSACTION,
  130. },
  131. crash_free_sessions: {
  132. aggregate: SessionsAggregate.CRASH_FREE_SESSIONS,
  133. // TODO(scttcper): Use Dataset.Metric on GA of alert-crash-free-metrics
  134. dataset: Dataset.SESSIONS,
  135. eventTypes: EventTypes.SESSION,
  136. },
  137. crash_free_users: {
  138. aggregate: SessionsAggregate.CRASH_FREE_USERS,
  139. // TODO(scttcper): Use Dataset.Metric on GA of alert-crash-free-metrics
  140. dataset: Dataset.SESSIONS,
  141. eventTypes: EventTypes.USER,
  142. },
  143. };
  144. export const DEFAULT_WIZARD_TEMPLATE = AlertWizardRuleTemplates.num_errors;
  145. export const hidePrimarySelectorSet = new Set<AlertType>([
  146. 'num_errors',
  147. 'users_experiencing_errors',
  148. 'throughput',
  149. 'apdex',
  150. 'failure_rate',
  151. 'crash_free_sessions',
  152. 'crash_free_users',
  153. ]);
  154. export const hideParameterSelectorSet = new Set<AlertType>([
  155. 'trans_duration',
  156. 'lcp',
  157. 'fid',
  158. 'cls',
  159. ]);
  160. export function getFunctionHelpText(alertType: AlertType): {
  161. labelText: string;
  162. timeWindowText?: string;
  163. } {
  164. const timeWindowText = t('over');
  165. if (alertType === 'apdex') {
  166. return {
  167. labelText: t('Select apdex threshold and time interval'),
  168. timeWindowText,
  169. };
  170. }
  171. if (hidePrimarySelectorSet.has(alertType)) {
  172. return {
  173. labelText: t('Select time interval'),
  174. };
  175. }
  176. return {
  177. labelText: t('Select function and time interval'),
  178. timeWindowText,
  179. };
  180. }