Browse Source

feat(new-trace): Displaying emmitted metrics with new ui. (#70864)

Before:
<img width="1510" alt="Screenshot 2024-05-14 at 12 23 22 PM"
src="https://github.com/getsentry/sentry/assets/60121741/eefe8b7b-b06e-4f5b-9ce4-495b0184becb">

After: 
<img width="1508" alt="Screenshot 2024-05-14 at 12 23 00 PM"
src="https://github.com/getsentry/sentry/assets/60121741/8031d795-9d64-4851-a34e-cb5bb1d96061">

---------

Co-authored-by: Abdullah Khan <abdullahkhan@PG9Y57YDXQ.local>
Abdkhan14 10 months ago
parent
commit
3d98e12f2d

+ 52 - 0
static/app/views/metrics/customMetricsEventData.tsx

@@ -4,6 +4,7 @@ import styled from '@emotion/styled';
 
 import MarkLine from 'sentry/components/charts/components/markLine';
 import ScatterSeries from 'sentry/components/charts/series/scatterSeries';
+import {useHasNewTagsUI} from 'sentry/components/events/eventTags/util';
 import type {
   MetricsSummary,
   MetricsSummaryItem,
@@ -36,6 +37,11 @@ import type {Series} from 'sentry/views/metrics/chart/types';
 import {getChartTimeseries} from 'sentry/views/metrics/widget';
 import {getSampleChartSymbol} from 'sentry/views/starfish/views/spanSummaryPage/sampleList/durationChart/getSampleChartSymbol';
 
+import {
+  type SectionCardKeyValueList,
+  TraceDrawerComponents,
+} from '../performance/newTraceDetails/traceDrawer/details/styles';
+
 function flattenMetricsSummary(
   metricsSummary: MetricsSummary
 ): {item: MetricsSummaryItem; mri: MRI}[] {
@@ -76,6 +82,7 @@ export function CustomMetricsEventData({
   startTimestamp: number;
   metricsSummary?: MetricsSummary;
 }) {
+  const hasNewTagsUI = useHasNewTagsUI();
   const organization = useOrganization();
   const start = new Date(startTimestamp * 1000 - HALF_HOUR_IN_MS).toISOString();
   const end = new Date(startTimestamp * 1000 + HALF_HOUR_IN_MS).toISOString();
@@ -180,6 +187,51 @@ export function CustomMetricsEventData({
     return null;
   }
 
+  if (hasNewTagsUI) {
+    const items: SectionCardKeyValueList = [];
+
+    dataRows.forEach(dataRow => {
+      const {mri, summaryItem} = dataRow;
+      const name = formatMRI(mri);
+      items.push({
+        key: `metric-${name}`,
+        subject: name,
+        value: (
+          <TraceDrawerComponents.CopyableCardValueWithLink
+            value={
+              <Fragment>
+                <ValueRenderer dataRow={dataRow} />{' '}
+                <DeviationRenderer dataRow={dataRow} startTimestamp={startTimestamp} />
+                <br />
+                <TagsRenderer tags={dataRow.summaryItem.tags} />
+              </Fragment>
+            }
+            linkText={t('View Metric')}
+            linkTarget={getMetricsUrl(organization.slug, {
+              start: normalizeDateTimeString(start),
+              end: normalizeDateTimeString(end),
+              interval: '10s',
+              widgets: [
+                {
+                  mri: mri,
+                  displayType: MetricDisplayType.LINE,
+                  op: getDefaultMetricOp(mri),
+                  query: Object.entries(summaryItem.tags ?? {})
+                    .map(([tagKey, tagValue]) => tagToQuery(tagKey, tagValue))
+                    .join(' '),
+                },
+              ],
+            })}
+          />
+        ),
+      });
+    });
+
+    return (
+      <TraceDrawerComponents.SectionCard title={t('Emitted Metrics')} items={items} />
+    );
+  }
+
   return (
     <table className="table key-value">
       <tbody>

+ 1 - 1
static/app/views/performance/newTraceDetails/index.tsx

@@ -56,7 +56,6 @@ import {
   loadTraceViewPreferences,
   storeTraceViewPreferences,
 } from 'sentry/views/performance/newTraceDetails/traceState/tracePreferences';
-import {TraceType} from 'sentry/views/performance/traceDetails/newTraceDetailsContent';
 
 import {useTrace} from './traceApi/useTrace';
 import {useTraceMeta} from './traceApi/useTraceMeta';
@@ -69,6 +68,7 @@ import {isTraceNode} from './guards';
 import {Trace} from './trace';
 import {TraceMetadataHeader} from './traceMetadataHeader';
 import {TraceReducer, type TraceReducerState} from './traceState';
+import {TraceType} from './traceType';
 import {TraceUXChangeAlert} from './traceUXChangeBanner';
 import {useTraceQueryParamStateSync} from './useTraceQueryParamStateSync';
 

+ 2 - 1
static/app/views/performance/newTraceDetails/traceAnalytics.tsx

@@ -2,7 +2,8 @@ import * as Sentry from '@sentry/react';
 
 import type {Organization} from 'sentry/types/organization';
 import {trackAnalytics} from 'sentry/utils/analytics';
-import type {TraceType} from 'sentry/views/performance/traceDetails/newTraceDetailsContent';
+
+import type {TraceType} from './traceType';
 
 const trackTraceShape = (shape: TraceType, organization: Organization) => {
   Sentry.metrics.increment(`trace.trace_shape.${shape}`);

+ 1 - 1
static/app/views/performance/newTraceDetails/traceDrawer/details/error.tsx

@@ -59,7 +59,7 @@ export function ErrorNodeDetails({
     {
       key: 'title',
       subject: t('Title'),
-      value: <TraceDrawerComponents.CardValueWithCopy value={node.value.title} />,
+      value: <TraceDrawerComponents.CopyableCardValueWithLink value={node.value.title} />,
     },
   ];
 

+ 1 - 1
static/app/views/performance/newTraceDetails/traceDrawer/details/missingInstrumentation.tsx

@@ -55,7 +55,7 @@ export function MissingInstrumentationNodeDetails({
       key: 'profile_id',
       subject: 'Profile ID',
       value: (
-        <TraceDrawerComponents.CardValueWithCopy
+        <TraceDrawerComponents.CopyableCardValueWithLink
           value={profileId}
           linkTarget={generateProfileFlamechartRouteWithQuery({
             orgSlug: organization.slug,

+ 7 - 7
static/app/views/performance/newTraceDetails/traceDrawer/details/span/index.tsx

@@ -124,14 +124,14 @@ export function SpanNodeDetails({
                   <SpanHTTPInfo span={node.value} />
                   <Tags span={node.value} />
                   <SpanKeys node={node} />
+                  {node.value._metrics_summary ? (
+                    <CustomMetricsEventData
+                      projectId={project?.id || ''}
+                      metricsSummary={node.value._metrics_summary}
+                      startTimestamp={node.value.start_timestamp}
+                    />
+                  ) : null}
                 </TraceDrawerComponents.SectionCardGroup>
-                {node.value._metrics_summary ? (
-                  <CustomMetricsEventData
-                    projectId={project?.id || ''}
-                    metricsSummary={node.value._metrics_summary}
-                    startTimestamp={node.value.start_timestamp}
-                  />
-                ) : null}
                 <EventContexts event={event} />
                 {organization.features.includes('profiling') ? (
                   <SpanProfileDetails span={node.value} event={event} />

+ 2 - 2
static/app/views/performance/newTraceDetails/traceDrawer/details/span/sections/generalInfo.tsx

@@ -80,7 +80,7 @@ export function GeneralInfo(props: GeneralnfoProps) {
       subject: t('Description'),
       value:
         span.op && span.hash ? (
-          <TraceDrawerComponents.CardValueWithCopy
+          <TraceDrawerComponents.CopyableCardValueWithLink
             value={span.description}
             linkTarget={spanDetailsRouteWithQuery({
               orgSlug: props.organization.slug,
@@ -92,7 +92,7 @@ export function GeneralInfo(props: GeneralnfoProps) {
             linkText={t('View Similar Spans')}
           />
         ) : (
-          <TraceDrawerComponents.CardValueWithCopy value={span.description} />
+          <TraceDrawerComponents.CopyableCardValueWithLink value={span.description} />
         ),
     });
   }

+ 11 - 4
static/app/views/performance/newTraceDetails/traceDrawer/details/styles.tsx

@@ -649,12 +649,12 @@ const CardsColumn = styled('div')`
   grid-column: span 1;
 `;
 
-function CardValueWithCopy({
+function CopyableCardValueWithLink({
   value,
   linkTarget,
   linkText,
 }: {
-  value: string;
+  value: React.ReactNode;
   linkTarget?: LocationDescriptor;
   linkText?: string;
 }) {
@@ -662,7 +662,14 @@ function CardValueWithCopy({
     <CardValueContainer>
       <CardValueText>
         {value}
-        <StyledCopyToClipboardButton borderless size="zero" iconSize="xs" text={value} />
+        {typeof value === 'string' ? (
+          <StyledCopyToClipboardButton
+            borderless
+            size="zero"
+            iconSize="xs"
+            text={value}
+          />
+        ) : null}
       </CardValueText>
       {linkTarget && linkTarget ? <Link to={linkTarget}>{linkText}</Link> : null}
     </CardValueContainer>
@@ -749,7 +756,7 @@ const TraceDrawerComponents = {
   TableValueRow,
   IssuesLink,
   SectionCard,
-  CardValueWithCopy,
+  CopyableCardValueWithLink,
   EventTags,
   SectionCardGroup,
 };

+ 7 - 8
static/app/views/performance/newTraceDetails/traceDrawer/details/transaction/index.tsx

@@ -135,6 +135,13 @@ export function TransactionNodeDetails({
         <AdditionalData event={event} />
         <Measurements event={event} location={location} organization={organization} />
         <Sdk event={event} />
+        {event._metrics_summary ? (
+          <CustomMetricsEventData
+            metricsSummary={event._metrics_summary}
+            startTimestamp={event.startTimestamp}
+            projectId={event.projectID}
+          />
+        ) : null}
       </TraceDrawerComponents.SectionCardGroup>
 
       <Request event={event} />
@@ -157,14 +164,6 @@ export function TransactionNodeDetails({
 
       {project ? <EventEvidence event={event} project={project} /> : null}
 
-      {event._metrics_summary ? (
-        <CustomMetricsEventData
-          metricsSummary={event._metrics_summary}
-          startTimestamp={event.startTimestamp}
-          projectId={event.projectID}
-        />
-      ) : null}
-
       <ReplayPreview event={event} organization={organization} />
 
       <BreadCrumbs event={event} organization={organization} />

+ 1 - 1
static/app/views/performance/newTraceDetails/traceDrawer/details/transaction/sections/generalInfo.tsx

@@ -133,7 +133,7 @@ function GeneralInfo({
     key: 'description',
     subject: t('Description'),
     value: (
-      <TraceDrawerComponents.CardValueWithCopy
+      <TraceDrawerComponents.CopyableCardValueWithLink
         value={node.value.transaction}
         linkTarget={transactionSummaryRouteWithQuery({
           orgSlug: organization.slug,

Some files were not shown because too many files changed in this diff