initializePerformanceData.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {ProjectFixture} from 'sentry-fixture/project';
  3. import {initializeOrg} from 'sentry-test/initializeOrg';
  4. import {RawSpanType} from 'sentry/components/events/interfaces/spans/types';
  5. import {EntryType, EventTransaction, Project} from 'sentry/types';
  6. import {defined} from 'sentry/utils';
  7. import EventView from 'sentry/utils/discover/eventView';
  8. import {
  9. ExampleSpan,
  10. ExampleTransaction,
  11. SuspectSpan,
  12. } from 'sentry/utils/performance/suspectSpans/types';
  13. export interface InitializeDataSettings {
  14. features?: string[];
  15. project?: any; // TODO(k-fish): Fix this project type.
  16. projects?: Project[];
  17. query?: {};
  18. selectedProject?: any;
  19. }
  20. export function initializeData(settings?: InitializeDataSettings) {
  21. const _defaultProject = ProjectFixture();
  22. const _settings = {
  23. query: {},
  24. features: [],
  25. projects: [_defaultProject],
  26. project: _defaultProject,
  27. ...settings,
  28. };
  29. const {query, features, projects, selectedProject: project} = _settings;
  30. const organization = OrganizationFixture({
  31. features,
  32. projects,
  33. });
  34. const routerLocation: {query: {project?: string}} = {
  35. query: {
  36. ...query,
  37. },
  38. };
  39. if (settings?.selectedProject || settings?.project) {
  40. routerLocation.query.project = (project || settings?.project) as any;
  41. }
  42. const router = {
  43. location: routerLocation,
  44. };
  45. const initialData = initializeOrg({organization, projects, project, router});
  46. const location = initialData.router.location;
  47. const eventView = EventView.fromLocation(location);
  48. return {...initialData, location, eventView};
  49. }
  50. export const SAMPLE_SPANS = [
  51. {
  52. op: 'op1',
  53. group: 'aaaaaaaaaaaaaaaa',
  54. description: 'span-1',
  55. examples: [
  56. {
  57. id: 'abababababababab',
  58. description: 'span-1',
  59. spans: [{id: 'ababab11'}, {id: 'ababab22'}],
  60. },
  61. {
  62. id: 'acacacacacacacac',
  63. description: 'span-2',
  64. spans: [{id: 'acacac11'}, {id: 'acacac22'}],
  65. },
  66. {
  67. id: 'adadadadadadadad',
  68. description: 'span-3',
  69. spans: [{id: 'adadad11'}, {id: 'adadad22'}],
  70. },
  71. ],
  72. },
  73. {
  74. op: 'op2',
  75. group: 'bbbbbbbbbbbbbbbb',
  76. description: 'span-4',
  77. examples: [
  78. {
  79. id: 'bcbcbcbcbcbcbcbc',
  80. description: 'span-4',
  81. spans: [{id: 'bcbcbc11'}, {id: 'bcbcbc11'}],
  82. },
  83. {
  84. id: 'bdbdbdbdbdbdbdbd',
  85. description: 'span-5',
  86. spans: [{id: 'bdbdbd11'}, {id: 'bdbdbd22'}],
  87. },
  88. {
  89. id: 'bebebebebebebebe',
  90. description: 'span-6',
  91. spans: [{id: 'bebebe11'}, {id: 'bebebe22'}],
  92. },
  93. ],
  94. },
  95. ];
  96. type SpanOpt = {
  97. id: string;
  98. };
  99. type ExampleOpt = {
  100. description: string;
  101. id: string;
  102. spans: SpanOpt[];
  103. };
  104. type SuspectOpt = {
  105. description: string;
  106. examples: ExampleOpt[];
  107. group: string;
  108. op: string;
  109. };
  110. function makeSpan(opt: SpanOpt): ExampleSpan {
  111. const {id} = opt;
  112. return {
  113. id,
  114. startTimestamp: 10100,
  115. finishTimestamp: 10200,
  116. exclusiveTime: 100,
  117. };
  118. }
  119. function makeExample(opt: ExampleOpt): ExampleTransaction {
  120. const {id, description, spans} = opt;
  121. return {
  122. id,
  123. description,
  124. startTimestamp: 10000,
  125. finishTimestamp: 12000,
  126. nonOverlappingExclusiveTime: 2000,
  127. spans: spans.map(makeSpan),
  128. };
  129. }
  130. export function makeSuspectSpan(opt: SuspectOpt): SuspectSpan {
  131. const {op, group, description, examples} = opt;
  132. return {
  133. op,
  134. group,
  135. description,
  136. frequency: 1,
  137. count: 1,
  138. avgOccurrences: 1,
  139. sumExclusiveTime: 5,
  140. p50ExclusiveTime: 1,
  141. p75ExclusiveTime: 2,
  142. p95ExclusiveTime: 3,
  143. p99ExclusiveTime: 4,
  144. examples: examples.map(makeExample),
  145. };
  146. }
  147. export function generateSuspectSpansResponse(opts?: {
  148. examples?: number;
  149. examplesOnly?: boolean;
  150. }) {
  151. const {examples, examplesOnly} = opts ?? {};
  152. return SAMPLE_SPANS.map(sampleSpan => {
  153. const span = {...sampleSpan};
  154. if (defined(examples)) {
  155. span.examples = span.examples.slice(0, examples);
  156. }
  157. const suspectSpans = makeSuspectSpan(span);
  158. if (examplesOnly) {
  159. return {
  160. op: suspectSpans.op,
  161. group: suspectSpans.group,
  162. examples: suspectSpans.examples,
  163. };
  164. }
  165. return suspectSpans;
  166. });
  167. }
  168. export function generateSampleEvent(): EventTransaction {
  169. const event = {
  170. id: '2b658a829a21496b87fd1f14a61abf65',
  171. eventID: '2b658a829a21496b87fd1f14a61abf65',
  172. title: '/organizations/:orgId/discover/results/',
  173. type: 'transaction',
  174. startTimestamp: 1622079935.86141,
  175. endTimestamp: 1622079940.032905,
  176. contexts: {
  177. trace: {
  178. trace_id: '8cbbc19c0f54447ab702f00263262726',
  179. span_id: 'a000000000000000',
  180. op: 'pageload',
  181. status: 'unknown',
  182. type: 'trace',
  183. },
  184. },
  185. entries: [
  186. {
  187. data: [],
  188. type: EntryType.SPANS,
  189. },
  190. ],
  191. } as unknown as EventTransaction;
  192. return event;
  193. }
  194. export function generateSampleSpan(
  195. description: string | undefined,
  196. op: string | undefined,
  197. span_id: string,
  198. parent_span_id: string,
  199. event: EventTransaction
  200. ) {
  201. const span: RawSpanType = {
  202. start_timestamp: 1000,
  203. timestamp: 2000,
  204. description,
  205. op,
  206. span_id,
  207. parent_span_id,
  208. trace_id: '8cbbc19c0f54447ab702f00263262726',
  209. status: 'ok',
  210. tags: {
  211. 'http.status_code': '200',
  212. },
  213. data: {},
  214. };
  215. if (!Array.isArray(event.entries[0].data)) {
  216. throw new Error('Event entries data is not an array');
  217. }
  218. const data = event.entries[0].data as RawSpanType[];
  219. data.push(span);
  220. return span;
  221. }