123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import {useMemo} from 'react';
- import styled from '@emotion/styled';
- import {LinkButton} from 'sentry/components/button';
- import {DateTime} from 'sentry/components/dateTime';
- import {DataSection} from 'sentry/components/events/styles';
- import Link from 'sentry/components/links/link';
- import PerformanceDuration from 'sentry/components/performanceDuration';
- import {Tooltip} from 'sentry/components/tooltip';
- import {IconOpen} from 'sentry/icons';
- import {t, tct} from 'sentry/locale';
- import {space} from 'sentry/styles/space';
- import type {Event, Group} from 'sentry/types';
- import {IssueType} from 'sentry/types';
- import {defined} from 'sentry/utils';
- import {formatPercentage} from 'sentry/utils/number/formatPercentage';
- import {useRelativeDateTime} from 'sentry/utils/profiling/hooks/useRelativeDateTime';
- import normalizeUrl from 'sentry/utils/url/normalizeUrl';
- import useOrganization from 'sentry/utils/useOrganization';
- import {
- DisplayModes,
- transactionSummaryRouteWithQuery,
- } from 'sentry/views/performance/transactionSummary/utils';
- type EventStatisticalDetectorMessageProps = {
- event: Event;
- group: Group;
- };
- function EventStatisticalDetectorMessage({
- event,
- group,
- }: EventStatisticalDetectorMessageProps) {
- switch (group.issueType) {
- case IssueType.PERFORMANCE_DURATION_REGRESSION:
- case IssueType.PERFORMANCE_ENDPOINT_REGRESSION: {
- return (
- <EventStatisticalDetectorRegressedPerformanceMessage
- event={event}
- group={group}
- />
- );
- }
- case IssueType.PROFILE_FUNCTION_REGRESSION_EXPERIMENTAL:
- case IssueType.PROFILE_FUNCTION_REGRESSION: {
- return (
- <EventStatisticalDetectorRegressedFunctionMessage event={event} group={group} />
- );
- }
- default: {
- return null;
- }
- }
- }
- function EventStatisticalDetectorRegressedPerformanceMessage({
- event,
- }: EventStatisticalDetectorMessageProps) {
- const now = useMemo(() => new Date(), []);
- const organization = useOrganization();
- const {transaction, breakpoint, aggregateRange1, aggregateRange2, trendPercentage} =
- event?.occurrence?.evidenceData ?? {};
- const {end: afterDateTime} = useRelativeDateTime({
- anchor: breakpoint,
- relativeDays: 14,
- });
- const transactionSummaryLink = transactionSummaryRouteWithQuery({
- orgSlug: organization.slug,
- transaction,
- query: {},
- trendFunction: 'p95',
- projectID: event.projectID,
- display: DisplayModes.TREND,
- });
- const detectionTime = new Date(breakpoint * 1000);
- return (
- <DataSection>
- <Message>
- <span>
- {tct(
- 'Based on the transaction [transactionName], there was a [absoluteChange] ([percentageAmount]) increase in duration (P95) from [previousDuration] to [regressionDuration] around [date] at [time]. Overall operation percentage changes indicate what may have changed in the regression.',
- {
- transactionName: (
- <Link to={normalizeUrl(transactionSummaryLink)}>{transaction}</Link>
- ),
- absoluteChange: (
- <PerformanceDuration
- abbreviation
- milliseconds={aggregateRange2 - aggregateRange1}
- />
- ),
- percentageAmount: formatPercentage(trendPercentage - 1),
- previousDuration: (
- <PerformanceDuration abbreviation milliseconds={aggregateRange1} />
- ),
- regressionDuration: (
- <PerformanceDuration abbreviation milliseconds={aggregateRange2} />
- ),
- date: <DateTime date={detectionTime} dateOnly />,
- time: <DateTime date={detectionTime} timeOnly />,
- }
- )}
- </span>
- {afterDateTime && now > afterDateTime && (
- <Tooltip
- title={t(
- 'The current date is over 14 days from the breakpoint. Open the Transaction Summary to see the most up to date transaction behaviour.'
- )}
- >
- <LinkButton to={transactionSummaryLink} size="xs" icon={<IconOpen />}>
- {t('Go to Summary')}
- </LinkButton>
- </Tooltip>
- )}
- </Message>
- </DataSection>
- );
- }
- const Message = styled('div')`
- display: flex;
- flex-direction: row;
- gap: ${space(1)};
- align-items: baseline;
- `;
- function EventStatisticalDetectorRegressedFunctionMessage({
- event,
- }: EventStatisticalDetectorMessageProps) {
- const evidenceData = event?.occurrence?.evidenceData;
- const absoluteChange = evidenceData?.trendDifference;
- const percentageChange = evidenceData?.trendPercentage;
- const detectionTime = new Date(evidenceData?.breakpoint * 1000);
- const functionName = evidenceData?.function as string;
- return (
- <DataSection>
- <div style={{display: 'inline'}}>
- {tct(
- '[functionName] had [change] in duration (P95) from [before] to [after] around [date] at [time]. The example profiles may indicate what changed in the regression.',
- {
- functionName: <code>{functionName}</code>,
- change:
- defined(absoluteChange) && defined(percentageChange)
- ? t(
- 'a %s (%s) increase',
- <PerformanceDuration abbreviation nanoseconds={absoluteChange} />,
- formatPercentage(percentageChange - 1)
- )
- : t('an increase'),
- before: (
- <PerformanceDuration
- abbreviation
- nanoseconds={evidenceData?.aggregateRange1 ?? 0}
- />
- ),
- after: (
- <PerformanceDuration
- abbreviation
- nanoseconds={evidenceData?.aggregateRange2 ?? 0}
- />
- ),
- date: <DateTime date={detectionTime} dateOnly />,
- time: <DateTime date={detectionTime} timeOnly />,
- }
- )}
- </div>
- </DataSection>
- );
- }
- export default EventStatisticalDetectorMessage;
|