data.tsx 6.4 KB

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