|
@@ -7,33 +7,32 @@ import {defined} from 'sentry/utils';
|
|
|
import {tooltipFormatterUsingAggregateOutputType} from 'sentry/utils/discover/charts';
|
|
|
import EventView from 'sentry/utils/discover/eventView';
|
|
|
import {DiscoverDatasets} from 'sentry/utils/discover/types';
|
|
|
+import {formatVersion} from 'sentry/utils/formatters';
|
|
|
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
|
|
|
import usePageFilters from 'sentry/utils/usePageFilters';
|
|
|
+import {RELEASE_COMPARISON} from 'sentry/views/starfish/colours';
|
|
|
import Chart from 'sentry/views/starfish/components/chart';
|
|
|
import MiniChartPanel from 'sentry/views/starfish/components/miniChartPanel';
|
|
|
import {useReleaseSelection} from 'sentry/views/starfish/queries/useReleases';
|
|
|
import {STARFISH_CHART_INTERVAL_FIDELITY} from 'sentry/views/starfish/utils/constants';
|
|
|
import {appendReleaseFilters} from 'sentry/views/starfish/utils/releaseComparison';
|
|
|
import {useEventsStatsQuery} from 'sentry/views/starfish/utils/useEventsStatsQuery';
|
|
|
-import {
|
|
|
- COLD_START_COLOR,
|
|
|
- WARM_START_COLOR,
|
|
|
-} from 'sentry/views/starfish/views/appStartup/screenSummary/appStartBreakdownWidget';
|
|
|
-import {OUTPUT_TYPE, YAxis} from 'sentry/views/starfish/views/screens';
|
|
|
|
|
|
-const SPAN_OP_TO_STRING = {
|
|
|
- 'app.start.cold': t('Cold Start'),
|
|
|
- 'app.start.warm': t('Warm Start'),
|
|
|
-};
|
|
|
+const COLD_START_CONDITIONS = ['span.op:app.start.cold', 'span.description:"Cold Start"'];
|
|
|
+const WARM_START_CONDITIONS = ['span.op:app.start.warm', 'span.description:"Warm Start"'];
|
|
|
|
|
|
-function transformData(data?: MultiSeriesEventsStats) {
|
|
|
- const transformedSeries: {[yAxisName: string]: Series} = {};
|
|
|
+export function transformData(data?: MultiSeriesEventsStats, primaryRelease?: string) {
|
|
|
+ const transformedSeries: {[releaseName: string]: Series} = {};
|
|
|
if (defined(data)) {
|
|
|
- Object.keys(data).forEach(yAxis => {
|
|
|
- transformedSeries[yAxis] = {
|
|
|
- seriesName: yAxis,
|
|
|
+ Object.keys(data).forEach(releaseName => {
|
|
|
+ transformedSeries[releaseName] = {
|
|
|
+ seriesName: releaseName,
|
|
|
+ color:
|
|
|
+ releaseName === primaryRelease
|
|
|
+ ? RELEASE_COMPARISON.PRIMARY_RELEASE_COLOR
|
|
|
+ : RELEASE_COMPARISON.SECONDARY_RELEASE_COLOR,
|
|
|
data:
|
|
|
- data[yAxis]?.data.map(datum => {
|
|
|
+ data[releaseName]?.data?.map(datum => {
|
|
|
return {
|
|
|
name: datum[0] * 1000,
|
|
|
value: datum[1][0].count,
|
|
@@ -47,10 +46,11 @@ function transformData(data?: MultiSeriesEventsStats) {
|
|
|
|
|
|
interface Props {
|
|
|
chartHeight: number;
|
|
|
+ type: 'cold' | 'warm';
|
|
|
additionalFilters?: string[];
|
|
|
}
|
|
|
|
|
|
-function CountWidget({additionalFilters, chartHeight}: Props) {
|
|
|
+function StartDurationWidget({additionalFilters, chartHeight, type}: Props) {
|
|
|
const pageFilter = usePageFilters();
|
|
|
const {
|
|
|
primaryRelease,
|
|
@@ -59,14 +59,10 @@ function CountWidget({additionalFilters, chartHeight}: Props) {
|
|
|
} = useReleaseSelection();
|
|
|
|
|
|
const query = new MutableSearch([
|
|
|
- 'span.op:[app.start.warm,app.start.cold]',
|
|
|
+ ...(type === 'cold' ? COLD_START_CONDITIONS : WARM_START_CONDITIONS),
|
|
|
...(additionalFilters ?? []),
|
|
|
]);
|
|
|
- const queryString = `${appendReleaseFilters(
|
|
|
- query,
|
|
|
- primaryRelease,
|
|
|
- secondaryRelease
|
|
|
- )} span.description:["Cold Start","Warm Start"]`;
|
|
|
+ const queryString = appendReleaseFilters(query, primaryRelease, secondaryRelease);
|
|
|
|
|
|
const {
|
|
|
data: series,
|
|
@@ -77,8 +73,8 @@ function CountWidget({additionalFilters, chartHeight}: Props) {
|
|
|
{
|
|
|
name: '',
|
|
|
topEvents: '2',
|
|
|
- fields: ['span.op', 'count()'],
|
|
|
- yAxis: ['count()'],
|
|
|
+ fields: ['release', 'avg(span.duration)'],
|
|
|
+ yAxis: ['avg(span.duration)'],
|
|
|
query: queryString,
|
|
|
dataset: DiscoverDatasets.SPANS_METRICS,
|
|
|
version: 2,
|
|
@@ -98,13 +94,24 @@ function CountWidget({additionalFilters, chartHeight}: Props) {
|
|
|
return <LoadingContainer isLoading />;
|
|
|
}
|
|
|
|
|
|
- const transformedSeries = transformData(series);
|
|
|
+ // The expected response is a multi series response, but if there is no data
|
|
|
+ // then we get an object representing a single series with all empty values
|
|
|
+ // (i.e without being grouped by release)
|
|
|
+ const hasReleaseData = series && !('data' in series);
|
|
|
+
|
|
|
+ // Only transform the data is we know there's at least one release
|
|
|
+ const transformedSeries = hasReleaseData
|
|
|
+ ? Object.values(transformData(series, primaryRelease)).sort()
|
|
|
+ : [];
|
|
|
|
|
|
return (
|
|
|
- <MiniChartPanel title={t('Count')}>
|
|
|
+ <MiniChartPanel
|
|
|
+ title={
|
|
|
+ type === 'cold' ? t('Avg. Cold Start Duration') : t('Avg. Warm Start Duration')
|
|
|
+ }
|
|
|
+ >
|
|
|
<Chart
|
|
|
- chartColors={[COLD_START_COLOR, WARM_START_COLOR]}
|
|
|
- data={Object.values(transformedSeries)}
|
|
|
+ data={transformedSeries}
|
|
|
height={chartHeight}
|
|
|
loading={isSeriesLoading}
|
|
|
grid={{
|
|
@@ -116,17 +123,17 @@ function CountWidget({additionalFilters, chartHeight}: Props) {
|
|
|
showLegend
|
|
|
definedAxisTicks={2}
|
|
|
isLineChart
|
|
|
- aggregateOutputFormat={OUTPUT_TYPE[YAxis.COUNT]}
|
|
|
+ aggregateOutputFormat="duration"
|
|
|
tooltipFormatterOptions={{
|
|
|
valueFormatter: value =>
|
|
|
- tooltipFormatterUsingAggregateOutputType(value, OUTPUT_TYPE[YAxis.COUNT]),
|
|
|
- nameFormatter: value => SPAN_OP_TO_STRING[value],
|
|
|
+ tooltipFormatterUsingAggregateOutputType(value, 'duration'),
|
|
|
+ nameFormatter: value => formatVersion(value),
|
|
|
}}
|
|
|
- legendFormatter={value => SPAN_OP_TO_STRING[value]}
|
|
|
+ legendFormatter={value => formatVersion(value)}
|
|
|
errored={isError}
|
|
|
/>
|
|
|
</MiniChartPanel>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
-export default CountWidget;
|
|
|
+export default StartDurationWidget;
|