Skip to content

Commit

Permalink
feat(ddm): 10s granularity support (getsentry#58581)
Browse files Browse the repository at this point in the history
  • Loading branch information
obostjancic authored Oct 23, 2023
1 parent 67e0775 commit 7b6bc75
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 13 deletions.
52 changes: 41 additions & 11 deletions static/app/utils/metrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import {useEffect, useMemo, useState} from 'react';
import {InjectedRouter} from 'react-router';
import moment from 'moment';

import {getInterval} from 'sentry/components/charts/utils';
import {ApiResult} from 'sentry/api';
import {
DateTimeObject,
getDiffInMinutes,
getInterval,
} from 'sentry/components/charts/utils';
import {t} from 'sentry/locale';
import {defined, formatBytesBase2, formatBytesBase10} from 'sentry/utils';
import {formatPercentage, getDuration} from 'sentry/utils/formatters';
Expand Down Expand Up @@ -134,7 +139,7 @@ export function useMetricsData({
const useCase = getUseCaseFromMri(mri);
const field = op ? `${op}(${mri})` : mri;

const interval = getInterval(datetime, 'metrics');
const interval = getMetricsInterval(datetime);

const queryToSend = {
...getDateTimeParams(datetime),
Expand All @@ -146,7 +151,6 @@ export function useMetricsData({
interval,
groupBy,
allowPrivate: true, // TODO(ddm): reconsider before widening audience

// max result groups
per_page: 20,
};
Expand All @@ -158,18 +162,27 @@ export function useMetricsData({
staleTime: 0,
refetchOnReconnect: true,
refetchOnWindowFocus: true,
// auto refetch every 60 seconds
refetchInterval: data => {
// don't refetch if the request failed
if (!data) {
return false;
}
return 60 * 1000;
},
refetchInterval: data => getRefetchInterval(data, interval),
}
);
}

function getRefetchInterval(
data: ApiResult | undefined,
interval: string
): number | false {
// no data means request failed - don't refetch
if (!data) {
return false;
}
if (interval === '10s') {
// refetch every 10 seconds
return 10 * 1000;
}
// refetch every 60 seconds
return 60 * 1000;
}

// Wraps useMetricsData and provides two additional features:
// 1. return data is undefined only during the initial load
// 2. provides a callback to trim the data to a specific time range when chart zoom is used
Expand Down Expand Up @@ -221,6 +234,23 @@ export function useMetricsDataZoom(props: MetricsQuery) {
};
}

// Wraps getInterval since other users of this function do not have support for 10s granularity
function getMetricsInterval(dateTimeObj: DateTimeObject) {
const interval = getInterval(dateTimeObj, 'metrics');

if (interval !== '1m') {
return interval;
}

const diffInMinutes = getDiffInMinutes(dateTimeObj);

if (diffInMinutes <= 60) {
return '10s';
}

return interval;
}

function getDateTimeParams({start, end, period}: PageFilters['datetime']) {
return period
? {statsPeriod: period}
Expand Down
21 changes: 19 additions & 2 deletions static/app/views/ddm/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export function MetricChart({

// TODO(ddm): This assumes that all series have the same bucket size
const bucketSize = seriesToShow[0]?.data[1]?.name - seriesToShow[0]?.data[0]?.name;
const isSubMinuteBucket = bucketSize < 60_000;
const seriesLength = seriesToShow[0]?.data.length;

const formatters = {
Expand All @@ -75,6 +76,7 @@ export function MetricChart({
isGroupedByDate: true,
bucketSize,
showTimeInTooltip: true,
addSecondsToTimeFormat: isSubMinuteBucket,
};
const displayFogOfWar = operation && ['sum', 'count'].includes(operation);

Expand Down Expand Up @@ -185,8 +187,7 @@ function FogOfWar({
return null;
}

// For smaller time frames we want to show a wider fog of war
const widthFactor = bucketSize > 30 * 60_000 ? 1 : 2;
const widthFactor = getWidthFactor(bucketSize);
const fogOfWarWidth = widthFactor * bucketSize + 30_000;

const seriesWidth = bucketSize * seriesLength;
Expand All @@ -201,6 +202,22 @@ function FogOfWar({
return <FogOfWarOverlay width={width ?? 0} />;
}

function getWidthFactor(bucketSize: number) {
// In general, fog of war should cover the last bucket
if (bucketSize > 30 * 60_000) {
return 1;
}

// for 10s timeframe we want to show a fog of war that spans last 10 buckets
// because on average, we are missing last 90 seconds of data
if (bucketSize <= 10_000) {
return 10;
}

// For smaller time frames we want to show a wider fog of war
return 2;
}

const ChartWrapper = styled('div')`
position: relative;
height: 300px;
Expand Down

0 comments on commit 7b6bc75

Please sign in to comment.