data.tsx 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. import {t} from 'sentry/locale';
  2. import ConfigStore from 'sentry/stores/configStore';
  3. import type {Organization} from 'sentry/types';
  4. import {TOP_N} from 'sentry/utils/discover/types';
  5. import type {Widget} from '../types';
  6. import {DisplayType, WidgetType} from '../types';
  7. export type WidgetTemplate = Widget & {
  8. description: string;
  9. };
  10. export const getDefaultWidgets = (organization: Organization) => {
  11. const isSelfHostedErrorsOnly = ConfigStore.get('isSelfHostedErrorsOnly');
  12. const transactionsWidgets = [
  13. {
  14. id: 'duration-distribution',
  15. title: t('Duration Distribution'),
  16. description: t('Compare transaction durations across different percentiles.'),
  17. displayType: DisplayType.LINE,
  18. widgetType: organization.features.includes('performance-discover-dataset-selector')
  19. ? WidgetType.TRANSACTIONS
  20. : WidgetType.DISCOVER,
  21. interval: '5m',
  22. queries: [
  23. {
  24. name: '',
  25. conditions: 'event.type:transaction',
  26. fields: [
  27. 'p50(transaction.duration)',
  28. 'p75(transaction.duration)',
  29. 'p95(transaction.duration)',
  30. ],
  31. aggregates: [
  32. 'p50(transaction.duration)',
  33. 'p75(transaction.duration)',
  34. 'p95(transaction.duration)',
  35. ],
  36. columns: [],
  37. orderby: '',
  38. },
  39. ],
  40. },
  41. {
  42. id: 'high-throughput-transactions',
  43. title: t('High Throughput Transactions'),
  44. description: t('Top 5 transactions with the largest volume.'),
  45. displayType: DisplayType.TOP_N,
  46. widgetType: organization.features.includes('performance-discover-dataset-selector')
  47. ? WidgetType.TRANSACTIONS
  48. : WidgetType.DISCOVER,
  49. interval: '5m',
  50. queries: [
  51. {
  52. name: '',
  53. conditions: 'event.type:transaction',
  54. fields: ['transaction', 'count()'],
  55. aggregates: ['count()'],
  56. columns: ['transaction'],
  57. orderby: '-count()',
  58. },
  59. ],
  60. },
  61. {
  62. id: 'crash-rates-recent-releases',
  63. title: t('Crash Rates for Recent Releases'),
  64. description: t('Percentage of crashed sessions for latest releases.'),
  65. displayType: DisplayType.LINE,
  66. widgetType: WidgetType.RELEASE,
  67. interval: '5m',
  68. limit: 8,
  69. queries: [
  70. {
  71. name: '',
  72. conditions: '',
  73. fields: ['crash_rate(session)', 'release'],
  74. aggregates: ['crash_rate(session)'],
  75. columns: ['release'],
  76. orderby: '-release',
  77. },
  78. ],
  79. },
  80. {
  81. id: 'session-health',
  82. title: t('Session Health'),
  83. description: t('Number of abnormal, crashed, errored and healthy sessions.'),
  84. displayType: DisplayType.TABLE,
  85. widgetType: WidgetType.RELEASE,
  86. interval: '5m',
  87. queries: [
  88. {
  89. name: '',
  90. conditions: '',
  91. fields: ['session.status', 'sum(session)'],
  92. aggregates: ['sum(session)'],
  93. columns: ['session.status'],
  94. orderby: '-sum(session)',
  95. },
  96. ],
  97. },
  98. {
  99. id: 'lcp-country',
  100. title: t('LCP by Country'),
  101. description: t('Table showing page load times by country.'),
  102. displayType: DisplayType.TABLE,
  103. widgetType: organization.features.includes('performance-discover-dataset-selector')
  104. ? WidgetType.TRANSACTIONS
  105. : WidgetType.DISCOVER,
  106. interval: '5m',
  107. queries: [
  108. {
  109. name: '',
  110. conditions: 'has:geo.country_code',
  111. fields: ['geo.country_code', 'geo.region', 'p75(measurements.lcp)'],
  112. aggregates: ['p75(measurements.lcp)'],
  113. columns: ['geo.country_code', 'geo.region'],
  114. orderby: '-p75(measurements.lcp)',
  115. },
  116. ],
  117. },
  118. {
  119. id: 'miserable-users',
  120. title: t('Miserable Users'),
  121. description: t('Unique users who have experienced slow load times.'),
  122. displayType: DisplayType.BIG_NUMBER,
  123. widgetType: organization.features.includes('performance-discover-dataset-selector')
  124. ? WidgetType.TRANSACTIONS
  125. : WidgetType.DISCOVER,
  126. interval: '5m',
  127. queries: [
  128. {
  129. name: '',
  130. conditions: '',
  131. fields: ['count_miserable(user,300)'],
  132. aggregates: ['count_miserable(user,300)'],
  133. columns: [],
  134. orderby: '',
  135. },
  136. ],
  137. },
  138. {
  139. id: 'slow-vs-fast',
  140. title: t('Slow vs. Fast Transactions'),
  141. description: t(
  142. 'Percentage breakdown of transaction durations over and under 300ms.'
  143. ),
  144. displayType: DisplayType.BAR,
  145. widgetType: organization.features.includes('performance-discover-dataset-selector')
  146. ? WidgetType.TRANSACTIONS
  147. : WidgetType.DISCOVER,
  148. interval: '5m',
  149. queries: [
  150. {
  151. name: '',
  152. conditions: 'event.type:transaction',
  153. fields: [
  154. 'equation|(count_if(transaction.duration,greater,300) / count()) * 100',
  155. 'equation|(count_if(transaction.duration,lessOrEquals,300) / count()) * 100',
  156. ],
  157. aggregates: [
  158. 'equation|(count_if(transaction.duration,greater,300) / count()) * 100',
  159. 'equation|(count_if(transaction.duration,lessOrEquals,300) / count()) * 100',
  160. ],
  161. columns: [],
  162. orderby: '',
  163. },
  164. ],
  165. },
  166. ];
  167. const errorsWidgets = [
  168. {
  169. id: 'issue-for-review',
  170. title: t('Issues For Review'),
  171. description: t('Most recently seen unresolved issues for review.'),
  172. displayType: DisplayType.TABLE,
  173. widgetType: WidgetType.ISSUE,
  174. interval: '5m',
  175. queries: [
  176. {
  177. name: '',
  178. conditions: 'is:unresolved is:for_review',
  179. fields: ['issue', 'assignee', 'events', 'title'],
  180. aggregates: [],
  181. columns: ['issue', 'assignee', 'events', 'title'],
  182. orderby: 'date',
  183. },
  184. ],
  185. },
  186. {
  187. id: 'top-unhandled',
  188. title: t('Top Unhandled Error Types'),
  189. description: t('Most frequently encountered unhandled errors.'),
  190. displayType: DisplayType.TOP_N,
  191. widgetType: organization.features.includes('performance-discover-dataset-selector')
  192. ? WidgetType.ERRORS
  193. : WidgetType.DISCOVER,
  194. interval: '5m',
  195. queries: [
  196. {
  197. name: '',
  198. conditions: 'error.unhandled:true',
  199. fields: ['error.type', 'count()'],
  200. aggregates: ['count()'],
  201. columns: ['error.type'],
  202. orderby: '-count()',
  203. },
  204. ],
  205. },
  206. {
  207. id: 'users-affected',
  208. title: t('Users Affected by Errors'),
  209. description: t('Footprint of unique users affected by errors.'),
  210. displayType: DisplayType.LINE,
  211. widgetType: organization.features.includes('performance-discover-dataset-selector')
  212. ? WidgetType.ERRORS
  213. : WidgetType.DISCOVER,
  214. interval: '5m',
  215. queries: [
  216. {
  217. name: '',
  218. conditions: 'event.type:error',
  219. fields: ['count_unique(user)', 'count()'],
  220. aggregates: ['count_unique(user)', 'count()'],
  221. columns: [],
  222. orderby: '',
  223. },
  224. ],
  225. },
  226. ];
  227. return isSelfHostedErrorsOnly
  228. ? errorsWidgets
  229. : [...transactionsWidgets, ...errorsWidgets];
  230. };
  231. export function getTopNConvertedDefaultWidgets(
  232. organization: Organization
  233. ): Readonly<Array<WidgetTemplate>> {
  234. return getDefaultWidgets(organization).map(widget => {
  235. if (widget.displayType === DisplayType.TOP_N) {
  236. return {
  237. ...widget,
  238. displayType: DisplayType.AREA,
  239. limit: TOP_N,
  240. };
  241. }
  242. return widget;
  243. });
  244. }