Skip to content

ref(insights): Refactor cache- + queues- page widgets #89344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 6 additions & 35 deletions static/app/views/insights/cache/views/cacheLandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ import {
} from 'sentry/views/insights/cache/components/tables/transactionsTable';
import {Referrer} from 'sentry/views/insights/cache/referrers';
import {BASE_FILTERS, MODULE_DOC_LINK} from 'sentry/views/insights/cache/settings';
import {InsightsLineChartWidget} from 'sentry/views/insights/common/components/insightsLineChartWidget';
import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout';
import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modulePageFilterBar';
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
import {ModulesOnboarding} from 'sentry/views/insights/common/components/modulesOnboarding';
import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper';
import CacheMissRateChartWidget from 'sentry/views/insights/common/components/widgets/cacheMissRateChartWidget';
import CacheThroughputChartWidget from 'sentry/views/insights/common/components/widgets/cacheThroughputChartWidget';
import {
useMetrics,
useSpanMetrics,
Expand All @@ -37,10 +38,6 @@ import {useOnboardingProject} from 'sentry/views/insights/common/queries/useOnbo
import {useInsightsEap} from 'sentry/views/insights/common/utils/useEap';
import {useSamplesDrawer} from 'sentry/views/insights/common/utils/useSamplesDrawer';
import {QueryParameterNames} from 'sentry/views/insights/common/views/queryParameters';
import {
DataTitles,
getThroughputChartTitle,
} from 'sentry/views/insights/common/views/spans/types';
import {BackendHeader} from 'sentry/views/insights/pages/backend/backendPageHeader';
import {
type MetricsProperty,
Expand Down Expand Up @@ -81,11 +78,7 @@ export function CacheLandingPage() {
requiredParams: ['transaction'],
});

const {
isPending: isCacheMissRateLoading,
data: cacheMissRateData,
error: cacheMissRateError,
} = useSpanMetricsSeries(
const {error: cacheMissRateError} = useSpanMetricsSeries(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dupe request because of error handling :'(

{
yAxis: [`${CACHE_MISS_RATE}()`],
search: MutableSearch.fromQueryObject(BASE_FILTERS),
Expand All @@ -94,19 +87,6 @@ export function CacheLandingPage() {
Referrer.LANDING_CACHE_HIT_MISS_CHART
);

const {
isPending: isThroughputDataLoading,
data: throughputData,
error: throughputError,
} = useSpanMetricsSeries(
{
search: MutableSearch.fromQueryObject(BASE_FILTERS),
yAxis: ['epm()'],
transformAliasToInputFormat: true,
},
Referrer.LANDING_CACHE_THROUGHPUT_CHART
);

const {
isFetching: isTransactionsListFetching,
data: transactionsList,
Expand Down Expand Up @@ -160,6 +140,7 @@ export function CacheLandingPage() {
const hasData = useHasFirstSpan(ModuleName.CACHE);

useEffect(() => {
// TODO: EAP does not use an indexer, so these metrics indexer errors are not possible. When EAP is fully rolled out, remove this check.
const hasMissingDataError =
cacheMissRateError?.message === CACHE_ERROR_MESSAGE ||
transactionsListError?.message === CACHE_ERROR_MESSAGE;
Expand Down Expand Up @@ -211,20 +192,10 @@ export function CacheLandingPage() {
</ModuleLayout.Full>
<ModulesOnboarding moduleName={ModuleName.CACHE}>
<ModuleLayout.Half>
<InsightsLineChartWidget
title={DataTitles[`cache_miss_rate()`]}
series={[cacheMissRateData[`${CACHE_MISS_RATE}()`]]}
isLoading={isCacheMissRateLoading}
error={cacheMissRateError}
/>
<CacheMissRateChartWidget />
</ModuleLayout.Half>
<ModuleLayout.Half>
<InsightsLineChartWidget
title={getThroughputChartTitle('cache.get_item')}
series={[throughputData['epm()']]}
isLoading={isThroughputDataLoading}
error={throughputError}
/>
<CacheThroughputChartWidget />
</ModuleLayout.Half>
<ModuleLayout.Full>
<TransactionsTable
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {Referrer} from 'sentry/views/insights/cache/referrers';
import {BASE_FILTERS} from 'sentry/views/insights/cache/settings';
import {InsightsLineChartWidget} from 'sentry/views/insights/common/components/insightsLineChartWidget';
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
import {useSpanMetricsSeries} from 'sentry/views/insights/common/queries/useDiscoverSeries';
import {DataTitles} from 'sentry/views/insights/common/views/spans/types';
import {SpanFunction} from 'sentry/views/insights/types';

const {CACHE_MISS_RATE} = SpanFunction;

export default function CacheMissRateChartWidget(props: LoadableChartWidgetProps) {
const {isPending, data, error} = useSpanMetricsSeries(
{
yAxis: [`${CACHE_MISS_RATE}()`],
search: MutableSearch.fromQueryObject(BASE_FILTERS),
transformAliasToInputFormat: true,
},
Referrer.LANDING_CACHE_HIT_MISS_CHART,
props.pageFilters
);

return (
<InsightsLineChartWidget
{...props}
id="cacheMissRateChartWidget"
title={DataTitles[`cache_miss_rate()`]}
series={[data[`${CACHE_MISS_RATE}()`]]}
isLoading={isPending}
error={error}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {Referrer} from 'sentry/views/insights/cache/referrers';
import {BASE_FILTERS} from 'sentry/views/insights/cache/settings';
import {InsightsLineChartWidget} from 'sentry/views/insights/common/components/insightsLineChartWidget';
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
import {useSpanMetricsSeries} from 'sentry/views/insights/common/queries/useDiscoverSeries';
import {getThroughputChartTitle} from 'sentry/views/insights/common/views/spans/types';

export default function CacheThroughputChartWidget(props: LoadableChartWidgetProps) {
const {isPending, data, error} = useSpanMetricsSeries(
{
search: MutableSearch.fromQueryObject(BASE_FILTERS),
yAxis: ['epm()'],
transformAliasToInputFormat: true,
},
Referrer.LANDING_CACHE_THROUGHPUT_CHART,
props.pageFilters
);

return (
<InsightsLineChartWidget
{...props}
id="cacheThroughputChartWidget"
title={getThroughputChartTitle('cache.get_item')}
series={[data['epm()']]}
isLoading={isPending}
error={error}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
import {LatencyChart} from 'sentry/views/insights/queues/charts/latencyChart';
import {Referrer} from 'sentry/views/insights/queues/referrers';

export default function QueuesLandingLatencyChartWidget(props: LoadableChartWidgetProps) {
return (
<LatencyChart
{...props}
id="queuesLandingLatencyChartWidget"
referrer={Referrer.QUEUES_LANDING_CHARTS}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
import {ThroughputChart} from 'sentry/views/insights/queues/charts/throughputChart';
import {Referrer} from 'sentry/views/insights/queues/referrers';

export default function QueuesLandingThroughputChartWidget(
props: LoadableChartWidgetProps
) {
return (
<ThroughputChart
{...props}
id="queuesLandingThroughputChartWidget"
referrer={Referrer.QUEUES_LANDING_CHARTS}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {decodeScalar} from 'sentry/utils/queryString';
import useLocationQuery from 'sentry/utils/url/useLocationQuery';
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
import {LatencyChart} from 'sentry/views/insights/queues/charts/latencyChart';
import {Referrer} from 'sentry/views/insights/queues/referrers';

export default function QueuesSummaryLatencyChartWidget(props: LoadableChartWidgetProps) {
const {destination} = useLocationQuery({
fields: {
destination: decodeScalar,
},
});
Comment on lines +8 to +12
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does mean that if this chart were rendered via the drawer, it needs to be on the Queues Summary Page (or have destination in query params). It's an optional param but I wonder if we want to be more strict about it?

We have a similar situation with the resources charts, it uses groupId url parameter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe! I think this is okay for now, though.


return (
<LatencyChart
{...props}
id="queuesSummaryLatencyChartWidget"
referrer={Referrer.QUEUES_SUMMARY_CHARTS}
destination={destination}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {decodeScalar} from 'sentry/utils/queryString';
import useLocationQuery from 'sentry/utils/url/useLocationQuery';
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
import {ThroughputChart} from 'sentry/views/insights/queues/charts/throughputChart';
import {Referrer} from 'sentry/views/insights/queues/referrers';

export default function QueuesSummaryThroughputChartWidget(
props: LoadableChartWidgetProps
) {
const {destination} = useLocationQuery({
fields: {
destination: decodeScalar,
},
});

return (
<ThroughputChart
{...props}
id="queuesSummaryThroughputChartWidget"
referrer={Referrer.QUEUES_SUMMARY_CHARTS}
destination={destination}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ describe('latencyChart', () => {
});
it('renders', async () => {
render(
<LatencyChart destination="events" referrer={Referrer.QUEUES_SUMMARY_CHARTS} />,
<LatencyChart
id="latency-chart-test"
destination="events"
referrer={Referrer.QUEUES_SUMMARY_CHARTS}
/>,
{organization}
);
screen.getByText('Average Duration');
Expand Down
7 changes: 6 additions & 1 deletion static/app/views/insights/queues/charts/latencyChart.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import cloneDeep from 'lodash/cloneDeep';

import {t} from 'sentry/locale';
import type {PageFilters} from 'sentry/types/core';
import {defined} from 'sentry/utils';
import {InsightsAreaChartWidget} from 'sentry/views/insights/common/components/insightsAreaChartWidget';
import {useProcessQueuesTimeSeriesQuery} from 'sentry/views/insights/queues/queries/useProcessQueuesTimeSeriesQuery';
import type {Referrer} from 'sentry/views/insights/queues/referrers';
import {FIELD_ALIASES} from 'sentry/views/insights/queues/settings';

interface Props {
id: string;
referrer: Referrer;
destination?: string;
error?: Error | null;
pageFilters?: PageFilters;
}

export function LatencyChart({error, destination, referrer}: Props) {
export function LatencyChart({id, error, destination, referrer, pageFilters}: Props) {
const {
data,
isPending,
error: latencyError,
} = useProcessQueuesTimeSeriesQuery({
destination,
referrer,
pageFilters,
});

const messageReceiveLatencySeries = cloneDeep(
Expand Down Expand Up @@ -51,6 +55,7 @@ export function LatencyChart({error, destination, referrer}: Props) {

return (
<InsightsAreaChartWidget
id={id}
title={t('Average Duration')}
series={[messageReceiveLatencySeries, data['avg(span.duration)']]}
aliases={FIELD_ALIASES}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ describe('throughputChart', () => {
});
});
it('renders', async () => {
render(<ThroughputChart referrer={Referrer.QUEUES_SUMMARY_CHARTS} />, {organization});
render(
<ThroughputChart
id="throughput-chart-test"
referrer={Referrer.QUEUES_SUMMARY_CHARTS}
/>,
{organization}
);
screen.getByText('Published vs Processed');
expect(eventsStatsMock).toHaveBeenCalledWith(
'/organizations/org-slug/events-stats/',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {useTheme} from '@emotion/react';

import {t} from 'sentry/locale';
import type {PageFilters} from 'sentry/types/core';
import {InsightsLineChartWidget} from 'sentry/views/insights/common/components/insightsLineChartWidget';
import {renameDiscoverSeries} from 'sentry/views/insights/common/utils/renameDiscoverSeries';
import {useProcessQueuesTimeSeriesQuery} from 'sentry/views/insights/queues/queries/useProcessQueuesTimeSeriesQuery';
Expand All @@ -9,12 +10,14 @@ import type {Referrer} from 'sentry/views/insights/queues/referrers';
import {FIELD_ALIASES} from 'sentry/views/insights/queues/settings';

interface Props {
id: string;
referrer: Referrer;
destination?: string;
error?: Error | null;
pageFilters?: PageFilters;
}

export function ThroughputChart({error, destination, referrer}: Props) {
export function ThroughputChart({id, error, destination, pageFilters, referrer}: Props) {
const theme = useTheme();
const {
data: publishData,
Expand All @@ -23,6 +26,7 @@ export function ThroughputChart({error, destination, referrer}: Props) {
} = usePublishQueuesTimeSeriesQuery({
destination,
referrer,
pageFilters,
});

const {
Expand All @@ -32,10 +36,12 @@ export function ThroughputChart({error, destination, referrer}: Props) {
} = useProcessQueuesTimeSeriesQuery({
destination,
referrer,
pageFilters,
});

return (
<InsightsLineChartWidget
id={id}
title={t('Published vs Processed')}
series={[
renameDiscoverSeries(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type {PageFilters} from 'sentry/types/core';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useSpanMetricsSeries} from 'sentry/views/insights/common/queries/useDiscoverSeries';
import type {Referrer} from 'sentry/views/insights/queues/referrers';
Expand All @@ -7,6 +8,7 @@ type Props = {
referrer: Referrer;
destination?: string;
enabled?: boolean;
pageFilters?: PageFilters;
};

const yAxis: SpanMetricsProperty[] = [
Expand All @@ -15,7 +17,12 @@ const yAxis: SpanMetricsProperty[] = [
'epm()',
];

export function useProcessQueuesTimeSeriesQuery({enabled, destination, referrer}: Props) {
export function useProcessQueuesTimeSeriesQuery({
enabled,
destination,
referrer,
pageFilters,
}: Props) {
const search = new MutableSearch('span.op:queue.process');
if (destination) {
search.addFilterValue('messaging.destination.name', destination, false);
Expand All @@ -28,6 +35,7 @@ export function useProcessQueuesTimeSeriesQuery({enabled, destination, referrer}
enabled,
transformAliasToInputFormat: true,
},
referrer
referrer,
pageFilters
);
}
Loading
Loading