Browse Source

fix(starfish): Handle free text search (#54060)

- This fixes free text search on the span-metrics dataset so instead of
handling something like query:`test abc` as `message:"test abc"` it'll
now be handled as `span.description:"test abc"`
- This also identifies an issue with the metric layer where tag
searching like this isn't supported
William Mak 1 year ago
parent
commit
4cee72d9a2

+ 2 - 0
src/sentry/search/events/builder/metrics.py

@@ -1111,6 +1111,7 @@ class TimeseriesMetricQueryBuilder(MetricsQueryBuilder):
         use_metrics_layer: Optional[bool] = False,
         groupby: Optional[Column] = None,
         on_demand_metrics_enabled: Optional[bool] = False,
+        parser_config_overrides: Optional[Mapping[str, Any]] = None,
     ):
         super().__init__(
             params=params,
@@ -1122,6 +1123,7 @@ class TimeseriesMetricQueryBuilder(MetricsQueryBuilder):
             functions_acl=functions_acl,
             use_metrics_layer=use_metrics_layer,
             on_demand_metrics_enabled=on_demand_metrics_enabled,
+            parser_config_overrides=parser_config_overrides,
         )
         if self.granularity.granularity > interval:
             for granularity in constants.METRICS_GRANULARITIES:

+ 10 - 0
src/sentry/search/events/builder/spans_metrics.py

@@ -16,6 +16,16 @@ class SpansMetricsQueryBuilder(MetricsQueryBuilder):
     spans_metrics_builder = True
     has_transaction = False
 
+    def __init__(
+        self,
+        *args: Any,
+        **kwargs: Any,
+    ):
+        parser_config_overrides = kwargs.pop("parser_config_overrides", {})
+        parser_config_overrides["free_text_key"] = "span.description"
+        kwargs["parser_config_overrides"] = parser_config_overrides
+        super().__init__(*args, **kwargs)
+
     def get_field_type(self, field: str) -> Optional[str]:
         if field in self.meta_resolver_map:
             return self.meta_resolver_map[field]

+ 64 - 0
tests/snuba/api/endpoints/test_organization_events_span_metrics.py

@@ -476,6 +476,62 @@ class OrganizationEventsMetricsEnhancedPerformanceEndpointTest(MetricsEnhancedPe
         assert meta["dataset"] == "spansMetrics"
         assert meta["fields"]["p50(span.self_time)"] == "duration"
 
+    def test_tag_search(self):
+        self.store_span_metric(
+            321,
+            internal_metric=constants.SELF_TIME_LIGHT,
+            timestamp=self.min_ago,
+            tags={"span.description": "foo"},
+        )
+        self.store_span_metric(
+            99,
+            internal_metric=constants.SELF_TIME_LIGHT,
+            timestamp=self.min_ago,
+            tags={"span.description": "bar"},
+        )
+        response = self.do_request(
+            {
+                "field": ["sum(span.self_time)"],
+                "query": "span.description:bar",
+                "project": self.project.id,
+                "dataset": "spansMetrics",
+            }
+        )
+        assert response.status_code == 200, response.content
+        data = response.data["data"]
+        meta = response.data["meta"]
+        assert len(data) == 1
+        assert data[0]["sum(span.self_time)"] == 99
+        assert meta["dataset"] == "spansMetrics"
+
+    def test_free_text_search(self):
+        self.store_span_metric(
+            321,
+            internal_metric=constants.SELF_TIME_LIGHT,
+            timestamp=self.min_ago,
+            tags={"span.description": "foo"},
+        )
+        self.store_span_metric(
+            99,
+            internal_metric=constants.SELF_TIME_LIGHT,
+            timestamp=self.min_ago,
+            tags={"span.description": "bar"},
+        )
+        response = self.do_request(
+            {
+                "field": ["sum(span.self_time)"],
+                "query": "foo",
+                "project": self.project.id,
+                "dataset": "spansMetrics",
+            }
+        )
+        assert response.status_code == 200, response.content
+        data = response.data["data"]
+        meta = response.data["meta"]
+        assert len(data) == 1
+        assert data[0]["sum(span.self_time)"] == 321
+        assert meta["dataset"] == "spansMetrics"
+
 
 @region_silo_test
 class OrganizationEventsMetricsEnhancedPerformanceEndpointTestWithMetricLayer(
@@ -500,3 +556,11 @@ class OrganizationEventsMetricsEnhancedPerformanceEndpointTestWithMetricLayer(
     @pytest.mark.xfail(reason="Cannot group by transform")
     def test_span_module(self):
         super().test_span_module()
+
+    @pytest.mark.xfail(reason="Cannot search by tags")
+    def test_tag_search(self):
+        super().test_tag_search()
+
+    @pytest.mark.xfail(reason="Cannot search by tags")
+    def test_free_text_search(self):
+        super().test_free_text_search()