traceBackgroundPatterns.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import {Fragment, useMemo} from 'react';
  2. import clamp from 'lodash/clamp';
  3. import type {TraceTree} from '../traceModels/traceTree';
  4. import type {TraceTreeNode} from '../traceModels/traceTreeNode';
  5. import type {VirtualizedViewManager} from '../traceRenderers/virtualizedViewManager';
  6. function getMaxErrorSeverity(errors: TraceTree.TraceError[]) {
  7. return errors.reduce((acc, error) => {
  8. if (error.level === 'fatal') {
  9. return 'fatal';
  10. }
  11. if (error.level === 'error') {
  12. return acc === 'fatal' ? 'fatal' : 'error';
  13. }
  14. if (error.level === 'warning') {
  15. return acc === 'fatal' || acc === 'error' ? acc : 'warning';
  16. }
  17. return acc;
  18. }, 'default');
  19. }
  20. interface BackgroundPatternsProps {
  21. errors: TraceTreeNode<TraceTree.Transaction>['errors'];
  22. manager: VirtualizedViewManager;
  23. node_space: [number, number] | null;
  24. performance_issues: TraceTreeNode<TraceTree.Transaction>['performance_issues'];
  25. }
  26. export function TraceBackgroundPatterns(props: BackgroundPatternsProps) {
  27. const performance_issues = useMemo(() => {
  28. if (!props.performance_issues.size) {
  29. return [];
  30. }
  31. return [...props.performance_issues];
  32. }, [props.performance_issues]);
  33. const errors = useMemo(() => {
  34. if (!props.errors.size) {
  35. return [];
  36. }
  37. return [...props.errors];
  38. }, [props.errors]);
  39. const severity = useMemo(() => {
  40. return getMaxErrorSeverity(errors);
  41. }, [errors]);
  42. if (!props.performance_issues.size && !props.errors.size) {
  43. return null;
  44. }
  45. // If there is an error, render the error pattern across the entire width.
  46. // Else if there is a performance issue, render the performance issue pattern
  47. // for the duration of the performance issue. If there is a profile, render
  48. // the profile pattern for entire duration (we do not have profile durations here)
  49. return (
  50. <Fragment>
  51. {errors.length > 0 ? (
  52. <div
  53. className="TracePatternContainer"
  54. style={{
  55. left: 0,
  56. width: '100%',
  57. }}
  58. >
  59. <div className={`TracePattern ${severity}`} />
  60. </div>
  61. ) : performance_issues.length > 0 ? (
  62. <Fragment>
  63. {performance_issues.map((issue, i) => {
  64. const timestamp = issue.start * 1e3;
  65. // Clamp the issue timestamp to the span's timestamp
  66. const left = props.manager.computeRelativeLeftPositionFromOrigin(
  67. clamp(
  68. timestamp,
  69. props.node_space![0],
  70. props.node_space![0] + props.node_space![1]
  71. ),
  72. props.node_space!
  73. );
  74. return (
  75. <div
  76. key={i}
  77. className="TracePatternContainer"
  78. style={{
  79. left: left * 100 + '%',
  80. width: (1 - left) * 100 + '%',
  81. }}
  82. >
  83. <div className="TracePattern performance_issue" />
  84. </div>
  85. );
  86. })}
  87. </Fragment>
  88. ) : null}
  89. </Fragment>
  90. );
  91. }