Browse Source

fix(spans): Fix example spans query to return only events containing both span.op and span.group (#31855)

This PR adds an additional condition to the span example query checking that examples have the same span.op and span.group as the passed in span. It's possible that an event has the span.op but with a different span.group; thus, returning an event that isn't an example for a given span. This is a backend fix for #31552

Fixes VIS-1411

* fix(spans): Fix example spans query to return only events containing span.op and span.group

* install js dev

* chore(spans): Use consistent alias

* fixes

* test(spans): Test queries

* test(spans): Fix tests

* remove mocks

* add a comment

* fix tests

* fix assertion

* update response shape
Dameli Ushbayeva 3 years ago
parent
commit
9b8b24ce5f

+ 5 - 0
src/sentry/api/endpoints/organization_events_spans_performance.py

@@ -598,6 +598,11 @@ def query_example_transactions(
         [
             Condition(Function("has", [builder.column("spans_op"), span.op]), Op.EQ, 1),
             Condition(Function("has", [builder.column("spans_group"), span.group]), Op.EQ, 1),
+            Condition(
+                builder.resolve_span_function("count", span, "count_span_time"),
+                Op.GT,
+                0,
+            ),
         ]
     )
 

+ 41 - 0
tests/snuba/api/endpoints/test_organization_events_spans_performance.py

@@ -1033,6 +1033,47 @@ class OrganizationEventsSpansExamplesEndpointTest(OrganizationEventsSpansEndpoin
             ]
         }
 
+    def test_span_filters(self):
+        test_op = "django.middleware"
+        test_hash = "cd" * 8
+        spans = [
+            # span with test_op but different hash
+            {
+                "same_process_as_parent": True,
+                "parent_span_id": "a" * 16,
+                "span_id": "b" * 16,
+                "start_timestamp": iso_format(self.min_ago + timedelta(seconds=1)),
+                "timestamp": iso_format(self.min_ago + timedelta(seconds=4)),
+                "op": test_op,
+                "description": "middleware span",
+                "hash": "ab" * 8,
+                "exclusive_time": 3.0,
+            },
+            # span with test_hash but different op
+            {
+                "same_process_as_parent": True,
+                "parent_span_id": "a" * 16,
+                "span_id": "c" * 16,
+                "start_timestamp": iso_format(self.min_ago + timedelta(seconds=1)),
+                "timestamp": iso_format(self.min_ago + timedelta(seconds=4)),
+                "op": "django.view",
+                "description": "middleware span",
+                "hash": test_hash,
+                "exclusive_time": 1.0,
+            },
+        ]
+        self.create_event(spans=spans)
+
+        with self.feature(self.FEATURES):
+            response = self.client.get(
+                self.url,
+                data={"project": self.project.id, "span": f"{test_op}:{test_hash}"},
+                format="json",
+            )
+
+        assert response.status_code == 200, response.content
+        assert response.data == [{"op": test_op, "group": test_hash, "examples": []}]
+
     @patch("sentry.api.endpoints.organization_events_spans_performance.raw_snql_query")
     def test_one_span(self, mock_raw_snql_query):
         event = self.create_event()