utils.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import {LocationDescriptor, Query} from 'history';
  2. import {PAGE_URL_PARAM} from 'sentry/constants/pageFilters';
  3. import {Organization, OrganizationSummary} from 'sentry/types';
  4. import {
  5. EventLite,
  6. TraceError,
  7. TraceFull,
  8. TraceFullDetailed,
  9. TraceSplitResults,
  10. } from 'sentry/utils/performance/quickTrace/types';
  11. import {isTraceSplitResult, reduceTrace} from 'sentry/utils/performance/quickTrace/utils';
  12. import {TraceInfo} from './types';
  13. export function getTraceDetailsUrl(
  14. organization: OrganizationSummary,
  15. traceSlug: string,
  16. dateSelection,
  17. query: Query
  18. ): LocationDescriptor {
  19. const {start, end, statsPeriod} = dateSelection;
  20. return {
  21. pathname: `/organizations/${organization.slug}/performance/trace/${traceSlug}/`,
  22. query: {
  23. ...query,
  24. statsPeriod,
  25. [PAGE_URL_PARAM.PAGE_START]: start,
  26. [PAGE_URL_PARAM.PAGE_END]: end,
  27. },
  28. };
  29. }
  30. function transactionVisitor() {
  31. return (accumulator: TraceInfo, event: TraceFullDetailed) => {
  32. for (const error of event.errors ?? []) {
  33. accumulator.errors.add(error.event_id);
  34. }
  35. for (const performanceIssue of event.performance_issues ?? []) {
  36. accumulator.errors.add(performanceIssue.event_id);
  37. }
  38. accumulator.transactions.add(event.event_id);
  39. accumulator.projects.add(event.project_slug);
  40. accumulator.startTimestamp = Math.min(
  41. accumulator.startTimestamp,
  42. event.start_timestamp
  43. );
  44. accumulator.endTimestamp = Math.max(accumulator.endTimestamp, event.timestamp);
  45. accumulator.maxGeneration = Math.max(accumulator.maxGeneration, event.generation);
  46. return accumulator;
  47. };
  48. }
  49. export function hasTraceData(
  50. traces: TraceFullDetailed[] | null | undefined,
  51. orphanErrors: TraceError[] | undefined
  52. ): boolean {
  53. return Boolean(
  54. (traces && traces.length > 0) || (orphanErrors && orphanErrors.length > 0)
  55. );
  56. }
  57. export function getTraceSplitResults<U extends TraceFullDetailed | TraceFull | EventLite>(
  58. trace: TraceSplitResults<U> | U[],
  59. organization: Organization
  60. ) {
  61. let transactions: U[] | undefined;
  62. let orphanErrors: TraceError[] | undefined;
  63. if (
  64. trace &&
  65. organization.features.includes('performance-tracing-without-performance') &&
  66. isTraceSplitResult<TraceSplitResults<U>, U[]>(trace)
  67. ) {
  68. orphanErrors = trace.orphan_errors;
  69. transactions = trace.transactions;
  70. }
  71. return {transactions, orphanErrors};
  72. }
  73. export function getTraceInfo(
  74. traces: TraceFullDetailed[] = [],
  75. orphanErrors: TraceError[] = []
  76. ) {
  77. const initial = {
  78. projects: new Set<string>(),
  79. errors: new Set<string>(),
  80. performanceIssues: new Set<string>(),
  81. transactions: new Set<string>(),
  82. startTimestamp: Number.MAX_SAFE_INTEGER,
  83. endTimestamp: 0,
  84. maxGeneration: 0,
  85. };
  86. const transactionsInfo = traces.reduce(
  87. (info: TraceInfo, trace: TraceFullDetailed) =>
  88. reduceTrace<TraceInfo>(trace, transactionVisitor(), info),
  89. initial
  90. );
  91. // Accumulate orphan error information.
  92. return orphanErrors.reduce((accumulator: TraceInfo, event: TraceError) => {
  93. accumulator.errors.add(event.event_id);
  94. if (event.timestamp) {
  95. accumulator.startTimestamp = Math.min(accumulator.startTimestamp, event.timestamp);
  96. accumulator.endTimestamp = Math.max(accumulator.endTimestamp, event.timestamp);
  97. }
  98. return accumulator;
  99. }, transactionsInfo);
  100. }
  101. export function shortenErrorTitle(title: string): string {
  102. return title.split(':')[0];
  103. }
  104. export function isRootTransaction(trace: TraceFullDetailed): boolean {
  105. // Root transactions has no parent_span_id
  106. return trace.parent_span_id === null;
  107. }