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

feat(perf-issues): add new thresholds to consecutive http detector (#45534)

Dominik Buszowiecki 2 лет назад
Родитель
Сommit
31ba3e662a

+ 6 - 0
src/sentry/utils/performance_issues/base.py

@@ -153,6 +153,12 @@ def get_span_duration(span: Span) -> timedelta:
     )
 
 
+def get_duration_between_spans(first_span: Span, second_span: Span):
+    first_span_ends = first_span.get("timestamp", 0)
+    second_span_begins = second_span.get("start_timestamp", 0)
+    return timedelta(seconds=second_span_begins - first_span_ends).total_seconds() * 1000
+
+
 def get_url_from_span(span: Span) -> str:
     data = span.get("data") or {}
     url = data.get("url") or ""

+ 20 - 2
src/sentry/utils/performance_issues/detectors/consecutive_http_detector.py

@@ -5,7 +5,13 @@ from datetime import timedelta
 from sentry.issues.grouptype import PerformanceConsecutiveHTTPQueriesGroupType
 from sentry.models import Organization, Project
 
-from ..base import DetectorType, PerformanceDetector, fingerprint_spans, get_span_duration
+from ..base import (
+    DetectorType,
+    PerformanceDetector,
+    fingerprint_spans,
+    get_duration_between_spans,
+    get_span_duration,
+)
 from ..performance_problem import PerformanceProblem
 from ..types import Span
 
@@ -45,7 +51,19 @@ class ConsecutiveHTTPSpanDetector(PerformanceDetector):
             for span in self.consecutive_http_spans
         )
 
-        if exceeds_count_threshold and exceeds_span_duration_threshold:
+        exceeds_duration_between_spans_threshold = all(
+            get_duration_between_spans(
+                self.consecutive_http_spans[idx - 1], self.consecutive_http_spans[idx]
+            )
+            < self.settings.get("max_duration_between_spans")
+            for idx in range(1, len(self.consecutive_http_spans))
+        )
+
+        if (
+            exceeds_count_threshold
+            and exceeds_span_duration_threshold
+            and exceeds_duration_between_spans_threshold
+        ):
             self._store_performance_problem()
 
     def _store_performance_problem(self) -> None:

+ 2 - 1
src/sentry/utils/performance_issues/performance_detection.py

@@ -236,8 +236,9 @@ def get_detection_settings(project_id: Optional[int] = None) -> Dict[DetectorTyp
             "detection_enabled": settings["uncompressed_assets_detection_enabled"],
         },
         DetectorType.CONSECUTIVE_HTTP_OP: {
-            "span_duration_threshold": 300,  # ms
+            "span_duration_threshold": 1000,  # ms
             "consecutive_count_threshold": 3,
+            "max_duration_between_spans": 10000,  # ms
         },
     }
 

+ 20 - 0
tests/sentry/utils/performance_issues/test_consecutive_http_detector.py

@@ -160,3 +160,23 @@ class ConsecutiveDbDetectorTest(TestCase):
         )
 
         assert self.find_problems(create_event(spans)) == []
+
+    def test_does_not_detect_with_high_duration_between_spans(self):
+        span_duration = 2000
+        spans = [
+            create_span(
+                "http.client", span_duration, "GET /api/0/organizations/endpoint1", "hash1"
+            ),
+            create_span(
+                "http.client", span_duration, "GET /api/0/organizations/endpoint2", "hash2"
+            ),
+            create_span(
+                "http.client", span_duration, "GET /api/0/organizations/endpoint3", "hash3"
+            ),
+        ]
+
+        spans = [
+            modify_span_start(span, (10000 + span_duration) * spans.index(span)) for span in spans
+        ]  # ensure spans don't overlap
+
+        assert self.find_problems(create_event(spans)) == []