initializePerformanceData.ts 5.5 KB

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