Browse Source

ref(relay): Make cardinality limits more configurable (#68158)

Makes cardinality limits for Relay more configurable, to be able to test
and roll them out more easily.

`drop` from the sessions config was removed in
https://github.com/getsentry/relay/pull/3271 - required for the librelay
update to work
David Herberth 11 months ago
parent
commit
a245c4263d

+ 1 - 1
requirements-base.txt

@@ -65,7 +65,7 @@ sentry-arroyo>=2.16.5
 sentry-kafka-schemas>=0.1.65
 sentry-ophio==0.2.6
 sentry-redis-tools>=0.1.7
-sentry-relay>=0.8.55
+sentry-relay>=0.8.56
 sentry-sdk>=1.44.0
 snuba-sdk>=2.0.31
 simplejson>=3.17.6

+ 1 - 1
requirements-dev-frozen.txt

@@ -179,7 +179,7 @@ sentry-forked-djangorestframework-stubs==3.14.5.post1
 sentry-kafka-schemas==0.1.65
 sentry-ophio==0.2.6
 sentry-redis-tools==0.1.7
-sentry-relay==0.8.55
+sentry-relay==0.8.56
 sentry-sdk==1.44.0
 sentry-usage-accountant==0.0.10
 simplejson==3.17.6

+ 1 - 1
requirements-frozen.txt

@@ -121,7 +121,7 @@ sentry-arroyo==2.16.5
 sentry-kafka-schemas==0.1.65
 sentry-ophio==0.2.6
 sentry-redis-tools==0.1.7
-sentry-relay==0.8.55
+sentry-relay==0.8.56
 sentry-sdk==1.44.0
 sentry-usage-accountant==0.0.10
 simplejson==3.17.6

+ 9 - 0
src/sentry/options/defaults.py

@@ -994,6 +994,15 @@ register(
 register(
     "relay.cardinality-limiter.error-sample-rate", default=0.01, flags=FLAG_AUTOMATOR_MODIFIABLE
 )
+# List of additional cardinality limits and selectors.
+#
+# ```
+# {
+#   "rollout_rate": 0.001,
+#   "limit": { .. Cardinality Limit .. }
+# }
+# ```
+register("relay.cardinality-limiter.limits", default=[], flags=FLAG_AUTOMATOR_MODIFIABLE)
 
 # Controls the encoding used in Relay for encoding distributions and sets
 # when writing to Kafka.

+ 17 - 3
src/sentry/relay/config/__init__.py

@@ -248,6 +248,11 @@ class CardinalityLimit(TypedDict):
     namespace: str | None
 
 
+class CardinalityLimitOption(TypedDict):
+    rollout_rate: NotRequired[float]
+    limit: CardinalityLimit
+
+
 def get_metrics_config(timeout: TimeChecker, project: Project) -> Mapping[str, Any] | None:
     metrics_config = {}
 
@@ -280,6 +285,18 @@ def get_metrics_config(timeout: TimeChecker, project: Project) -> Mapping[str, A
             if id in passive_limits:
                 limit["passive"] = True
             cardinality_limits.append(limit)
+
+        clos: list[CardinalityLimitOption] = options.get("relay.cardinality-limiter.limits")
+        for clo in clos:
+            rollout_rate = clo.get("rollout_rate", 1.0)
+            if (project.organization.id % 100000) / 100000 >= rollout_rate:
+                continue
+
+            try:
+                cardinality_limits.append(clo["limit"])
+            except KeyError:
+                pass
+
         metrics_config["cardinalityLimits"] = cardinality_limits
 
     if features.has("organizations:metrics-blocking", project.organization):
@@ -828,9 +845,6 @@ def _get_project_config(
                 if _should_extract_abnormal_mechanism(project)
                 else EXTRACT_METRICS_VERSION
             ),
-            "drop": features.has(
-                "organizations:release-health-drop-sessions", project.organization
-            ),
         }
 
     performance_score_profiles = [

+ 1 - 2
tests/sentry/api/endpoints/test_relay_projectconfigs_v2.py

@@ -357,7 +357,7 @@ def test_session_metrics_extraction(call_endpoint, task_runner, drop_sessions):
 
         for config in result["configs"].values():
             config = config["config"]
-            assert config["sessionMetrics"] == {"version": 1, "drop": drop_sessions}
+            assert config["sessionMetrics"] == {"version": 1}
 
 
 @django_db_all
@@ -378,5 +378,4 @@ def test_session_metrics_abnormal_mechanism_tag_extraction(
                 config = config["config"]
                 assert config["sessionMetrics"] == {
                     "version": 2 if abnormal_mechanism_rollout else 1,
-                    "drop": False,
                 }

+ 7 - 0
tests/sentry/relay/snapshots/test_config/test_project_config_cardinality_limits/False/REGION.pysnap

@@ -37,3 +37,10 @@ cardinalityLimits:
   window:
     granularitySeconds: 600
     windowSeconds: 3600
+- id: test2
+  limit: 80
+  report: true
+  scope: name
+  window:
+    granularitySeconds: 800
+    windowSeconds: 8000

+ 7 - 0
tests/sentry/relay/snapshots/test_config/test_project_config_cardinality_limits/True/REGION.pysnap

@@ -42,3 +42,10 @@ cardinalityLimits:
   window:
     granularitySeconds: 600
     windowSeconds: 3600
+- id: test2
+  limit: 80
+  report: true
+  scope: name
+  window:
+    granularitySeconds: 800
+    windowSeconds: 8000

+ 22 - 1
tests/sentry/relay/test_config.py

@@ -497,7 +497,6 @@ def test_project_config_with_organizations_metrics_extraction(
         session_metrics = get_path(cfg, "config", "sessionMetrics")
         if has_metrics_extraction:
             assert session_metrics == {
-                "drop": False,
                 "version": 2 if abnormal_mechanism_rollout else 1,
             }
         else:
@@ -957,6 +956,28 @@ def test_project_config_cardinality_limits(default_project, insta_snapshot, pass
             ]
         }
 
+    options["relay.cardinality-limiter.limits"] = [
+        {
+            "rollout_rate": 0,
+            "limit": {
+                "id": "test1",
+                "window": {"windowSeconds": 7000, "granularitySeconds": 700},
+                "limit": 70,
+                "scope": "name",
+            },
+        },
+        {
+            "rollout_rate": 1,
+            "limit": {
+                "id": "test2",
+                "window": {"windowSeconds": 8000, "granularitySeconds": 800},
+                "limit": 80,
+                "scope": "name",
+                "report": True,
+            },
+        },
+    ]
+
     features = Feature({"organizations:relay-cardinality-limiter": True})
 
     with override_options(options), features: