traceGuards.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import {MissingInstrumentationNode} from './traceModels/missingInstrumentationNode';
  2. import {ParentAutogroupNode} from './traceModels/parentAutogroupNode';
  3. import {SiblingAutogroupNode} from './traceModels/siblingAutogroupNode';
  4. import {CollapsedNode} from './traceModels/traceCollapsedNode';
  5. import type {TraceTree} from './traceModels/traceTree';
  6. import type {TraceTreeNode} from './traceModels/traceTreeNode';
  7. export function isMissingInstrumentationNode(
  8. node: TraceTreeNode<TraceTree.NodeValue>
  9. ): node is MissingInstrumentationNode {
  10. return node instanceof MissingInstrumentationNode;
  11. }
  12. export function isSpanNode(
  13. node: TraceTreeNode<TraceTree.NodeValue>
  14. ): node is TraceTreeNode<TraceTree.Span> {
  15. return (
  16. !!(node.value && !('transaction' in node.value) && 'span_id' in node.value) &&
  17. !isMissingInstrumentationNode(node) &&
  18. !isAutogroupedNode(node)
  19. );
  20. }
  21. export function isTransactionNode(
  22. node: TraceTreeNode<TraceTree.NodeValue>
  23. ): node is TraceTreeNode<TraceTree.Transaction> {
  24. return !!(node.value && 'transaction' in node.value) && !isAutogroupedNode(node);
  25. }
  26. export function isParentAutogroupedNode(
  27. node: TraceTreeNode<TraceTree.NodeValue>
  28. ): node is ParentAutogroupNode {
  29. return node instanceof ParentAutogroupNode;
  30. }
  31. export function isSiblingAutogroupedNode(
  32. node: TraceTreeNode<TraceTree.NodeValue>
  33. ): node is SiblingAutogroupNode {
  34. return node instanceof SiblingAutogroupNode;
  35. }
  36. export function isAutogroupedNode(
  37. node: TraceTreeNode<TraceTree.NodeValue>
  38. ): node is ParentAutogroupNode | SiblingAutogroupNode {
  39. return node instanceof ParentAutogroupNode || node instanceof SiblingAutogroupNode;
  40. }
  41. export function isCollapsedNode(
  42. node: TraceTreeNode<TraceTree.NodeValue>
  43. ): node is CollapsedNode {
  44. return node instanceof CollapsedNode;
  45. }
  46. export function isTraceErrorNode(
  47. node: TraceTreeNode<TraceTree.NodeValue>
  48. ): node is TraceTreeNode<TraceTree.TraceError> {
  49. return !!(node.value && 'level' in node.value);
  50. }
  51. export function isRootNode(
  52. node: TraceTreeNode<TraceTree.NodeValue>
  53. ): node is TraceTreeNode<null> {
  54. return node.value === null;
  55. }
  56. export function isTraceNode(
  57. node: TraceTreeNode<TraceTree.NodeValue>
  58. ): node is TraceTreeNode<TraceTree.Trace> {
  59. return !!(
  60. node.value &&
  61. ('orphan_errors' in node.value || 'transactions' in node.value)
  62. );
  63. }
  64. export function shouldAddMissingInstrumentationSpan(sdk: string | undefined): boolean {
  65. if (!sdk) {
  66. return true;
  67. }
  68. if (sdk.length < 'sentry.javascript.'.length) {
  69. return true;
  70. }
  71. switch (sdk.toLowerCase()) {
  72. case 'sentry.javascript.browser':
  73. case 'sentry.javascript.react':
  74. case 'sentry.javascript.gatsby':
  75. case 'sentry.javascript.ember':
  76. case 'sentry.javascript.vue':
  77. case 'sentry.javascript.angular':
  78. case 'sentry.javascript.angular-ivy':
  79. case 'sentry.javascript.nextjs':
  80. case 'sentry.javascript.nuxt':
  81. case 'sentry.javascript.electron':
  82. case 'sentry.javascript.remix':
  83. case 'sentry.javascript.svelte':
  84. case 'sentry.javascript.sveltekit':
  85. case 'sentry.javascript.react-native':
  86. case 'sentry.javascript.astro':
  87. return false;
  88. case undefined:
  89. return true;
  90. default:
  91. return true;
  92. }
  93. }
  94. export function isJavascriptSDKTransaction(transaction: TraceTree.Transaction): boolean {
  95. return /javascript|angular|astro|backbone|ember|gatsby|nextjs|react|remix|svelte|vue/.test(
  96. transaction.sdk_name
  97. );
  98. }
  99. export function isPageloadTransactionNode(
  100. node: TraceTreeNode<TraceTree.NodeValue>
  101. ): boolean {
  102. return isTransactionNode(node) && node.value['transaction.op'] === 'pageload';
  103. }
  104. export function isServerRequestHandlerTransactionNode(
  105. node: TraceTreeNode<TraceTree.NodeValue>
  106. ): boolean {
  107. return isTransactionNode(node) && node.value['transaction.op'] === 'http.server';
  108. }
  109. export function isBrowserRequestSpan(value: TraceTree.Span): boolean {
  110. return (
  111. // Adjust for SDK changes in https://github.com/getsentry/sentry-javascript/pull/13527
  112. value.op === 'browser.request' ||
  113. (value.op === 'browser' && value.description === 'request')
  114. );
  115. }
  116. export function getPageloadTransactionChildCount(
  117. node: TraceTreeNode<TraceTree.NodeValue>
  118. ): number {
  119. if (!isTransactionNode(node)) {
  120. return 0;
  121. }
  122. let count = 0;
  123. for (const txn of node.value.children) {
  124. if (txn && txn['transaction.op'] === 'pageload') {
  125. count++;
  126. }
  127. }
  128. return count;
  129. }
  130. export function isTracePerformanceIssue(
  131. issue: TraceTree.TraceError | TraceTree.TracePerformanceIssue
  132. ): issue is TraceTree.TracePerformanceIssue {
  133. return 'suspect_spans' in issue;
  134. }