Skip to content

Commit d20e51d

Browse files
authored
feat(perf-views) Add release markers to duration breakdown (#18484)
Add release markers to the release breakdown chart. This will help with diagnosing performance changes related to releases. I've moved decodeScalar() out of the eventsv2 views directory as it is used in other view paths as well.
1 parent 328b925 commit d20e51d

File tree

9 files changed

+64
-39
lines changed

9 files changed

+64
-39
lines changed

src/sentry/static/sentry/app/utils/discover/eventView.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import {SavedQuery, NewQuery, SelectValue, User} from 'app/types';
1313
import {getParams} from 'app/components/organizations/globalSelectionHeader/getParams';
1414
import {COL_WIDTH_UNDEFINED} from 'app/components/gridEditable';
1515
import {TableColumn, TableColumnSort} from 'app/views/eventsV2/table/types';
16-
import {decodeColumnOrder, decodeScalar} from 'app/views/eventsV2/utils';
16+
import {decodeColumnOrder} from 'app/views/eventsV2/utils';
17+
import {decodeScalar} from 'app/utils/queryString';
1718

1819
import {
1920
Sort,

src/sentry/static/sentry/app/utils/queryString.tsx

+16
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,23 @@ export function appendTagCondition(
5656
return currentQuery;
5757
}
5858

59+
export function decodeScalar(
60+
value: string[] | string | undefined | null
61+
): string | undefined {
62+
if (!value) {
63+
return undefined;
64+
}
65+
const unwrapped =
66+
Array.isArray(value) && value.length > 0
67+
? value[0]
68+
: isString(value)
69+
? value
70+
: undefined;
71+
return isString(unwrapped) ? unwrapped : undefined;
72+
}
73+
5974
export default {
75+
decodeScalar,
6076
formatQueryString,
6177
addQueryParamsToExistingUrl,
6278
appendTagCondition,

src/sentry/static/sentry/app/views/eventsV2/landing.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ import localStorage from 'app/utils/localStorage';
2525
import space from 'app/styles/space';
2626
import withOrganization from 'app/utils/withOrganization';
2727
import EventView from 'app/utils/discover/eventView';
28+
import {decodeScalar} from 'app/utils/queryString';
2829

2930
import {DEFAULT_EVENT_VIEW} from './data';
30-
import {getPrebuiltQueries, decodeScalar} from './utils';
31+
import {getPrebuiltQueries} from './utils';
3132
import QueryList from './queryList';
3233
import backgroundSpace from '../../../images/spot/background-space.svg';
3334

src/sentry/static/sentry/app/views/eventsV2/utils.tsx

-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import Papa from 'papaparse';
2-
import isString from 'lodash/isString';
32
import {Location, Query} from 'history';
43
import {browserHistory} from 'react-router';
54

@@ -121,21 +120,6 @@ export function getPrebuiltQueries(organization: Organization) {
121120
return views;
122121
}
123122

124-
export function decodeScalar(
125-
value: string[] | string | undefined | null
126-
): string | undefined {
127-
if (!value) {
128-
return undefined;
129-
}
130-
const unwrapped =
131-
Array.isArray(value) && value.length > 0
132-
? value[0]
133-
: isString(value)
134-
? value
135-
: undefined;
136-
return isString(unwrapped) ? unwrapped : undefined;
137-
}
138-
139123
export function downloadAsCsv(tableData, columnOrder, filename) {
140124
const {data} = tableData;
141125
const headings = columnOrder.map(column => column.name);

src/sentry/static/sentry/app/views/performance/data.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {Location} from 'history';
33
import {t} from 'app/locale';
44
import {NewQuery} from 'app/types';
55
import EventView from 'app/utils/discover/eventView';
6-
import {decodeScalar} from 'app/views/eventsV2/utils';
6+
import {decodeScalar} from 'app/utils/queryString';
77
import {stringifyQueryObject} from 'app/utils/tokenizeSearch';
88

99
export const DEFAULT_STATS_PERIOD = '24h';

src/sentry/static/sentry/app/views/performance/table.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import EventView, {MetaType, EventData} from 'app/utils/discover/eventView';
1414
import SortLink from 'app/views/eventsV2/sortLink';
1515
import {TableData, TableDataRow, TableColumn} from 'app/views/eventsV2/table/types';
1616
import HeaderCell from 'app/views/eventsV2/table/headerCell';
17-
import {decodeScalar} from 'app/views/eventsV2/utils';
17+
import {decodeScalar} from 'app/utils/queryString';
1818
import withProjects from 'app/utils/withProjects';
1919
import SearchBar from 'app/components/searchBar';
2020
import DiscoverQuery from 'app/utils/discover/discoverQuery';

src/sentry/static/sentry/app/views/performance/transactionSummary/durationChart.tsx

+25-18
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ import ChartZoom from 'app/components/charts/chartZoom';
1010
import ErrorPanel from 'app/components/charts/components/errorPanel';
1111
import TransparentLoadingMask from 'app/components/charts/components/transparentLoadingMask';
1212
import TransitionChart from 'app/components/charts/transitionChart';
13+
import ReleaseSeries from 'app/components/charts/releaseSeries';
1314
import {AREA_COLORS, getInterval} from 'app/components/charts/utils';
1415
import {IconWarning} from 'app/icons';
1516
import EventsRequest from 'app/views/events/utils/eventsRequest';
1617
import {getUtcToLocalDateObject} from 'app/utils/dates';
1718
import EventView from 'app/utils/discover/eventView';
1819
import withApi from 'app/utils/withApi';
20+
import {decodeScalar} from 'app/utils/queryString';
1921
import theme from 'app/utils/theme';
2022
import {getDuration} from 'app/utils/formatters';
2123

@@ -61,6 +63,7 @@ class DurationChart extends React.Component<Props> {
6163
: undefined;
6264

6365
const end = this.props.end ? getUtcToLocalDateObject(this.props.end) : undefined;
66+
const utc = decodeScalar(router.location.query.utc);
6467

6568
const legend = {
6669
right: 16,
@@ -152,24 +155,28 @@ class DurationChart extends React.Component<Props> {
152155
: [];
153156

154157
return (
155-
<TransitionChart loading={loading} reloading={reloading}>
156-
<TransparentLoadingMask visible={reloading} />
157-
<AreaChart
158-
{...zoomRenderProps}
159-
legend={legend}
160-
series={series}
161-
seriesOptions={{
162-
showSymbol: false,
163-
}}
164-
tooltip={tooltip}
165-
grid={{
166-
left: '24px',
167-
right: '24px',
168-
top: '32px',
169-
bottom: '12px',
170-
}}
171-
/>
172-
</TransitionChart>
158+
<ReleaseSeries utc={utc} api={api} projects={project}>
159+
{({releaseSeries}) => (
160+
<TransitionChart loading={loading} reloading={reloading}>
161+
<TransparentLoadingMask visible={reloading} />
162+
<AreaChart
163+
{...zoomRenderProps}
164+
legend={legend}
165+
series={[...series, ...releaseSeries]}
166+
seriesOptions={{
167+
showSymbol: false,
168+
}}
169+
tooltip={tooltip}
170+
grid={{
171+
left: '24px',
172+
right: '24px',
173+
top: '32px',
174+
bottom: '12px',
175+
}}
176+
/>
177+
</TransitionChart>
178+
)}
179+
</ReleaseSeries>
173180
);
174181
}}
175182
</EventsRequest>

src/sentry/static/sentry/app/views/performance/transactionSummary/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
1515
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
1616
import {PageContent} from 'app/styles/organization';
1717
import EventView, {isAPIPayloadSimilar} from 'app/utils/discover/eventView';
18-
import {decodeScalar} from 'app/views/eventsV2/utils';
18+
import {decodeScalar} from 'app/utils/queryString';
1919
import {stringifyQueryObject} from 'app/utils/tokenizeSearch';
2020
import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
2121
import withApi from 'app/utils/withApi';

tests/js/spec/utils/queryString.spec.js

+16
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,19 @@ describe('appendTagCondition', function() {
7070
expect(result).toEqual('user.name:"jill jones"');
7171
});
7272
});
73+
74+
describe('decodeScalar()', function() {
75+
it('unwraps array values', function() {
76+
expect(utils.decodeScalar(['one', 'two'])).toEqual('one');
77+
});
78+
79+
it('handles strings', function() {
80+
expect(utils.decodeScalar('one')).toEqual('one');
81+
});
82+
83+
it('handles falsey values', function() {
84+
expect(utils.decodeScalar(undefined)).toBeUndefined();
85+
expect(utils.decodeScalar(false)).toBeUndefined();
86+
expect(utils.decodeScalar('')).toBeUndefined();
87+
});
88+
});

0 commit comments

Comments
 (0)