data.tsx 6.3 KB

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