Browse Source

feat(agg-spans): Send filter by http.method if exists (#58451)

With https://github.com/getsentry/sentry/pull/58443 agg spans endpoint
optionally
takes http method, sending that in the FE.
Also fixes a small bug where span samples might come up empty!
Shruthi 1 year ago
parent
commit
13680f02a3

+ 1 - 1
static/app/components/events/interfaces/spans/aggregateSpanDetail.tsx

@@ -32,7 +32,7 @@ function renderSpanSamples(span: AggregateSpanType, project: Project | undefined
     return null;
   }
 
-  return span.samples.map(([transactionId, spanId], index) => (
+  return span.samples?.map(([transactionId, spanId], index) => (
     <Link
       key={`${transactionId}-${spanId}`}
       to={`/performance/${project.slug}:${transactionId}#span-${spanId}`}

+ 11 - 3
static/app/components/events/interfaces/spans/aggregateSpans.tsx

@@ -35,13 +35,20 @@ type AggregateSpanRow = {
   start_ms: number;
 };
 
-export function useAggregateSpans({transaction}) {
+export function useAggregateSpans({
+  transaction,
+  httpMethod,
+}: {
+  transaction: string;
+  httpMethod?: string;
+}) {
   const organization = useOrganization();
   const {selection} = usePageFilters();
 
   const endpointOptions = {
     query: {
       transaction,
+      ...(defined(httpMethod) ? {'http.method': httpMethod} : null),
       project: selection.projects,
       environment: selection.environments,
       ...normalizeDateTimeParams(selection.datetime),
@@ -67,11 +74,12 @@ export function useAggregateSpans({transaction}) {
 
 type Props = {
   transaction: string;
+  httpMethod?: string;
 };
 
-export function AggregateSpans({transaction}: Props) {
+export function AggregateSpans({transaction, httpMethod}: Props) {
   const organization = useOrganization();
-  const {data, isLoading} = useAggregateSpans({transaction});
+  const {data, isLoading} = useAggregateSpans({transaction, httpMethod});
 
   const [isBannerOpen, setIsBannerOpen] = useLocalStorageState<boolean>(
     'aggregate-waterfall-info-banner',

+ 4 - 1
static/app/views/performance/transactionSummary/aggregateSpanWaterfall/index.tsx

@@ -27,6 +27,7 @@ function AggregateSpanWaterfall(): React.ReactElement {
   const projects = useProjects();
 
   const transaction = decodeScalar(location.query.transaction);
+  const httpMethod = decodeScalar(location.query['http.method']);
   return (
     <Feature
       features={['starfish-aggregate-span-waterfall']}
@@ -43,7 +44,9 @@ function AggregateSpanWaterfall(): React.ReactElement {
         childComponent={() => {
           return (
             <Layout.Main fullWidth>
-              {defined(transaction) && <AggregateSpans transaction={transaction} />}
+              {defined(transaction) && (
+                <AggregateSpans transaction={transaction} httpMethod={httpMethod} />
+              )}
             </Layout.Main>
           );
         }}

+ 14 - 0
static/app/views/performance/transactionSummary/aggregateSpanWaterfall/utils.tsx

@@ -1,5 +1,8 @@
 import {Query} from 'history';
 
+import {decodeScalar} from 'sentry/utils/queryString';
+import {MutableSearch} from 'sentry/utils/tokenizeSearch';
+
 export function aggregateWaterfallRouteWithQuery({
   orgSlug,
   transaction,
@@ -13,6 +16,16 @@ export function aggregateWaterfallRouteWithQuery({
 }) {
   const pathname = `/organizations/${orgSlug}/performance/summary/aggregateWaterfall/`;
 
+  const filter = decodeScalar(query.query);
+  let httpMethod: string | undefined = undefined;
+  if (filter) {
+    const search = new MutableSearch(filter);
+    const method = search.tokens.find(token => token.key === 'http.method');
+    if (method) {
+      httpMethod = method.value;
+    }
+  }
+
   return {
     pathname,
     query: {
@@ -23,6 +36,7 @@ export function aggregateWaterfallRouteWithQuery({
       start: query.start,
       end: query.end,
       query: query.query,
+      ...(httpMethod ? {'http.method': httpMethod} : null),
     },
   };
 }