replayReader.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import type {eventWithTime} from 'rrweb/typings/types';
  2. import type {
  3. MemorySpanType,
  4. RawSpanType,
  5. } from 'sentry/components/events/interfaces/spans/types';
  6. import type {RawCrumb} from 'sentry/types/breadcrumbs';
  7. import type {Event, EventTransaction} from 'sentry/types/event';
  8. import {Entry, EntryType} from 'sentry/types/event';
  9. import {
  10. breadcrumbEntryFactory,
  11. breadcrumbValuesFromEvents,
  12. replayTimestamps,
  13. rrwebEventListFactory,
  14. spanDataFromEvents,
  15. spanEntryFactory,
  16. } from 'sentry/utils/replays/replayDataUtils';
  17. export default class ReplayReader {
  18. static factory(
  19. event: EventTransaction | undefined,
  20. rrwebEvents: eventWithTime[] | undefined,
  21. replayEvents: Event[] | undefined
  22. ) {
  23. if (!event || !rrwebEvents || !replayEvents) {
  24. return null;
  25. }
  26. return new ReplayReader(event, rrwebEvents, replayEvents);
  27. }
  28. private constructor(
  29. /**
  30. * The root Replay event, created at the start of the browser session.
  31. */
  32. event: EventTransaction,
  33. /**
  34. * The captured data from rrweb.
  35. * Saved as N attachments that belong to the root Replay event.
  36. */
  37. rrwebEvents: eventWithTime[],
  38. /**
  39. * Regular Sentry SDK events that occurred during the rrweb session.
  40. */
  41. replayEvents: Event[]
  42. ) {
  43. const rawCrumbs = breadcrumbValuesFromEvents(replayEvents);
  44. const rawSpanData = spanDataFromEvents(replayEvents);
  45. const {startTimestampMS, endTimestampMS} = replayTimestamps(
  46. rrwebEvents,
  47. rawCrumbs,
  48. rawSpanData
  49. );
  50. this.breadcrumbEntry = breadcrumbEntryFactory(
  51. startTimestampMS,
  52. event.tags,
  53. rawCrumbs
  54. );
  55. this.spanEntry = spanEntryFactory(rawSpanData);
  56. this.rrwebEvents = rrwebEventListFactory(
  57. startTimestampMS,
  58. endTimestampMS,
  59. rawSpanData,
  60. rrwebEvents
  61. );
  62. this.event = {
  63. ...event,
  64. entries: [this.breadcrumbEntry, this.spanEntry],
  65. startTimestamp: startTimestampMS / 1000,
  66. endTimestamp: endTimestampMS / 1000,
  67. } as EventTransaction;
  68. }
  69. event: EventTransaction;
  70. rrwebEvents: eventWithTime[];
  71. breadcrumbEntry: Entry;
  72. spanEntry: Entry;
  73. getEvent = () => {
  74. return this.event;
  75. };
  76. getRRWebEvents = () => {
  77. return this.rrwebEvents;
  78. };
  79. getEntryType = (type: EntryType) => {
  80. switch (type) {
  81. case EntryType.BREADCRUMBS:
  82. return this.breadcrumbEntry;
  83. case EntryType.SPANS:
  84. return this.spanEntry;
  85. default:
  86. throw new Error(
  87. `ReplayReader is unable to prepare EntryType ${type}. Type not supported.`
  88. );
  89. }
  90. };
  91. getRawCrumbs = () => {
  92. return this.breadcrumbEntry.data.values as RawCrumb[];
  93. };
  94. getRawSpans = () => {
  95. return this.spanEntry.data as RawSpanType[];
  96. };
  97. isMemorySpan = (span: RawSpanType): span is MemorySpanType => {
  98. return span.op === 'memory';
  99. };
  100. isNotMemorySpan = (span: RawSpanType) => {
  101. return !this.isMemorySpan(span);
  102. };
  103. }