Skip to content

Commit e559d20

Browse files
authored
chore(dynamic-sampling): remove dynamic sampling minimum samplerate project option (#95104)
1 parent 2a5c0f8 commit e559d20

File tree

7 files changed

+1
-176
lines changed

7 files changed

+1
-176
lines changed

src/sentry/api/endpoints/project_details.py

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@
3636
from sentry.deletions.models.scheduleddeletion import RegionScheduledDeletion
3737
from sentry.dynamic_sampling import get_supported_biases_ids, get_user_biases
3838
from sentry.dynamic_sampling.types import DynamicSamplingMode
39-
from sentry.dynamic_sampling.utils import (
40-
has_custom_dynamic_sampling,
41-
has_dynamic_sampling,
42-
has_dynamic_sampling_minimum_sample_rate,
43-
)
39+
from sentry.dynamic_sampling.utils import has_custom_dynamic_sampling, has_dynamic_sampling
4440
from sentry.grouping.enhancer import Enhancements
4541
from sentry.grouping.enhancer.exceptions import InvalidEnhancerConfig
4642
from sentry.grouping.fingerprinting import FingerprintingRules, InvalidFingerprintingConfig
@@ -131,7 +127,6 @@ class ProjectMemberSerializer(serializers.Serializer):
131127
"copy_from_project",
132128
"targetSampleRate",
133129
"dynamicSamplingBiases",
134-
"dynamicSamplingMinimumSampleRate",
135130
"tempestFetchScreenshots",
136131
"tempestFetchDumps",
137132
"autofixAutomationTuning",
@@ -225,7 +220,6 @@ class ProjectAdminSerializer(ProjectMemberSerializer):
225220
copy_from_project = serializers.IntegerField(required=False)
226221
targetSampleRate = serializers.FloatField(required=False, min_value=0, max_value=1)
227222
dynamicSamplingBiases = DynamicSamplingBiasSerializer(required=False, many=True)
228-
dynamicSamplingMinimumSampleRate = serializers.BooleanField(required=False)
229223
tempestFetchScreenshots = serializers.BooleanField(required=False)
230224
tempestFetchDumps = serializers.BooleanField(required=False)
231225
autofixAutomationTuning = serializers.ChoiceField(
@@ -434,15 +428,6 @@ def validate_targetSampleRate(self, value):
434428

435429
return value
436430

437-
def validate_dynamicSamplingMinimumSampleRate(self, value):
438-
organization = self.context["project"].organization
439-
actor = self.context["request"].user
440-
if not has_dynamic_sampling_minimum_sample_rate(organization, actor=actor):
441-
raise serializers.ValidationError(
442-
"Organization does not have the dynamic sampling minimum sample rate feature enabled."
443-
)
444-
return value
445-
446431
def validate_tempestFetchScreenshots(self, value):
447432
organization = self.context["project"].organization
448433
actor = self.context["request"].user
@@ -773,14 +758,6 @@ def put(self, request: Request, project) -> Response:
773758
changed_proj_settings["sentry:dynamic_sampling_biases"] = result[
774759
"dynamicSamplingBiases"
775760
]
776-
if result.get("dynamicSamplingMinimumSampleRate") is not None:
777-
if project.update_option(
778-
"sentry:dynamic_sampling_minimum_sample_rate",
779-
result["dynamicSamplingMinimumSampleRate"],
780-
):
781-
changed_proj_settings["sentry:dynamic_sampling_minimum_sample_rate"] = result[
782-
"dynamicSamplingMinimumSampleRate"
783-
]
784761

785762
if result.get("autofixAutomationTuning") is not None:
786763
if project.update_option(

src/sentry/api/serializers/models/project.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
from sentry.dynamic_sampling.utils import (
2626
has_custom_dynamic_sampling,
2727
has_dynamic_sampling,
28-
has_dynamic_sampling_minimum_sample_rate,
2928
is_project_mode_sampling,
3029
)
3130
from sentry.eventstore.models import DEFAULT_SUBJECT_TEMPLATE
@@ -950,7 +949,6 @@ class DetailedProjectResponse(ProjectWithTeamResponseDict):
950949
relayPiiConfig: str | None
951950
builtinSymbolSources: list[str]
952951
dynamicSamplingBiases: list[dict[str, str | bool]]
953-
dynamicSamplingMinimumSampleRate: bool
954952
eventProcessing: dict[str, bool]
955953
symbolSources: str
956954
isDynamicallySampled: bool
@@ -1101,9 +1099,6 @@ def serialize(
11011099
"dynamicSamplingBiases": self.get_value_with_default(
11021100
attrs, "sentry:dynamic_sampling_biases"
11031101
),
1104-
"dynamicSamplingMinimumSampleRate": self.get_value_with_default(
1105-
attrs, "sentry:dynamic_sampling_minimum_sample_rate"
1106-
),
11071102
"eventProcessing": {
11081103
"symbolicationDegraded": False,
11091104
},
@@ -1123,11 +1118,6 @@ def serialize(
11231118
)
11241119
data["tempestFetchDumps"] = attrs["options"].get("sentry:tempest_fetch_dumps", False)
11251120

1126-
if has_dynamic_sampling_minimum_sample_rate(obj.organization, user):
1127-
data["dynamicSamplingMinimumSampleRate"] = bool(
1128-
obj.get_option("sentry:dynamic_sampling_minimum_sample_rate")
1129-
)
1130-
11311121
return data
11321122

11331123
def format_options(self, attrs: Mapping[str, Any]) -> dict[str, Any]:

src/sentry/apidocs/examples/project_examples.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@
152152
"filters:releases": "",
153153
"filters:error_messages": "",
154154
"feedback:branding": True,
155-
"sentry:dynamic_sampling_minimum_sample_rate": True,
156155
},
157156
"digestsMinDelay": 180,
158157
"digestsMaxDelay": 600,
@@ -260,7 +259,6 @@
260259
{"id": "boostReplayId", "active": True},
261260
{"id": "recalibrationRule", "active": True},
262261
],
263-
"dynamicSamplingMinimumSampleRate": True,
264262
"eventProcessing": {"symbolicationDegraded": False},
265263
"symbolSources": "[]",
266264
"tempestFetchScreenshots": False,

src/sentry/dynamic_sampling/utils.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,6 @@ def has_custom_dynamic_sampling(
2525
)
2626

2727

28-
def has_dynamic_sampling_minimum_sample_rate(
29-
organization: Organization | None, actor: User | RpcUser | AnonymousUser | None = None
30-
) -> bool:
31-
return (
32-
organization is not None
33-
and features.has(
34-
"organizations:dynamic-sampling-minimum-sample-rate", organization, actor=actor
35-
)
36-
and has_custom_dynamic_sampling(organization, actor=actor)
37-
)
38-
39-
4028
def is_project_mode_sampling(organization: Organization | None) -> bool:
4129
return (
4230
organization is not None

src/sentry/models/options/project_option.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
"sentry:relay_pii_config",
6060
"sentry:dynamic_sampling",
6161
"sentry:dynamic_sampling_biases",
62-
"sentry:dynamic_sampling_minimum_sample_rate",
6362
"sentry:target_sample_rate",
6463
"sentry:tempest_fetch_screenshots",
6564
"sentry:tempest_fetch_dumps",

src/sentry/projectoptions/defaults.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,6 @@
193193
# Dynamic sampling rate in project-level "manual" configuration mode
194194
register(key="sentry:target_sample_rate", default=TARGET_SAMPLE_RATE_DEFAULT)
195195

196-
# Dynamic sampling minimum sample rate
197-
register(key="sentry:dynamic_sampling_minimum_sample_rate", default=False)
198-
199196
# Should tempest fetch screenshots for this project
200197
register(key="sentry:tempest_fetch_screenshots", default=False)
201198

tests/sentry/api/endpoints/test_project_details.py

Lines changed: 0 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,130 +1874,6 @@ def test_put_new_dynamic_sampling_incorrect_rules_with_correct_flags(self):
18741874
"Error: Only 'id' and 'active' fields are allowed for bias."
18751875
]
18761876

1877-
@with_feature(
1878-
{
1879-
"organizations:dynamic-sampling-minimum-sample-rate": True,
1880-
"organizations:dynamic-sampling-custom": True,
1881-
}
1882-
)
1883-
def test_dynamic_sampling_minimum_sample_rate_with_feature(self):
1884-
"""Test setting and getting dynamicSamplingMinimumSampleRate with feature flag enabled"""
1885-
# Test setting to True
1886-
response = self.get_success_response(
1887-
self.organization.slug,
1888-
self.project.slug,
1889-
method="put",
1890-
dynamicSamplingMinimumSampleRate=True,
1891-
)
1892-
assert response.data["dynamicSamplingMinimumSampleRate"] is True
1893-
assert self.project.get_option("sentry:dynamic_sampling_minimum_sample_rate") is True
1894-
1895-
# Test getting the field after setting it
1896-
get_response = self.get_success_response(
1897-
self.organization.slug, self.project.slug, method="get"
1898-
)
1899-
assert "dynamicSamplingMinimumSampleRate" in get_response.data
1900-
assert get_response.data["dynamicSamplingMinimumSampleRate"] is True
1901-
1902-
# Test setting to False
1903-
response = self.get_success_response(
1904-
self.organization.slug,
1905-
self.project.slug,
1906-
method="put",
1907-
dynamicSamplingMinimumSampleRate=False,
1908-
)
1909-
assert response.data["dynamicSamplingMinimumSampleRate"] is False
1910-
assert self.project.get_option("sentry:dynamic_sampling_minimum_sample_rate") is False
1911-
1912-
# Test getting the field after setting it to False
1913-
get_response = self.get_success_response(
1914-
self.organization.slug, self.project.slug, method="get"
1915-
)
1916-
assert "dynamicSamplingMinimumSampleRate" in get_response.data
1917-
assert get_response.data["dynamicSamplingMinimumSampleRate"] is False
1918-
1919-
def test_dynamic_sampling_minimum_sample_rate_without_feature(self):
1920-
"""Test setting and getting dynamicSamplingMinimumSampleRate without feature flag"""
1921-
# Test setting the field without feature flag - should fail
1922-
self.get_error_response(
1923-
self.organization.slug,
1924-
self.project.slug,
1925-
method="put",
1926-
dynamicSamplingMinimumSampleRate=True,
1927-
status_code=400,
1928-
)
1929-
1930-
# Test that the field is not present in GET response without feature flag
1931-
get_response = self.get_success_response(
1932-
self.organization.slug, self.project.slug, method="get"
1933-
)
1934-
assert not get_response.data["dynamicSamplingMinimumSampleRate"]
1935-
1936-
@with_feature(
1937-
{
1938-
"organizations:dynamic-sampling-minimum-sample-rate": True,
1939-
"organizations:dynamic-sampling-custom": True,
1940-
}
1941-
)
1942-
def test_dynamic_sampling_minimum_sample_rate_validation(self):
1943-
"""Test validation of dynamicSamplingMinimumSampleRate parameter types"""
1944-
# Ensure initial state is False
1945-
assert self.project.get_option("sentry:dynamic_sampling_minimum_sample_rate") is False
1946-
1947-
# Test with valid boolean value
1948-
response = self.get_success_response(
1949-
self.organization.slug,
1950-
self.project.slug,
1951-
method="put",
1952-
dynamicSamplingMinimumSampleRate=True,
1953-
)
1954-
assert response.data["dynamicSamplingMinimumSampleRate"] is True
1955-
assert self.project.get_option("sentry:dynamic_sampling_minimum_sample_rate") is True
1956-
1957-
# Test with valid string value
1958-
response = self.get_success_response(
1959-
self.organization.slug,
1960-
self.project.slug,
1961-
method="put",
1962-
dynamicSamplingMinimumSampleRate="true",
1963-
)
1964-
assert response.data["dynamicSamplingMinimumSampleRate"] is True
1965-
assert self.project.get_option("sentry:dynamic_sampling_minimum_sample_rate") is True
1966-
1967-
# Test with valid number value
1968-
response = self.get_success_response(
1969-
self.organization.slug,
1970-
self.project.slug,
1971-
method="put",
1972-
dynamicSamplingMinimumSampleRate=1,
1973-
)
1974-
assert response.data["dynamicSamplingMinimumSampleRate"] is True
1975-
assert self.project.get_option("sentry:dynamic_sampling_minimum_sample_rate") is True
1976-
1977-
# Test with invalid float value
1978-
response = self.get_error_response(
1979-
self.organization.slug,
1980-
self.project.slug,
1981-
method="put",
1982-
dynamicSamplingMinimumSampleRate=0.5,
1983-
status_code=400,
1984-
)
1985-
assert "Must be a valid boolean." in response.data["dynamicSamplingMinimumSampleRate"][0]
1986-
# Ensure the project option wasn't changed by invalid request
1987-
assert self.project.get_option("sentry:dynamic_sampling_minimum_sample_rate") is True
1988-
1989-
# Test with null/None value
1990-
response = self.get_error_response(
1991-
self.organization.slug,
1992-
self.project.slug,
1993-
method="put",
1994-
dynamicSamplingMinimumSampleRate=None,
1995-
status_code=400,
1996-
)
1997-
assert "This field may not be null." in response.data["dynamicSamplingMinimumSampleRate"][0]
1998-
# Ensure the project option wasn't changed by invalid request
1999-
assert self.project.get_option("sentry:dynamic_sampling_minimum_sample_rate") is True
2000-
20011877
@with_feature("organizations:tempest-access")
20021878
def test_put_tempest_fetch_screenshots(self):
20031879
# assert default value is False, and that put request updates the value

0 commit comments

Comments
 (0)