traceAnalytics.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import * as Sentry from '@sentry/react';
  2. import type {Organization} from 'sentry/types/organization';
  3. import type {Project} from 'sentry/types/project';
  4. import {trackAnalytics} from 'sentry/utils/analytics';
  5. import type {TraceTree} from 'sentry/views/performance/newTraceDetails/traceModels/traceTree';
  6. import type {TraceType} from 'sentry/views/performance/newTraceDetails/traceType';
  7. const trackTraceMetadata = (
  8. tree: TraceTree,
  9. projects: Project[],
  10. organization: Organization
  11. ) => {
  12. Sentry.metrics.increment(`trace.trace_shape.${tree.shape}`);
  13. // space[1] represents the node duration (in milliseconds)
  14. const trace_duration_seconds = (tree.root.space?.[1] ?? 0) / 1000;
  15. const projectSlugs = [
  16. ...new Set(
  17. tree.list.map(node => node.metadata.project_slug).filter(slug => slug !== undefined)
  18. ),
  19. ];
  20. const projectPlatforms = projects
  21. .filter(p => projectSlugs.includes(p.slug))
  22. .map(project => project?.platform ?? '');
  23. trackAnalytics('trace.metadata', {
  24. shape: tree.shape,
  25. // round trace_duration_seconds to nearest two decimal places
  26. trace_duration_seconds: Math.round(trace_duration_seconds * 100) / 100,
  27. num_root_children: tree.root.children.length,
  28. num_nodes: tree.list.length,
  29. project_platforms: projectPlatforms,
  30. organization,
  31. });
  32. };
  33. const trackFailedToFetchTraceState = () =>
  34. Sentry.metrics.increment('trace.failed_to_fetch_trace');
  35. const trackEmptyTraceState = () => Sentry.metrics.increment('trace.empty_trace');
  36. const trackLayoutChange = (layout: string, organization: Organization) =>
  37. trackAnalytics('trace.trace_layout.change', {
  38. layout,
  39. organization,
  40. });
  41. const trackDrawerMinimize = (organization: Organization) =>
  42. trackAnalytics('trace.trace_layout.drawer_minimize', {
  43. organization,
  44. });
  45. const trackShowInView = (organization: Organization) =>
  46. trackAnalytics('trace.trace_layout.show_in_view', {
  47. organization,
  48. });
  49. const trackViewEventJSON = (organization: Organization) =>
  50. trackAnalytics('trace.trace_layout.view_event_json', {
  51. organization,
  52. });
  53. const trackTabPin = (organization: Organization) =>
  54. trackAnalytics('trace.trace_layout.tab_pin', {
  55. organization,
  56. });
  57. const trackTabView = (tab: string, organization: Organization) =>
  58. trackAnalytics('trace.trace_layout.tab_view', {
  59. organization,
  60. tab,
  61. });
  62. const trackSearchFocus = (organization: Organization) =>
  63. trackAnalytics('trace.trace_layout.search_focus', {
  64. organization,
  65. });
  66. const trackResetZoom = (organization: Organization) =>
  67. trackAnalytics('trace.trace_layout.reset_zoom', {
  68. organization,
  69. });
  70. const trackViewShortcuts = (organization: Organization) =>
  71. trackAnalytics('trace.trace_layout.view_shortcuts', {
  72. organization,
  73. });
  74. const trackTraceWarningType = (type: TraceType, organization: Organization) =>
  75. trackAnalytics('trace.trace_warning_type', {
  76. organization,
  77. type,
  78. });
  79. const traceAnalytics = {
  80. // Trace shape
  81. trackTraceMetadata,
  82. trackEmptyTraceState,
  83. trackFailedToFetchTraceState,
  84. // Drawer actions
  85. trackShowInView,
  86. trackViewEventJSON,
  87. // Layout actions
  88. trackLayoutChange,
  89. trackDrawerMinimize,
  90. trackSearchFocus,
  91. trackTabPin,
  92. trackTabView,
  93. // Toolbar actions
  94. trackResetZoom,
  95. trackViewShortcuts,
  96. trackTraceWarningType,
  97. };
  98. export {traceAnalytics};