Browse Source

feat(ddm-performance): Add experimental metrics badge (#64353)

Rename "custom metrics" to "measurements".
Add experimental badge to indicate metrics on a span / transaction
(behind feature flag).

- closes https://github.com/getsentry/sentry/issues/64031
ArthurKnaus 1 year ago
parent
commit
4819e774b0

+ 12 - 0
static/app/components/events/interfaces/spans/newTraceDetailsSpanBar.tsx

@@ -24,6 +24,7 @@ import {
   DividerLine,
   DividerLineGhostContainer,
   ErrorBadge,
+  MetricsBadge,
   ProfileBadge,
 } from 'sentry/components/performance/waterfall/rowDivider';
 import {
@@ -53,6 +54,7 @@ import {EventOrGroupType} from 'sentry/types/event';
 import {defined} from 'sentry/utils';
 import {trackAnalytics} from 'sentry/utils/analytics';
 import {generateEventSlug} from 'sentry/utils/discover/urls';
+import {hasDDMExperimentalFeature} from 'sentry/utils/metrics/features';
 import toPercent from 'sentry/utils/number/toPercent';
 import type {QuickTraceContextChildrenProps} from 'sentry/utils/performance/quickTrace/quickTraceContext';
 import type {
@@ -692,6 +694,15 @@ export class NewTraceDetailsSpanBar extends Component<
     return errors?.length ? <ErrorBadge /> : null;
   }
 
+  renderMetricsBadge(span: NewTraceDetailsSpanBarProps['span']): React.ReactNode {
+    const hasMetrics =
+      '_metrics_summary' in span && Object.keys(span._metrics_summary ?? {}).length > 0;
+
+    return hasMetrics && hasDDMExperimentalFeature(this.props.organization) ? (
+      <MetricsBadge />
+    ) : null;
+  }
+
   renderEmbeddedTransactionsBadge(
     transactions: QuickTraceEvent[] | null
   ): React.ReactNode {
@@ -857,6 +868,7 @@ export class NewTraceDetailsSpanBar extends Component<
         </RowCell>
         <DividerContainer>
           {this.renderDivider(dividerHandlerChildrenProps)}
+          {this.renderMetricsBadge(this.props.span)}
           {this.renderErrorBadge(errors)}
           {this.renderEmbeddedTransactionsBadge(transactions)}
           {this.renderMissingInstrumentationProfileBadge()}

+ 9 - 1
static/app/components/performance/waterfall/rowDivider.tsx

@@ -1,6 +1,6 @@
 import styled from '@emotion/styled';
 
-import {IconAdd, IconFire, IconProfiling, IconSubtract} from 'sentry/icons';
+import {IconAdd, IconFire, IconGraph, IconProfiling, IconSubtract} from 'sentry/icons';
 import {space} from 'sentry/styles/space';
 import type {Aliases, Color} from 'sentry/utils/theme';
 
@@ -75,6 +75,14 @@ export function ErrorBadge() {
   );
 }
 
+export function MetricsBadge() {
+  return (
+    <BadgeBorder color="pink400">
+      <IconGraph color="pink400" size="xs" />
+    </BadgeBorder>
+  );
+}
+
 export function EmbeddedTransactionBadge({
   inTraceView = false,
   expanded,

+ 1 - 1
static/app/utils/analytics/ddmAnalyticsEvents.tsx

@@ -26,7 +26,7 @@ export type DDMEventParameters = {
 
 export const ddmEventMap: Record<keyof DDMEventParameters, string> = {
   'ddm.page-view': 'DDM: Page View',
-  'ddm.remove-default-query': 'DDM: Set Default Query',
+  'ddm.remove-default-query': 'DDM: Remove Default Query',
   'ddm.set-default-query': 'DDM: Set Default Query',
   'ddm.open-onboarding': 'DDM: Open Onboarding',
   'ddm.widget.add': 'DDM: Widget Added',

+ 19 - 0
static/app/views/performance/traceDetails/newTraceDetailsTransactionBar.tsx

@@ -38,6 +38,7 @@ import {
   DividerLine,
   DividerLineGhostContainer,
   ErrorBadge,
+  MetricsBadge,
 } from 'sentry/components/performance/waterfall/rowDivider';
 import {
   RowTitle,
@@ -64,6 +65,7 @@ import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import type {EventTransaction, Organization} from 'sentry/types';
 import {defined} from 'sentry/utils';
+import {hasDDMExperimentalFeature} from 'sentry/utils/metrics/features';
 import toPercent from 'sentry/utils/number/toPercent';
 import QuickTraceQuery from 'sentry/utils/performance/quickTrace/quickTraceQuery';
 import type {
@@ -770,6 +772,22 @@ function NewTraceDetailsTransactionBar(props: Props) {
     return <ErrorBadge />;
   };
 
+  const renderMetricsBadge = () => {
+    const {organization} = props;
+    const hasMetrics = Object.keys(embeddedChildren?._metrics_summary ?? {}).length > 0;
+
+    if (
+      !hasDDMExperimentalFeature(organization) ||
+      isTraceRoot(transaction) ||
+      isTraceError(transaction) ||
+      !hasMetrics
+    ) {
+      return null;
+    }
+
+    return <MetricsBadge />;
+  };
+
   const renderRectangle = () => {
     const {transaction, traceInfo, barColor} = props;
 
@@ -801,6 +819,7 @@ function NewTraceDetailsTransactionBar(props: Props) {
           <ErrorBadge />
         ) : (
           <Fragment>
+            {renderMetricsBadge()}
             {renderErrorBadge()}
             <DurationPill
               durationDisplay={getDurationDisplay({

+ 1 - 1
static/app/views/performance/traceDetails/traceViewDetailPanel.tsx

@@ -405,7 +405,7 @@ function EventDetails({detail, organization, location}: EventDetailProps) {
 
           {measurementNames.length > 0 && (
             <tr>
-              <td className="key">{t('Custom Metrics')}</td>
+              <td className="key">{t('Measurements')}</td>
               <td className="value">
                 <Measurements>
                   {measurementNames.map(name => {