Skip to content

Commit 2828729

Browse files
authored
fix(aci): Display correct resolution threshold (#103409)
was always grabbing high threshold and not displaying resolution threshold when customized <img width="370" height="102" alt="image" src="https://github.com/user-attachments/assets/12a759ad-b0a7-41d3-956e-751504c01ce7" />
1 parent 8f0e5df commit 2828729

File tree

4 files changed

+81
-5
lines changed

4 files changed

+81
-5
lines changed

static/app/views/detectors/components/details/metric/sidebar.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ function DetectorResolve({detector}: {detector: MetricDetector}) {
9090
const mainCondition = conditions.find(
9191
condition => condition.conditionResult !== DetectorPriorityLevel.OK
9292
);
93+
94+
// Get the OK condition (resolution condition)
95+
const okCondition = conditions.find(
96+
condition => condition.conditionResult === DetectorPriorityLevel.OK
97+
);
98+
9399
const thresholdSuffix = getMetricDetectorSuffix(
94100
detector.config?.detectionType || 'static',
95101
detector.dataSources[0].queryObj?.snubaQuery?.aggregate || 'count()'
@@ -102,6 +108,8 @@ function DetectorResolve({detector}: {detector: MetricDetector}) {
102108
typeof mainCondition?.comparison === 'number'
103109
? mainCondition.comparison
104110
: undefined,
111+
resolutionThreshold:
112+
typeof okCondition?.comparison === 'number' ? okCondition.comparison : undefined,
105113
comparisonDelta: (detector.config as any)?.comparison_delta,
106114
thresholdSuffix,
107115
});

static/app/views/detectors/components/forms/metric/resolveSection.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ export function ResolveSection() {
6262
const highThreshold = useMetricDetectorFormField(
6363
METRIC_DETECTOR_FORM_FIELDS.highThreshold
6464
);
65+
const mediumThreshold = useMetricDetectorFormField(
66+
METRIC_DETECTOR_FORM_FIELDS.mediumThreshold
67+
);
6568
const conditionType = useMetricDetectorFormField(
6669
METRIC_DETECTOR_FORM_FIELDS.conditionType
6770
);
@@ -81,12 +84,17 @@ export function ResolveSection() {
8184

8285
const thresholdSuffix = getStaticDetectorThresholdSuffix(aggregate);
8386

87+
// Compute the automatic resolution threshold: medium if present, otherwise high
88+
const resolutionThreshold =
89+
mediumThreshold && mediumThreshold !== '' ? mediumThreshold : highThreshold || 0;
90+
8491
const descriptionContent = getResolutionDescription(
8592
detectionType === 'percent'
8693
? {
8794
detectionType: 'percent',
8895
conditionType,
8996
highThreshold: highThreshold || 0,
97+
resolutionThreshold,
9098
comparisonDelta: conditionComparisonAgo ?? 3600, // Default to 1 hour if not set
9199
thresholdSuffix,
92100
}
@@ -95,6 +103,7 @@ export function ResolveSection() {
95103
detectionType: 'static',
96104
conditionType,
97105
highThreshold: highThreshold || 0,
106+
resolutionThreshold,
98107
thresholdSuffix,
99108
}
100109
: {

static/app/views/detectors/utils/getDetectorResolutionDescription.spec.tsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ describe('getDetectorResolutionDescription', () => {
2121
detectionType: 'static',
2222
conditionType: DataConditionType.GREATER,
2323
highThreshold: 100,
24+
resolutionThreshold: undefined,
2425
thresholdSuffix: '%',
2526
});
2627

@@ -34,6 +35,7 @@ describe('getDetectorResolutionDescription', () => {
3435
detectionType: 'static',
3536
conditionType: DataConditionType.LESS,
3637
highThreshold: 50,
38+
resolutionThreshold: undefined,
3739
thresholdSuffix: 'ms',
3840
});
3941

@@ -47,13 +49,42 @@ describe('getDetectorResolutionDescription', () => {
4749
detectionType: 'static',
4850
conditionType: DataConditionType.GREATER,
4951
highThreshold: 100,
52+
resolutionThreshold: undefined,
5053
thresholdSuffix: '',
5154
});
5255

5356
expect(result).toBe(
5457
'Issue will be resolved when the query value is less than 100.'
5558
);
5659
});
60+
61+
it('uses resolutionThreshold instead of highThreshold when provided for GREATER condition', () => {
62+
const result = getResolutionDescription({
63+
detectionType: 'static',
64+
conditionType: DataConditionType.GREATER,
65+
highThreshold: 100,
66+
resolutionThreshold: 75,
67+
thresholdSuffix: '%',
68+
});
69+
70+
expect(result).toBe(
71+
'Issue will be resolved when the query value is less than 75%.'
72+
);
73+
});
74+
75+
it('uses resolutionThreshold instead of highThreshold when provided for LESS condition', () => {
76+
const result = getResolutionDescription({
77+
detectionType: 'static',
78+
conditionType: DataConditionType.LESS,
79+
highThreshold: 50,
80+
resolutionThreshold: 80,
81+
thresholdSuffix: 'ms',
82+
});
83+
84+
expect(result).toBe(
85+
'Issue will be resolved when the query value is more than 80ms.'
86+
);
87+
});
5788
});
5889

5990
describe('percent detection type', () => {
@@ -62,6 +93,7 @@ describe('getDetectorResolutionDescription', () => {
6293
detectionType: 'percent',
6394
conditionType: DataConditionType.GREATER,
6495
highThreshold: 25,
96+
resolutionThreshold: undefined,
6597
comparisonDelta: 3600, // 1 hour
6698
thresholdSuffix: '%',
6799
});
@@ -76,6 +108,7 @@ describe('getDetectorResolutionDescription', () => {
76108
detectionType: 'percent',
77109
conditionType: undefined,
78110
highThreshold: 25,
111+
resolutionThreshold: undefined,
79112
comparisonDelta: 3600,
80113
thresholdSuffix: '%',
81114
});
@@ -88,6 +121,7 @@ describe('getDetectorResolutionDescription', () => {
88121
detectionType: 'percent',
89122
conditionType: DataConditionType.GREATER,
90123
highThreshold: undefined,
124+
resolutionThreshold: undefined,
91125
comparisonDelta: 3600,
92126
thresholdSuffix: '%',
93127
});
@@ -100,6 +134,7 @@ describe('getDetectorResolutionDescription', () => {
100134
detectionType: 'percent',
101135
conditionType: DataConditionType.LESS,
102136
highThreshold: 15,
137+
resolutionThreshold: undefined,
103138
comparisonDelta: 7200, // 2 hours
104139
thresholdSuffix: '%',
105140
});
@@ -114,6 +149,7 @@ describe('getDetectorResolutionDescription', () => {
114149
detectionType: 'percent',
115150
conditionType: DataConditionType.GREATER,
116151
highThreshold: 20,
152+
resolutionThreshold: undefined,
117153
comparisonDelta: 300, // 5 minutes
118154
thresholdSuffix: '%',
119155
});
@@ -122,5 +158,20 @@ describe('getDetectorResolutionDescription', () => {
122158
'Issue will be resolved when the query value is less than 20% higher than the previous 5 minutes.'
123159
);
124160
});
161+
162+
it('uses resolutionThreshold instead of highThreshold when provided', () => {
163+
const result = getResolutionDescription({
164+
detectionType: 'percent',
165+
conditionType: DataConditionType.GREATER,
166+
highThreshold: 25,
167+
resolutionThreshold: 15,
168+
comparisonDelta: 3600,
169+
thresholdSuffix: '%',
170+
});
171+
172+
expect(result).toBe(
173+
'Issue will be resolved when the query value is less than 15% higher than the previous 1 hour.'
174+
);
175+
});
125176
});
126177
});

static/app/views/detectors/utils/getDetectorResolutionDescription.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ interface PercentDetectionParams extends BaseDetectionParams {
2020
conditionType: DataConditionType | undefined;
2121
detectionType: 'percent';
2222
highThreshold: string | number | undefined;
23+
resolutionThreshold: string | number | undefined;
2324
}
2425

2526
interface StaticDetectionParams extends BaseDetectionParams {
2627
conditionType: DataConditionType | undefined;
2728
detectionType: 'static';
2829
highThreshold: string | number | undefined;
30+
resolutionThreshold: string | number | undefined;
2931
}
3032

3133
interface DynamicDetectionParams extends BaseDetectionParams {
@@ -45,21 +47,27 @@ export function getResolutionDescription(params: ResolutionDescriptionParams): s
4547
);
4648
}
4749

48-
if (!params.conditionType || params.highThreshold === undefined) {
50+
// Use resolutionThreshold if provided, otherwise fall back to highThreshold
51+
const threshold =
52+
params.resolutionThreshold === undefined
53+
? params.highThreshold
54+
: params.resolutionThreshold;
55+
56+
if (!params.conditionType || threshold === undefined) {
4957
return t('Resolution conditions not configured');
5058
}
5159

5260
if (params.detectionType === 'static') {
5361
if (params.conditionType === DataConditionType.GREATER) {
5462
return t(
5563
'Issue will be resolved when the query value is less than %s%s.',
56-
params.highThreshold,
64+
threshold,
5765
suffix
5866
);
5967
}
6068
return t(
6169
'Issue will be resolved when the query value is more than %s%s.',
62-
params.highThreshold,
70+
threshold,
6371
suffix
6472
);
6573
}
@@ -69,13 +77,13 @@ export function getResolutionDescription(params: ResolutionDescriptionParams): s
6977
if (params.conditionType === DataConditionType.GREATER) {
7078
return t(
7179
'Issue will be resolved when the query value is less than %s%% higher than the previous %s.',
72-
params.highThreshold,
80+
threshold,
7381
getDuration(delta)
7482
);
7583
}
7684
return t(
7785
'Issue will be resolved when the query value is less than %s%% lower than the previous %s.',
78-
params.highThreshold,
86+
threshold,
7987
getDuration(delta)
8088
);
8189
}

0 commit comments

Comments
 (0)