Repository: getsentry/sentry

Issue:
Determine Root Cause for On demand metrics extraction slow/stopped



Discussion:

Resolving patch:
diff --git a/src/sentry/relay/config/metric_extraction.py b/src/sentry/relay/config/metric_extraction.py
--- a/src/sentry/relay/config/metric_extraction.py
+++ b/src/sentry/relay/config/metric_extraction.py
@@ -4,6 +4,7 @@
 from typing import Any, Dict, List, Literal, Optional, Sequence, Set, Tuple, TypedDict, Union
 
 import sentry_sdk
+from sentry_relay.processing import validate_sampling_condition
 
 from sentry import features, options
 from sentry.api.endpoints.project_transaction_threshold import DEFAULT_THRESHOLD
@@ -29,7 +30,7 @@
 )
 from sentry.snuba.models import SnubaQuery
 from sentry.snuba.referrer import Referrer
-from sentry.utils import metrics
+from sentry.utils import json, metrics
 from sentry.utils.cache import cache
 
 logger = logging.getLogger(__name__)
@@ -394,7 +395,29 @@ def _convert_aggregate_and_query_to_metric(
             spec_type=spec_type,
         )
 
+        # TODO: switch to validate_rule_condition
+        validate_sampling_condition(json.dumps(on_demand_spec.condition))
+
         return on_demand_spec.query_hash, on_demand_spec.to_metric_spec(project)
+
+    except ValueError:
+        # raised by validate_sampling_condition
+        metrics.incr(
+            "on_demand_metrics.invalid_metric_spec",
+            tags={"prefilling": prefilling},
+        )
+        logger.error(
+            "Invalid on-demand metric spec",
+            exc_info=True,
+            extra={
+                "dataset": dataset,
+                "aggregate": aggregate,
+                "query": query,
+                "groupbys": groupbys,
+            },
+        )
+        return None
+
     except Exception as e:
         # Since prefilling might include several non-ondemand-compatible alerts, we want to not trigger errors in the
         # Sentry console.


Test patch:
diff --git a/tests/sentry/relay/config/test_metric_extraction.py b/tests/sentry/relay/config/test_metric_extraction.py
--- a/tests/sentry/relay/config/test_metric_extraction.py
+++ b/tests/sentry/relay/config/test_metric_extraction.py
@@ -841,3 +841,29 @@ def test_get_metric_extraction_config_with_transactions_dataset(default_project)
             "mri": "c:transactions/on_demand@none",
             "tags": [{"key": "query_hash", "value": ANY}],
         }
+
+
+@django_db_all
+def test_get_metric_extraction_config_with_invalid_spec(default_project):
+    create_alert(
+        "count()",
+        "release.build:>231900000 transaction.duration:>=10",
+        default_project,
+        dataset=Dataset.PerformanceMetrics,
+    )
+    create_alert(
+        "count()", "transaction.duration:>=20", default_project, dataset=Dataset.PerformanceMetrics
+    )
+
+    with Feature({ON_DEMAND_METRICS: True}):
+        config = get_metric_extraction_config(default_project)
+
+        assert config
+        assert len(config["metrics"]) == 1
+        assert config["metrics"][0] == {
+            "category": "transaction",
+            "condition": {"name": "event.duration", "op": "gte", "value": 20.0},
+            "field": None,
+            "mri": "c:transactions/on_demand@none",
+            "tags": [{"key": "query_hash", "value": ANY}],
+        }