Browse Source

chore(dashboards): Remove support for session.duration (#43127)

Remove references to session.duration in Release widgets in Dashboards.
This also displays a banner on pre-existing widgets that reference
session duration warning users that their data might be incomplete.

<img width="431" alt="Screen Shot 2023-01-11 at 11 59 42 PM"
src="https://user-images.githubusercontent.com/63818634/211981259-0e5d1ff8-7616-4c50-b130-3daf473b493c.png">
Shruthi 2 years ago
parent
commit
b3a15b9b0b

+ 5 - 0
static/app/components/modals/widgetViewerModal.tsx

@@ -59,6 +59,7 @@ import {
   getWidgetIssueUrl,
   getWidgetReleasesUrl,
 } from 'sentry/views/dashboardsV2/utils';
+import {SESSION_DURATION_ALERT} from 'sentry/views/dashboardsV2/widgetCard';
 import WidgetCardChart, {
   AugmentedEChartDataZoomHandler,
   SLIDER_HEIGHT,
@@ -176,6 +177,9 @@ function WidgetViewerModal(props: Props) {
   const start = decodeScalar(location.query[WidgetViewerQueryField.START]);
   const end = decodeScalar(location.query[WidgetViewerQueryField.END]);
   const isTableWidget = widget.displayType === DisplayType.TABLE;
+  const hasSessionDuration = widget.queries.some(query =>
+    query.aggregates.some(aggregate => aggregate.includes('session.duration'))
+  );
   const locationPageFilter = useMemo(
     () =>
       start && end
@@ -791,6 +795,7 @@ function WidgetViewerModal(props: Props) {
   function renderWidgetViewer() {
     return (
       <Fragment>
+        {hasSessionDuration && SESSION_DURATION_ALERT}
         {widget.displayType !== DisplayType.TABLE && (
           <Container
             height={

+ 0 - 6
static/app/types/sessions.tsx

@@ -19,12 +19,6 @@ export enum SessionField {
 export type SessionsOperation =
   | 'sum'
   | 'count_unique'
-  | 'avg'
-  | 'max'
-  | 'p50'
-  | 'p75'
-  | 'p95'
-  | 'p99'
   | 'crash_rate'
   | 'crash_free_rate'
   | 'count_abnormal'

+ 0 - 102
static/app/views/dashboardsV2/widgetBuilder/releaseWidget/fields.spec.tsx

@@ -39,23 +39,6 @@ describe('generateReleaseWidgetFieldOptions', function () {
           },
         },
       },
-      'function:avg': {
-        label: 'avg(…)',
-        value: {
-          kind: 'function',
-          meta: {
-            name: 'avg',
-            parameters: [
-              {
-                columnTypes: ['duration'],
-                defaultValue: 'session.duration',
-                kind: 'column',
-                required: true,
-              },
-            ],
-          },
-        },
-      },
       'function:count_abnormal': {
         label: 'count_abnormal(…)',
         value: {
@@ -175,91 +158,6 @@ describe('generateReleaseWidgetFieldOptions', function () {
           },
         },
       },
-      'function:max': {
-        label: 'max(…)',
-        value: {
-          kind: 'function',
-          meta: {
-            name: 'max',
-            parameters: [
-              {
-                columnTypes: ['duration'],
-                defaultValue: 'session.duration',
-                kind: 'column',
-                required: true,
-              },
-            ],
-          },
-        },
-      },
-      'function:p50': {
-        label: 'p50(…)',
-        value: {
-          kind: 'function',
-          meta: {
-            name: 'p50',
-            parameters: [
-              {
-                columnTypes: ['duration'],
-                defaultValue: 'session.duration',
-                kind: 'column',
-                required: true,
-              },
-            ],
-          },
-        },
-      },
-      'function:p75': {
-        label: 'p75(…)',
-        value: {
-          kind: 'function',
-          meta: {
-            name: 'p75',
-            parameters: [
-              {
-                columnTypes: ['duration'],
-                defaultValue: 'session.duration',
-                kind: 'column',
-                required: true,
-              },
-            ],
-          },
-        },
-      },
-      'function:p95': {
-        label: 'p95(…)',
-        value: {
-          kind: 'function',
-          meta: {
-            name: 'p95',
-            parameters: [
-              {
-                columnTypes: ['duration'],
-                defaultValue: 'session.duration',
-                kind: 'column',
-                required: true,
-              },
-            ],
-          },
-        },
-      },
-      'function:p99': {
-        label: 'p99(…)',
-        value: {
-          kind: 'function',
-          meta: {
-            name: 'p99',
-            parameters: [
-              {
-                columnTypes: ['duration'],
-                defaultValue: 'session.duration',
-                kind: 'column',
-                required: true,
-              },
-            ],
-          },
-        },
-      },
       'function:sum': {
         label: 'sum(…)',
         value: {

+ 1 - 73
static/app/views/dashboardsV2/widgetBuilder/releaseWidget/fields.tsx

@@ -41,12 +41,6 @@ export const FIELD_TO_METRICS_EXPRESSION = {
   'crash_free_rate(user)': SessionMetric.USER_CRASH_FREE_RATE,
   'crash_rate(session)': SessionMetric.SESSION_CRASH_RATE,
   'crash_rate(user)': SessionMetric.USER_CRASH_RATE,
-  'avg(session.duration)': `avg(${SessionMetric.SESSION_DURATION})`,
-  'max(session.duration)': `max(${SessionMetric.SESSION_DURATION})`,
-  'p50(session.duration)': `p50(${SessionMetric.SESSION_DURATION})`,
-  'p75(session.duration)': `p75(${SessionMetric.SESSION_DURATION})`,
-  'p95(session.duration)': `p95(${SessionMetric.SESSION_DURATION})`,
-  'p99(session.duration)': `p99(${SessionMetric.SESSION_DURATION})`,
   project: 'project_id',
 };
 
@@ -91,7 +85,7 @@ export const SESSIONS_FIELDS: Readonly<Partial<Record<SessionField, SessionsMeta
   },
   [SessionField.SESSION_DURATION]: {
     name: 'session.duration',
-    operations: ['avg', 'p50', 'p75', 'p95', 'p99', 'max'],
+    operations: [],
     type: 'duration',
   },
 };
@@ -187,72 +181,6 @@ export const SESSIONS_OPERATIONS: Readonly<
       },
     ],
   },
-  avg: {
-    outputType: null,
-    parameters: [
-      {
-        kind: 'column',
-        columnTypes: ['duration'],
-        defaultValue: SessionField.SESSION_DURATION,
-        required: true,
-      },
-    ],
-  },
-  max: {
-    outputType: null,
-    parameters: [
-      {
-        kind: 'column',
-        columnTypes: ['duration'],
-        defaultValue: SessionField.SESSION_DURATION,
-        required: true,
-      },
-    ],
-  },
-  p50: {
-    outputType: null,
-    parameters: [
-      {
-        kind: 'column',
-        columnTypes: ['duration'],
-        defaultValue: SessionField.SESSION_DURATION,
-        required: true,
-      },
-    ],
-  },
-  p75: {
-    outputType: null,
-    parameters: [
-      {
-        kind: 'column',
-        columnTypes: ['duration'],
-        defaultValue: SessionField.SESSION_DURATION,
-        required: true,
-      },
-    ],
-  },
-  p95: {
-    outputType: null,
-    parameters: [
-      {
-        kind: 'column',
-        columnTypes: ['duration'],
-        defaultValue: SessionField.SESSION_DURATION,
-        required: true,
-      },
-    ],
-  },
-  p99: {
-    outputType: null,
-    parameters: [
-      {
-        kind: 'column',
-        columnTypes: ['duration'],
-        defaultValue: SessionField.SESSION_DURATION,
-        required: true,
-      },
-    ],
-  },
 };
 
 export const SESSIONS_TAGS = ['environment', 'project', 'release', 'session.status'];

+ 17 - 1
static/app/views/dashboardsV2/widgetCard/index.tsx

@@ -12,7 +12,7 @@ import ErrorPanel from 'sentry/components/charts/errorPanel';
 import {HeaderTitle} from 'sentry/components/charts/styles';
 import ErrorBoundary from 'sentry/components/errorBoundary';
 import ExternalLink from 'sentry/components/links/externalLink';
-import {Panel} from 'sentry/components/panels';
+import {Panel, PanelAlert} from 'sentry/components/panels';
 import Placeholder from 'sentry/components/placeholder';
 import {parseSearch} from 'sentry/components/searchSyntax/parser';
 import Tooltip from 'sentry/components/tooltip';
@@ -21,6 +21,7 @@ import {t, tct} from 'sentry/locale';
 import space from 'sentry/styles/space';
 import {Organization, PageFilters} from 'sentry/types';
 import {Series} from 'sentry/types/echarts';
+import {getFormattedDate} from 'sentry/utils/dates';
 import {TableDataWithTitle} from 'sentry/utils/discover/discoverQuery';
 import {AggregationOutputType, parseFunction} from 'sentry/utils/discover/fields';
 import {
@@ -41,6 +42,16 @@ import {DashboardsMEPConsumer, DashboardsMEPProvider} from './dashboardsMEPConte
 import WidgetCardChartContainer from './widgetCardChartContainer';
 import WidgetCardContextMenu from './widgetCardContextMenu';
 
+const SESSION_DURATION_INGESTION_STOP_DATE = new Date('2023-01-12');
+export const SESSION_DURATION_ALERT = (
+  <PanelAlert type="warning">
+    {t(
+      'session.duration is no longer being recorded as of %s. Data in this widget may be incomplete.',
+      getFormattedDate(SESSION_DURATION_INGESTION_STOP_DATE, 'MMM D, YYYY')
+    )}
+  </PanelAlert>
+);
+
 type DraggableProps = Pick<ReturnType<typeof useSortable>, 'attributes' | 'listeners'>;
 
 type Props = WithRouterProps & {
@@ -246,6 +257,10 @@ class WidgetCard extends Component<Props, State> {
       widget.limit = DEFAULT_RESULTS_LIMIT;
     }
 
+    const hasSessionDuration = widget.queries.some(query =>
+      query.aggregates.some(aggregate => aggregate.includes('session.duration'))
+    );
+
     function conditionalWrapWithDashboardsMEPProvider(component: React.ReactNode) {
       if (noDashboardsMEPProvider) {
         return component;
@@ -282,6 +297,7 @@ class WidgetCard extends Component<Props, State> {
                 </Tooltip>
                 {this.renderContextMenu()}
               </WidgetHeader>
+              {hasSessionDuration && SESSION_DURATION_ALERT}
               {isWidgetInvalid ? (
                 <Fragment>
                   {renderErrorMessage?.('Widget query condition is invalid.')}