functionBreakpointChart.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import {useEffect} from 'react';
  2. import * as Sentry from '@sentry/react';
  3. import {ChartType} from 'sentry/chartcuterie/types';
  4. import Chart from 'sentry/components/events/eventStatisticalDetector/lineChart';
  5. import {DataSection} from 'sentry/components/events/styles';
  6. import type {Event} from 'sentry/types/event';
  7. import {defined} from 'sentry/utils';
  8. import {useProfileEventsStats} from 'sentry/utils/profiling/hooks/useProfileEventsStats';
  9. import {useRelativeDateTime} from 'sentry/utils/profiling/hooks/useRelativeDateTime';
  10. import type {NormalizedTrendsTransaction} from 'sentry/views/performance/trends/types';
  11. import {RELATIVE_DAYS_WINDOW} from './consts';
  12. type EventFunctionBreakpointChartProps = {
  13. event: Event;
  14. };
  15. export function EventFunctionBreakpointChart({event}: EventFunctionBreakpointChartProps) {
  16. const evidenceData = event.occurrence?.evidenceData;
  17. const fingerprint = evidenceData?.fingerprint;
  18. const breakpoint = evidenceData?.breakpoint;
  19. const isValid = defined(fingerprint) && defined(breakpoint);
  20. useEffect(() => {
  21. if (isValid) {
  22. return;
  23. }
  24. Sentry.withScope(scope => {
  25. scope.setContext('evidence data fields', {
  26. fingerprint,
  27. breakpoint,
  28. });
  29. Sentry.captureException(
  30. new Error('Missing required evidence data on function regression issue.')
  31. );
  32. });
  33. }, [isValid, fingerprint, breakpoint]);
  34. return (
  35. <EventFunctionBreakpointChartInner
  36. breakpoint={breakpoint}
  37. evidenceData={evidenceData!}
  38. fingerprint={fingerprint}
  39. />
  40. );
  41. }
  42. type EventFunctionBreakpointChartInnerProps = {
  43. breakpoint: number;
  44. evidenceData: Record<string, any>;
  45. fingerprint: number;
  46. };
  47. const SERIES = ['p95()'];
  48. function EventFunctionBreakpointChartInner({
  49. breakpoint,
  50. evidenceData,
  51. fingerprint,
  52. }: EventFunctionBreakpointChartInnerProps) {
  53. const datetime = useRelativeDateTime({
  54. anchor: breakpoint,
  55. relativeDays: RELATIVE_DAYS_WINDOW,
  56. });
  57. const functionStats = useProfileEventsStats({
  58. dataset: 'profileFunctions',
  59. datetime,
  60. query: `fingerprint:${fingerprint}`,
  61. referrer: 'api.profiling.functions.regression.stats',
  62. yAxes: SERIES,
  63. });
  64. const normalizedOccurrenceEvent = {
  65. aggregate_range_1: evidenceData.aggregateRange1 / 1e6,
  66. aggregate_range_2: evidenceData.aggregateRange2 / 1e6,
  67. breakpoint: evidenceData.breakpoint,
  68. } as NormalizedTrendsTransaction;
  69. return (
  70. <DataSection>
  71. <Chart
  72. percentileData={functionStats}
  73. evidenceData={normalizedOccurrenceEvent}
  74. datetime={datetime}
  75. chartType={ChartType.SLACK_PERFORMANCE_FUNCTION_REGRESSION}
  76. />
  77. </DataSection>
  78. );
  79. }