utils.tsx 2.9 KB

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