Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 0 additions & 69 deletions src/sentry/relay/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from typing import Any, Literal, NotRequired, TypedDict

import sentry_sdk
from sentry_sdk import capture_exception

from sentry import features, killswitches, options, quotas, utils
from sentry.constants import (
Expand Down Expand Up @@ -51,8 +50,6 @@
from sentry.utils.http import get_origins
from sentry.utils.options import sample_modulo

from .measurements import CUSTOM_MEASUREMENT_LIMIT

# These features will be listed in the project config.
EXPOSABLE_FEATURES = [
"organizations:continuous-profiling",
Expand Down Expand Up @@ -1049,14 +1046,6 @@ def _get_project_config(
add_experimental_config(config, "metrics", get_metrics_config, project)

if _should_extract_transaction_metrics(project):
add_experimental_config(
config,
"transactionMetrics",
get_transaction_metrics_settings,
project,
config.get("breakdownsV2"),
)

# This config key is technically not specific to _transaction_ metrics,
# is however currently both only applied to transaction metrics in
# Relay, and only used to tag transaction metrics in Sentry.
Expand Down Expand Up @@ -1285,67 +1274,9 @@ def _filter_option_to_config_setting(flt: _FilterSpec, setting: str) -> Mapping[
return ret_val


#: Version of the transaction metrics extraction.
#: When you increment this version, outdated Relays will stop extracting
#: transaction metrics.
#: See https://github.com/getsentry/relay/blob/6181c6e80b9485ed394c40bc860586ae934704e2/relay-dynamic-config/src/metrics.rs#L85
TRANSACTION_METRICS_EXTRACTION_VERSION = 6


class CustomMeasurementSettings(TypedDict):
limit: int


TransactionNameStrategy = Literal["strict", "clientBased"]


class TransactionMetricsSettings(TypedDict):
version: int
extractCustomTags: list[str]
customMeasurements: CustomMeasurementSettings
acceptTransactionNames: TransactionNameStrategy


def _should_extract_transaction_metrics(project: Project) -> bool:
return features.has(
"organizations:transaction-metrics-extraction", project.organization
) and not killswitches.killswitch_matches_context(
"relay.drop-transaction-metrics", {"project_id": project.id}
)


def get_transaction_metrics_settings(
timeout: TimeChecker, project: Project, breakdowns_config: Mapping[str, Any] | None
) -> TransactionMetricsSettings:
"""This function assumes that the corresponding feature flag has been checked.
See _should_extract_transaction_metrics.
"""
custom_tags: list[str] = []

if breakdowns_config is not None:
# we already have a breakdown configuration that tells relay which
# breakdowns to compute for an event. metrics extraction should
# probably be in sync with that, or at least not extract more metrics
# than there are breakdowns configured.
try:
for _, breakdown_config in breakdowns_config.items():
assert breakdown_config["type"] == "spanOperations"

except Exception:
capture_exception()

# Tells relay which user-defined tags to add to each extracted
# transaction metric. This cannot include things such as `os.name`
# which are computed on the server, they have to come from the SDK as
# event tags.
try:
custom_tags.extend(project.get_option("sentry:transaction_metrics_custom_tags") or ())
except Exception:
capture_exception()

return {
"version": TRANSACTION_METRICS_EXTRACTION_VERSION,
"extractCustomTags": custom_tags,
"customMeasurements": {"limit": CUSTOM_MEASUREMENT_LIMIT},
"acceptTransactionNames": "clientBased",
}
Original file line number Diff line number Diff line change
Expand Up @@ -915,9 +915,3 @@ metricConditionalTagging:
- d:transactions/measurements.fcp@millisecond
- d:transactions/measurements.lcp@millisecond
targetTag: histogram_outlier
transactionMetrics:
acceptTransactionNames: clientBased
customMeasurements:
limit: 10
extractCustomTags: []
version: 3
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,3 @@ breakdownsV2:
- ui
type: spanOperations
metricConditionalTagging: null
transactionMetrics: null
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,3 @@ metricConditionalTagging:
- d:transactions/measurements.lcp@millisecond
- s:transactions/user@none
targetTag: satisfaction
transactionMetrics:
acceptTransactionNames: clientBased
customMeasurements:
limit: 10
extractCustomTags: []
version: 6
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,3 @@ breakdownsV2:
- ui
type: spanOperations
metricConditionalTagging: null
transactionMetrics: null
67 changes: 0 additions & 67 deletions tests/sentry/relay/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,26 +152,6 @@ def test_get_experimental_config_dyn_sampling(mock_logger, _, default_project) -
assert mock_logger.exception.call_args == mock.call(ANY)


@django_db_all
@cell_silo_test
@mock.patch("sentry.relay.config.capture_exception")
def test_get_experimental_config_transaction_metrics_exception(
mock_capture_exception, default_project
):
keys = ProjectKey.objects.filter(project=default_project)
default_project.update_option("sentry:breakdowns", {"invalid_breakdowns": "test"})
# wrong type
default_project.update_option("sentry:transaction_metrics_custom_tags", 42)

with Feature({"organizations:transaction-metrics-extraction": True}):
cfg = get_project_config(default_project, project_keys=keys)

config = cfg.to_dict()["config"]

assert config["transactionMetrics"]["extractCustomTags"] == []
assert mock_capture_exception.call_count == 2


@django_db_all
@cell_silo_test
@pytest.mark.parametrize("has_custom_filters", [False, True])
Expand Down Expand Up @@ -539,7 +519,6 @@ def test_project_config_with_breakdown(
insta_snapshot(
{
"breakdownsV2": cfg["config"]["breakdownsV2"],
"transactionMetrics": cfg["config"].get("transactionMetrics"),
"metricConditionalTagging": cfg["config"].get("metricConditionalTagging"),
}
)
Expand Down Expand Up @@ -606,52 +585,6 @@ def test_project_config_satisfaction_thresholds(
insta_snapshot(cfg["config"]["metricConditionalTagging"])


@django_db_all
@cell_silo_test
@pytest.mark.parametrize("feature_flag", (False, True), ids=("feature_disabled", "feature_enabled"))
@pytest.mark.parametrize(
"killswitch", (False, True), ids=("killswitch_disabled", "killswitch_enabled")
)
def test_has_metric_extraction(default_project, feature_flag, killswitch) -> None:
options = override_options(
{
"relay.drop-transaction-metrics": (
[{"project_id": default_project.id}] if killswitch else []
)
}
)
feature = Feature(
{
"organizations:transaction-metrics-extraction": feature_flag,
}
)
with feature, options:
project_config = get_project_config(default_project)
config = project_config.to_dict()["config"]
_validate_project_config(config)
if killswitch or not feature_flag:
assert "transactionMetrics" not in config
else:
config = config["transactionMetrics"]
assert config["customMeasurements"]["limit"] > 0


@django_db_all
def test_accept_transaction_names(default_project) -> None:
feature = Feature(
{
"organizations:transaction-metrics-extraction": True,
}
)
with feature:
config = get_project_config(default_project).to_dict()["config"]

_validate_project_config(config)
transaction_metrics_config = config["transactionMetrics"]

assert transaction_metrics_config["acceptTransactionNames"] == "clientBased"


@pytest.mark.parametrize("num_clusterer_runs", [9, 10])
@django_db_all
def test_txnames_ready(default_project, num_clusterer_runs) -> None:
Expand Down
Loading