Browse Source

feat(projectconfig): Entry for transaction name strategy (#37102)

Relay has two modes for handling transaction names with source unknown
(see getsentry/relay#1352):

- In strict mode, treat all transaction names with source unknown as
high-cardinality, and drop the name in the extracted metrics.
- In clientBased mode, treat unknown as low-cardinality, except for browser
JS SDKs.

This PR adds the corresponding project config, such that a
percentage of orgs can be consistently opted into clientBased
behavior.
Joris Bayer 2 years ago
parent
commit
ea3f49ad6e

+ 11 - 1
src/sentry/relay/config/__init__.py

@@ -1,7 +1,7 @@
 import logging
 import uuid
 from datetime import datetime
-from typing import Any, Collection, Mapping, Optional, Sequence, TypedDict
+from typing import Any, Collection, Literal, Mapping, Optional, Sequence, TypedDict
 
 import sentry_sdk
 from pytz import utc
@@ -432,11 +432,15 @@ class CustomMeasurementSettings(TypedDict):
     limit: int
 
 
+TransactionNameStrategy = Literal["strict", "clientBased"]
+
+
 class TransactionMetricsSettings(TypedDict):
     version: int
     extractMetrics: Collection[str]
     extractCustomTags: Collection[str]
     customMeasurements: CustomMeasurementSettings
+    acceptTransactionNames: TransactionNameStrategy
 
 
 def _should_extract_transaction_metrics(project: Project) -> bool:
@@ -448,6 +452,11 @@ def _should_extract_transaction_metrics(project: Project) -> bool:
     )
 
 
+def _accept_transaction_names_strategy(project: Project) -> TransactionNameStrategy:
+    is_selected_org = sample_modulo("relay.transaction-names-client-based", project.organization_id)
+    return "clientBased" if is_selected_org else "strict"
+
+
 def get_transaction_metrics_settings(
     project: Project, breakdowns_config: Optional[Mapping[str, Any]]
 ) -> TransactionMetricsSettings:
@@ -492,4 +501,5 @@ def get_transaction_metrics_settings(
         "extractMetrics": metrics,
         "extractCustomTags": custom_tags,
         "customMeasurements": {"limit": CUSTOM_MEASUREMENT_LIMIT},
+        "acceptTransactionNames": _accept_transaction_names_strategy(project),
     }

+ 2 - 1
tests/sentry/relay/snapshots/test_config/test_project_config_with_breakdown/with_metrics.pysnap

@@ -1,5 +1,5 @@
 ---
-created: '2022-07-22T12:59:33.487327Z'
+created: '2022-07-27T10:44:43.700505Z'
 creator: sentry
 source: tests/sentry/relay/test_config.py
 ---
@@ -861,6 +861,7 @@ metricConditionalTagging:
   - d:transactions/duration@millisecond
   targetTag: histogram_outlier
 transactionMetrics:
+  acceptTransactionNames: strict
   customMeasurements:
     limit: 5
   extractCustomTags: []

+ 23 - 0
tests/sentry/relay/test_config.py

@@ -224,3 +224,26 @@ def test_has_metric_extraction(default_project, feature_flag, org_sample, killsw
             config = config.to_dict()["config"]["transactionMetrics"]
             assert config["extractMetrics"]
             assert config["customMeasurements"]["limit"] > 0
+
+
+@pytest.mark.django_db
+@pytest.mark.parametrize("org_sample", (0.0, 1.0), ids=("no_orgs", "all_orgs"))
+def test_accept_transaction_names(default_project, org_sample):
+    options = override_options(
+        {
+            "relay.transaction-names-client-based": org_sample,
+        }
+    )
+    feature = Feature(
+        {
+            "organizations:transaction-metrics-extraction": True,
+        }
+    )
+    with feature, options:
+        config = get_project_config(default_project).to_dict()["config"]
+        transaction_metrics_config = config["transactionMetrics"]
+        assert (
+            transaction_metrics_config["acceptTransactionNames"] == "clientBased"
+            if org_sample
+            else "strict"
+        )