Просмотр исходного кода

feat(perf): expose N+1 DB Query count threshold in settings (#80247)

The N+1 DB Query performance issue has a threshold of 5 identical
queries before triggering. In #76835, we decided to make this user
configurable.

Expose the Minimum Query Count setting on the Performance settings
screen (where all the other configuratble thresholds already are). The
current default setting of 5 is the minimum, with options to increase it
to 10, 20, 50 or 100 queries.

Depends on the backend PR #80156.

Fixes #76835.
Matt Quinn 4 месяцев назад
Родитель
Сommit
363192f022

+ 19 - 10
static/app/views/settings/projectPerformance/projectPerformance.spec.tsx

@@ -14,6 +14,7 @@ import {
 import {IssueTitle} from 'sentry/types/group';
 import * as utils from 'sentry/utils/isActiveSuperuser';
 import ProjectPerformance, {
+  allowedCountValues,
   allowedDurationValues,
   allowedPercentageValues,
   allowedSizeValues,
@@ -191,13 +192,21 @@ describe('projectPerformance', function () {
       newValue: 500,
       sliderIndex: 1,
     },
+    {
+      title: IssueTitle.PERFORMANCE_N_PLUS_ONE_DB_QUERIES,
+      threshold: DetectorConfigCustomer.N_PLUS_DB_COUNT,
+      allowedValues: allowedCountValues,
+      defaultValue: 5,
+      newValue: 10,
+      sliderIndex: 2,
+    },
     {
       title: IssueTitle.PERFORMANCE_SLOW_DB_QUERY,
       threshold: DetectorConfigCustomer.SLOW_DB_DURATION,
       allowedValues: allowedDurationValues.slice(5),
       defaultValue: 1000,
       newValue: 3000,
-      sliderIndex: 2,
+      sliderIndex: 3,
     },
     {
       title: IssueTitle.PERFORMANCE_N_PLUS_ONE_API_CALLS,
@@ -205,7 +214,7 @@ describe('projectPerformance', function () {
       allowedValues: allowedDurationValues.slice(5),
       defaultValue: 300,
       newValue: 500,
-      sliderIndex: 3,
+      sliderIndex: 4,
     },
     {
       title: IssueTitle.PERFORMANCE_RENDER_BLOCKING_ASSET,
@@ -213,7 +222,7 @@ describe('projectPerformance', function () {
       allowedValues: allowedPercentageValues,
       defaultValue: 0.33,
       newValue: 0.5,
-      sliderIndex: 4,
+      sliderIndex: 5,
     },
     {
       title: IssueTitle.PERFORMANCE_LARGE_HTTP_PAYLOAD,
@@ -221,7 +230,7 @@ describe('projectPerformance', function () {
       allowedValues: allowedSizeValues.slice(1),
       defaultValue: 1000000,
       newValue: 5000000,
-      sliderIndex: 5,
+      sliderIndex: 6,
     },
     {
       title: IssueTitle.PERFORMANCE_DB_MAIN_THREAD,
@@ -229,7 +238,7 @@ describe('projectPerformance', function () {
       allowedValues: [10, 16, 33, 50],
       defaultValue: 16,
       newValue: 33,
-      sliderIndex: 6,
+      sliderIndex: 7,
     },
     {
       title: IssueTitle.PERFORMANCE_FILE_IO_MAIN_THREAD,
@@ -237,7 +246,7 @@ describe('projectPerformance', function () {
       allowedValues: [10, 16, 33, 50],
       defaultValue: 16,
       newValue: 50,
-      sliderIndex: 7,
+      sliderIndex: 8,
     },
     {
       title: IssueTitle.PERFORMANCE_CONSECUTIVE_DB_QUERIES,
@@ -245,7 +254,7 @@ describe('projectPerformance', function () {
       allowedValues: allowedDurationValues.slice(0, 23),
       defaultValue: 100,
       newValue: 5000,
-      sliderIndex: 8,
+      sliderIndex: 9,
     },
     {
       title: IssueTitle.PERFORMANCE_UNCOMPRESSED_ASSET,
@@ -253,7 +262,7 @@ describe('projectPerformance', function () {
       allowedValues: allowedSizeValues.slice(1),
       defaultValue: 512000,
       newValue: 700000,
-      sliderIndex: 9,
+      sliderIndex: 10,
     },
     {
       title: IssueTitle.PERFORMANCE_UNCOMPRESSED_ASSET,
@@ -261,7 +270,7 @@ describe('projectPerformance', function () {
       allowedValues: allowedDurationValues.slice(5),
       defaultValue: 500,
       newValue: 400,
-      sliderIndex: 10,
+      sliderIndex: 11,
     },
     {
       title: IssueTitle.PERFORMANCE_CONSECUTIVE_HTTP,
@@ -269,7 +278,7 @@ describe('projectPerformance', function () {
       allowedValues: allowedDurationValues.slice(14),
       defaultValue: 2000,
       newValue: 4000,
-      sliderIndex: 11,
+      sliderIndex: 12,
     },
   ])(
     'renders detector thresholds settings for $title issue',

+ 25 - 0
static/app/views/settings/projectPerformance/projectPerformance.tsx

@@ -59,6 +59,8 @@ export const allowedSizeValues: number[] = [
   10000000,
 ]; // 50kb to 10MB in bytes
 
+export const allowedCountValues: number[] = [5, 10, 20, 50, 100];
+
 export const projectDetectorSettingsId = 'detector-threshold-settings';
 
 type ProjectPerformanceSettings = {[key: string]: number | boolean};
@@ -82,6 +84,7 @@ enum DetectorConfigAdmin {
 export enum DetectorConfigCustomer {
   SLOW_DB_DURATION = 'slow_db_query_duration_threshold',
   N_PLUS_DB_DURATION = 'n_plus_one_db_duration_threshold',
+  N_PLUS_DB_COUNT = 'n_plus_one_db_count',
   N_PLUS_API_CALLS_DURATION = 'n_plus_one_api_calls_total_duration_threshold',
   RENDER_BLOCKING_ASSET_RATIO = 'render_blocking_fcp_ratio',
   LARGE_HTT_PAYLOAD_SIZE = 'large_http_payload_size_threshold',
@@ -511,6 +514,10 @@ class ProjectPerformance extends DeprecatedAsyncView<Props, State> {
       return fps ? `${Math.floor(fps / 5) * 5}fps` : '';
     };
 
+    const formatCount = (value: number | ''): string => {
+      return '' + value;
+    };
+
     const issueType = safeGetQsParam('issueType');
 
     return [
@@ -535,6 +542,24 @@ class ProjectPerformance extends DeprecatedAsyncView<Props, State> {
             flexibleControlStateSize: true,
             disabledReason,
           },
+          {
+            name: DetectorConfigCustomer.N_PLUS_DB_COUNT,
+            type: 'range',
+            label: t('Minimum Query Count'),
+            defaultValue: 5,
+            help: t(
+              'Setting the value to 5 means that an eligible event will be detected as an N+1 DB Query Issue only if the number of repeated queries exceeds 5'
+            ),
+            allowedValues: allowedCountValues,
+            disabled: !(
+              hasAccess && performanceSettings[DetectorConfigAdmin.N_PLUS_DB_ENABLED]
+            ),
+            tickValues: [0, allowedCountValues.length - 1],
+            showTickLabels: true,
+            formatLabel: formatCount,
+            flexibleControlStateSize: true,
+            disabledReason,
+          },
         ],
         initiallyCollapsed: issueType !== IssueType.PERFORMANCE_N_PLUS_ONE_DB_QUERIES,
       },