Browse Source

feat(metrics): beta (#67100)

Ogi 11 months ago
parent
commit
58314f5b93

+ 2 - 2
static/app/components/events/interfaces/spans/newTraceDetailsSpanBar.tsx

@@ -54,7 +54,7 @@ import {EventOrGroupType} from 'sentry/types/event';
 import {defined} from 'sentry/utils';
 import {trackAnalytics} from 'sentry/utils/analytics';
 import {generateEventSlug} from 'sentry/utils/discover/urls';
-import {hasDDMExperimentalFeature} from 'sentry/utils/metrics/features';
+import {hasMetricsExperimentalFeature} from 'sentry/utils/metrics/features';
 import toPercent from 'sentry/utils/number/toPercent';
 import type {QuickTraceContextChildrenProps} from 'sentry/utils/performance/quickTrace/quickTraceContext';
 import type {
@@ -698,7 +698,7 @@ export class NewTraceDetailsSpanBar extends Component<
     const hasMetrics =
       '_metrics_summary' in span && Object.keys(span._metrics_summary ?? {}).length > 0;
 
-    return hasMetrics && hasDDMExperimentalFeature(this.props.organization) ? (
+    return hasMetrics && hasMetricsExperimentalFeature(this.props.organization) ? (
       <MetricsBadge />
     ) : null;
   }

+ 8 - 7
static/app/components/sidebar/index.tsx

@@ -43,6 +43,7 @@ import type {Organization} from 'sentry/types';
 import {isDemoWalkthrough} from 'sentry/utils/demoMode';
 import {getDiscoverLandingUrl} from 'sentry/utils/discover/urls';
 import {isActiveSuperuser} from 'sentry/utils/isActiveSuperuser';
+import {hasMetricsSidebarItem} from 'sentry/utils/metrics/features';
 import theme from 'sentry/utils/theme';
 import {useLocation} from 'sentry/utils/useLocation';
 import useMedia from 'sentry/utils/useMedia';
@@ -432,8 +433,8 @@ function Sidebar() {
     </Feature>
   );
 
-  const ddmPath = `/organizations/${organization?.slug}/ddm/`;
-  const ddm = hasOrganization && (
+  const metricsPath = `/organizations/${organization?.slug}/metrics/`;
+  const metrics = hasOrganization && hasMetricsSidebarItem(organization) && (
     <Feature
       features={['ddm-ui', 'custom-metrics']}
       organization={organization}
@@ -443,10 +444,10 @@ function Sidebar() {
         {...sidebarItemProps}
         icon={<IconGraph />}
         label={t('Metrics')}
-        to={ddmPath}
-        search={location.pathname === normalizeUrl(ddmPath) ? location.search : ''}
-        id="ddm"
-        isAlpha
+        to={metricsPath}
+        search={location.pathname === normalizeUrl(metricsPath) ? location.search : ''}
+        id="metrics"
+        isBeta
       />
     </Feature>
   );
@@ -530,7 +531,7 @@ function Sidebar() {
                 {performance}
                 {starfish}
                 {profiling}
-                {ddm}
+                {metrics}
                 {replays}
                 {feedback}
                 {monitors}

+ 13 - 5
static/app/routes.tsx

@@ -2044,10 +2044,18 @@ function buildRoutes() {
     </Route>
   );
 
-  const ddmRoutes = (
-    <Route path="/ddm/" component={make(() => import('sentry/views/ddm'))} withOrgPath>
-      <IndexRoute component={make(() => import('sentry/views/ddm/ddm'))} />
-    </Route>
+  const metricsRoutes = (
+    <Fragment>
+      <Route
+        path="/metrics/"
+        component={make(() => import('sentry/views/ddm'))}
+        withOrgPath
+      >
+        <IndexRoute component={make(() => import('sentry/views/ddm/ddm'))} />
+      </Route>
+      {/* TODO(ddm): fade this out */}
+      <Redirect from="/ddm/" to="/metrics/" />
+    </Fragment>
   );
 
   // Support for deprecated URLs (pre-Sentry 10). We just redirect users to new
@@ -2158,7 +2166,7 @@ function buildRoutes() {
       {performanceRoutes}
       {starfishRoutes}
       {profilingRoutes}
-      {ddmRoutes}
+      {metricsRoutes}
       {gettingStartedRoutes}
       {adminManageRoutes}
       {legacyOrganizationRootRoutes}

+ 11 - 3
static/app/utils/metrics/features.tsx

@@ -1,11 +1,11 @@
 import type {Organization} from 'sentry/types';
 import {Dataset} from 'sentry/views/alerts/rules/metric/types';
 
-export function hasDDMExperimentalFeature(organization: Organization) {
+export function hasMetricsExperimentalFeature(organization: Organization) {
   return organization.features.includes('ddm-experimental');
 }
 
-export function hasDDMFeature(organization: Organization) {
+export function hasMetricsUI(organization: Organization) {
   return organization.features.includes('ddm-ui');
 }
 
@@ -13,6 +13,14 @@ export function hasDashboardImportFeature(organization: Organization) {
   return organization.features.includes('ddm-dashboard-import');
 }
 
+export function hasMetricsSidebarItem(organization: Organization) {
+  return !organization.features.includes('ddm-sidebar-item-hidden');
+}
+
+export function hasCustomMetrics(organization: Organization) {
+  return hasMetricsUI(organization) && hasMetricsSidebarItem(organization);
+}
+
 /**
  * Returns the forceMetricsLayer query param for the alert
  * wrapped in an object so it can be spread into existing query params
@@ -23,7 +31,7 @@ export function getForceMetricsLayerQueryExtras(
   organization: Organization,
   alertDataset: Dataset
 ): {forceMetricsLayer: 'true'} | Record<string, never> {
-  return hasDDMFeature(organization) && alertDataset === Dataset.GENERIC_METRICS
+  return hasCustomMetrics(organization) && alertDataset === Dataset.GENERIC_METRICS
     ? {forceMetricsLayer: 'true'}
     : {};
 }

+ 3 - 2
static/app/views/alerts/rules/metric/ruleConditionsForm.tsx

@@ -25,7 +25,7 @@ import {t, tct} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import type {Environment, Organization, Project, SelectValue} from 'sentry/types';
 import {getDisplayName} from 'sentry/utils/environment';
-import {hasDDMFeature} from 'sentry/utils/metrics/features';
+import {hasCustomMetrics} from 'sentry/utils/metrics/features';
 import {getMRI} from 'sentry/utils/metrics/mri';
 import {getOnDemandKeys, isOnDemandQueryString} from 'sentry/utils/onDemandMetrics';
 import {hasOnDemandMetricAlertFeature} from 'sentry/utils/onDemandMetrics/features';
@@ -466,7 +466,8 @@ class RuleConditionsForm extends PureComponent<Props, State> {
                 flexibleControlStateSize
               >
                 {({onChange, onBlur, onKeyDown, initialData, value}) => {
-                  return hasDDMFeature(organization) && alertType === 'custom_metrics' ? (
+                  return hasCustomMetrics(organization) &&
+                    alertType === 'custom_metrics' ? (
                     <MetricSearchBar
                       mri={getMRI(aggregate)}
                       projectIds={[project.id]}

+ 2 - 2
static/app/views/alerts/rules/metric/ruleForm.tsx

@@ -37,7 +37,7 @@ import type EventView from 'sentry/utils/discover/eventView';
 import {AggregationKey} from 'sentry/utils/fields';
 import {
   getForceMetricsLayerQueryExtras,
-  hasDDMFeature,
+  hasCustomMetrics,
 } from 'sentry/utils/metrics/features';
 import {DEFAULT_METRIC_ALERT_FIELD, formatMRIField} from 'sentry/utils/metrics/mri';
 import {isOnDemandQueryString} from 'sentry/utils/onDemandMetrics';
@@ -1088,7 +1088,7 @@ class RuleFormContainer extends DeprecatedAsyncComponent<Props, State> {
               thresholdChart={wizardBuilderChart}
               onFilterSearch={this.handleFilterUpdate}
               allowChangeEventTypes={
-                hasDDMFeature(organization)
+                hasCustomMetrics(organization)
                   ? dataset === Dataset.ERRORS
                   : dataset === Dataset.ERRORS || alertType === 'custom_transactions'
               }

+ 5 - 5
static/app/views/alerts/rules/metric/wizardField.tsx

@@ -9,7 +9,7 @@ import {space} from 'sentry/styles/space';
 import type {Organization, Project} from 'sentry/types';
 import type {QueryFieldValue} from 'sentry/utils/discover/fields';
 import {explodeFieldString, generateFieldAsString} from 'sentry/utils/discover/fields';
-import {hasDDMFeature} from 'sentry/utils/metrics/features';
+import {hasCustomMetrics} from 'sentry/utils/metrics/features';
 import MriField from 'sentry/views/alerts/rules/metric/mriField';
 import type {Dataset} from 'sentry/views/alerts/rules/metric/types';
 import type {AlertType} from 'sentry/views/alerts/wizard/options';
@@ -107,7 +107,7 @@ export default function WizardField({
           label: AlertWizardAlertNames.cls,
           value: 'cls',
         },
-        ...(hasDDMFeature(organization)
+        ...(hasCustomMetrics(organization)
           ? [
               {
                 label: AlertWizardAlertNames.custom_transactions,
@@ -118,9 +118,9 @@ export default function WizardField({
       ],
     },
     {
-      label: hasDDMFeature(organization) ? t('METRICS') : t('CUSTOM'),
+      label: hasCustomMetrics(organization) ? t('METRICS') : t('CUSTOM'),
       options: [
-        hasDDMFeature(organization)
+        hasCustomMetrics(organization)
           ? {
               label: AlertWizardAlertNames.custom_metrics,
               value: 'custom_metrics',
@@ -181,7 +181,7 @@ export default function WizardField({
                 model.setValue('alertType', option.value);
               }}
             />
-            {hasDDMFeature(organization) && alertType === 'custom_metrics' ? (
+            {hasCustomMetrics(organization) && alertType === 'custom_metrics' ? (
               <MriField
                 project={project}
                 aggregate={aggregate}

+ 4 - 4
static/app/views/alerts/wizard/options.tsx

@@ -11,7 +11,7 @@ import {
   SpanOpBreakdown,
   WebVital,
 } from 'sentry/utils/fields';
-import {hasDDMFeature} from 'sentry/utils/metrics/features';
+import {hasCustomMetrics} from 'sentry/utils/metrics/features';
 import {DEFAULT_METRIC_ALERT_FIELD} from 'sentry/utils/metrics/mri';
 import {ON_DEMAND_METRICS_UNSUPPORTED_TAGS} from 'sentry/utils/onDemandMetrics/constants';
 import {shouldShowOnDemandMetricAlertUI} from 'sentry/utils/onDemandMetrics/features';
@@ -103,12 +103,12 @@ export const getAlertWizardCategories = (org: Organization): AlertWizardCategory
       'lcp',
       'fid',
       'cls',
-      ...(hasDDMFeature(org) ? (['custom_transactions'] satisfies AlertType[]) : []),
+      ...(hasCustomMetrics(org) ? (['custom_transactions'] satisfies AlertType[]) : []),
     ],
   },
   {
-    categoryHeading: hasDDMFeature(org) ? t('Metrics') : t('Custom'),
-    options: [hasDDMFeature(org) ? 'custom_metrics' : 'custom_transactions'],
+    categoryHeading: hasCustomMetrics(org) ? t('Metrics') : t('Custom'),
+    options: [hasCustomMetrics(org) ? 'custom_metrics' : 'custom_transactions'],
   },
 ];
 

+ 7 - 5
static/app/views/dashboards/addWidget.tsx

@@ -7,12 +7,13 @@ import {Button} from 'sentry/components/button';
 import DropdownButton from 'sentry/components/dropdownButton';
 import type {MenuItemProps} from 'sentry/components/dropdownMenu';
 import {DropdownMenu} from 'sentry/components/dropdownMenu';
+import FeatureBadge from 'sentry/components/featureBadge';
 import ExternalLink from 'sentry/components/links/externalLink';
 import {IconAdd} from 'sentry/icons';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import {trackAnalytics} from 'sentry/utils/analytics';
-import {hasDDMFeature} from 'sentry/utils/metrics/features';
+import {hasCustomMetrics} from 'sentry/utils/metrics/features';
 import useOrganization from 'sentry/utils/useOrganization';
 import {DataSet} from 'sentry/views/dashboards/widgetBuilder/utils';
 
@@ -62,7 +63,7 @@ function AddWidget({onAddWidget}: Props) {
         duration: 0.25,
       }}
     >
-      {hasDDMFeature(organization) ? (
+      {hasCustomMetrics(organization) ? (
         <InnerWrapper>
           <AddWidgetButton
             onAddWidget={onAddWidget}
@@ -109,8 +110,8 @@ export function AddWidgetButton({onAddWidget, ...buttonProps}: Props & ButtonPro
     [organization, onAddWidget]
   );
 
-  const items: MenuItemProps[] = useMemo(() => {
-    const menuItems = [
+  const items = useMemo(() => {
+    const menuItems: MenuItemProps[] = [
       {
         key: DataSet.EVENTS,
         label: t('Errors and Transactions'),
@@ -133,11 +134,12 @@ export function AddWidgetButton({onAddWidget, ...buttonProps}: Props & ButtonPro
       });
     }
 
-    if (hasDDMFeature(organization)) {
+    if (hasCustomMetrics(organization)) {
       menuItems.push({
         key: DataSet.METRICS,
         label: t('Custom Metrics'),
         onAction: () => handleAction(DataSet.METRICS),
+        trailingItems: <FeatureBadge type="beta" />,
       });
     }
 

+ 2 - 2
static/app/views/dashboards/controls.tsx

@@ -13,7 +13,7 @@ import {t, tct} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import type {Organization} from 'sentry/types';
 import {trackAnalytics} from 'sentry/utils/analytics';
-import {hasDDMFeature} from 'sentry/utils/metrics/features';
+import {hasCustomMetrics} from 'sentry/utils/metrics/features';
 import useOrganization from 'sentry/utils/useOrganization';
 import {AddWidgetButton} from 'sentry/views/dashboards/addWidget';
 import {DataSet} from 'sentry/views/dashboards/widgetBuilder/utils';
@@ -171,7 +171,7 @@ function Controls({
                 })}
                 disabled={!widgetLimitReached}
               >
-                {hasDDMFeature(organization) ? (
+                {hasCustomMetrics(organization) ? (
                   <AddWidgetButton
                     onAddWidget={onAddWidget}
                     aria-label="Add Widget"

Some files were not shown because too many files changed in this diff