diff --git a/src/sentry/api/endpoints/organization_trace_item_attributes.py b/src/sentry/api/endpoints/organization_trace_item_attributes.py index 0839655d21d084..a30503db1b9081 100644 --- a/src/sentry/api/endpoints/organization_trace_item_attributes.py +++ b/src/sentry/api/endpoints/organization_trace_item_attributes.py @@ -68,7 +68,6 @@ get_secondary_aliases, is_sentry_convention_replacement_attribute, translate_internal_to_public_alias, - translate_to_sentry_conventions, ) from sentry.search.events.constants import ( RELEASE_STAGE_ALIAS, @@ -295,14 +294,6 @@ def get(self, request: Request, organization: Organization) -> Response: paginator=ChainPaginator([]), ) - use_sentry_conventions = features.has( - "organizations:performance-sentry-conventions-fields", - organization, - actor=request.user, - ) - - sentry_sdk.set_tag("feature.use_sentry_conventions", use_sentry_conventions) - serialized = serializer.validated_data substring_match = serialized.get("substring_match", "") query_string = serialized.get("query") @@ -357,7 +348,6 @@ def data_fn(offset: int, limit: int) -> list[TraceItemAttributeKey]: substring_match, attribute_type, column_definitions, - use_sentry_conventions, trace_item_type, include_internal, ) @@ -384,7 +374,6 @@ def query_trace_attributes( substring_match: str, attribute_type: Literal["string", "number", "boolean"], column_definitions: ColumnDefinitions, - use_sentry_conventions: bool, trace_item_type: SupportedTraceItemType, include_internal: bool, ): @@ -461,12 +450,7 @@ def query_trace_attributes( rpc_response = TraceItemAttributeNamesResponse() with sentry_sdk.start_span(op="query", name="serialize") as span: - if use_sentry_conventions: - serialize_function = self.serialize_trace_attributes_using_sentry_conventions - else: - serialize_function = self.serialize_trace_attributes - - attributes = serialize_function( + attributes = self.serialize_trace_attributes( rpc_response, attribute_type, trace_item_type, @@ -481,60 +465,6 @@ def query_trace_attributes( span.set_data("attribute_type", attribute_type) return attributes - def serialize_trace_attributes_using_sentry_conventions( - self, - rpc_response: TraceItemAttributeNamesResponse, - attribute_type: Literal["string", "number", "boolean"], - trace_item_type: SupportedTraceItemType, - include_internal: bool, - substring_match: str, - aliased_attributes: list[ResolvedAttribute | ProxyResolvedAttribute], - exclude_attributes: list[ResolvedAttribute | ProxyResolvedAttribute], - ) -> list[TraceItemAttributeKey]: - attribute_keys = {} - for attribute in rpc_response.attributes: - if attribute.name and can_expose_attribute( - attribute.name, - trace_item_type, - include_internal=include_internal, - ): - attr_key = as_attribute_key( - attribute.name, - attribute_type, - trace_item_type, - ) - public_alias = attr_key["name"] - replacement = translate_to_sentry_conventions(public_alias, trace_item_type) - if public_alias != replacement: - attr_key = as_attribute_key( - replacement, - attribute_type, - trace_item_type, - ) - - attribute_keys[attr_key["name"]] = attr_key - for aliased_attr in exclude_attributes: - attr_key = as_attribute_key( - aliased_attr.internal_name, - attribute_type, - trace_item_type, - is_proxy=isinstance(aliased_attr, ProxyResolvedAttribute), - ) - if attr_key["name"] in attribute_keys: - del attribute_keys[attr_key["name"]] - for aliased_attr in aliased_attributes: - attr_key = as_attribute_key( - aliased_attr.internal_name, - attribute_type, - trace_item_type, - is_proxy=isinstance(aliased_attr, ProxyResolvedAttribute), - ) - attribute_keys[attr_key["name"]] = attr_key - - attributes = list(attribute_keys.values()) - sentry_sdk.set_context("api_response", {"attributes": attributes}) - return attributes - def serialize_trace_attributes( self, rpc_response: TraceItemAttributeNamesResponse, diff --git a/src/sentry/api/endpoints/project_trace_item_details.py b/src/sentry/api/endpoints/project_trace_item_details.py index 6efbba3419db47..2969bb8ef0756e 100644 --- a/src/sentry/api/endpoints/project_trace_item_details.py +++ b/src/sentry/api/endpoints/project_trace_item_details.py @@ -37,7 +37,6 @@ is_sentry_convention_replacement_attribute, translate_internal_to_public_alias, translate_search_type_for_internal_column, - translate_to_sentry_conventions, ) from sentry.search.utils import InvalidQuery, parse_datetime_string from sentry.snuba.referrer import Referrer @@ -112,12 +111,10 @@ def _get_value_from_attribute( def convert_rpc_attribute_to_json( attributes: list[dict], trace_item_type: SupportedTraceItemType, - use_sentry_conventions: bool = False, include_internal: bool = False, include_arrays: bool = False, ) -> list[TraceItemAttribute]: result: list[TraceItemAttribute] = [] - seen_sentry_conventions: set[str] = set() all_internal_names = {attr["name"] for attr in attributes} for attribute in attributes: @@ -147,17 +144,12 @@ def convert_rpc_attribute_to_json( internal_name, translate_type, trace_item_type ) if not include_arrays: - convention_name = ( - translate_to_sentry_conventions(external_name, trace_item_type) - if use_sentry_conventions and external_name - else external_name - ) if ( translate_type != "string" or not isinstance(output_value, list) - or not convention_name + or not external_name or not is_sentry_convention_replacement_attribute( - convention_name, trace_item_type + external_name, trace_item_type ) ): continue @@ -172,20 +164,12 @@ def convert_rpc_attribute_to_json( internal_name, translate_type, trace_item_type ) - if use_sentry_conventions and external_name: - external_name = translate_to_sentry_conventions(external_name, trace_item_type) - if external_name in seen_sentry_conventions: + if external_name and is_sentry_convention_replacement_attribute( + external_name, trace_item_type + ): + deprecated_names = get_deprecated_source_internal_names(external_name, trace_item_type) + if not deprecated_names.isdisjoint(all_internal_names): continue - seen_sentry_conventions.add(external_name) - else: - if external_name and is_sentry_convention_replacement_attribute( - external_name, trace_item_type - ): - deprecated_names = get_deprecated_source_internal_names( - external_name, trace_item_type - ) - if not deprecated_names.isdisjoint(all_internal_names): - continue if trace_item_type == SupportedTraceItemType.SPANS and internal_name.startswith("sentry."): internal_name = internal_name.replace("sentry.", "", count=1) @@ -434,11 +418,6 @@ def get(request: Request, project: Project, item_id: str) -> Response: resp = MessageToDict(trace_item_details_rpc(req)) - use_sentry_conventions = features.has( - "organizations:performance-sentry-conventions-fields", - project.organization, - actor=request.user, - ) include_arrays = features.has( "organizations:trace-item-details-array-fields", project.organization, @@ -453,7 +432,6 @@ def get(request: Request, project: Project, item_id: str) -> Response: "attributes": convert_rpc_attribute_to_json( resp["attributes"], item_type, - use_sentry_conventions, include_internal=include_internal, include_arrays=include_arrays, ), diff --git a/src/sentry/features/temporary.py b/src/sentry/features/temporary.py index 3bd5327635ed7b..d3319439e0c888 100644 --- a/src/sentry/features/temporary.py +++ b/src/sentry/features/temporary.py @@ -195,8 +195,6 @@ def register_temporary_features(manager: FeatureManager) -> None: manager.add("organizations:insights-ai-and-mcp-dashboard-migration", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True) # Enable all registered prebuilt dashboards to be synced to the database manager.add("organizations:dashboards-sync-all-registered-prebuilt-dashboards", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=False) - # Enable sentry convention fields - manager.add("organizations:performance-sentry-conventions-fields", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True) # Enable Seer Suggestions for Web Vitals Module manager.add("organizations:performance-web-vitals-seer-suggestions", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True) # Enable the warning banner to inform users of pending deprecation of the transactions dataset diff --git a/src/sentry/search/eap/utils.py b/src/sentry/search/eap/utils.py index 3d05577c8c580c..be54d93669b06d 100644 --- a/src/sentry/search/eap/utils.py +++ b/src/sentry/search/eap/utils.py @@ -326,8 +326,3 @@ def get_deprecated_source_internal_names( replacement: str, item_type: SupportedTraceItemType ) -> set[str]: return SENTRY_CONVENTIONS_REVERSE_REPLACEMENT_MAP.get(item_type, {}).get(replacement, set()) - - -def translate_to_sentry_conventions(public_alias: str, item_type: SupportedTraceItemType) -> str: - mapping = SENTRY_CONVENTIONS_REPLACEMENT_MAPPINGS.get(item_type, {}) - return mapping.get(public_alias, public_alias) diff --git a/src/sentry/seer/endpoints/seer_rpc.py b/src/sentry/seer/endpoints/seer_rpc.py index 54133bedb7843b..d6c355cacdb259 100644 --- a/src/sentry/seer/endpoints/seer_rpc.py +++ b/src/sentry/seer/endpoints/seer_rpc.py @@ -520,7 +520,6 @@ def get_attributes_for_span( attributes = convert_rpc_attribute_to_json( response_dict.get("attributes", []), SupportedTraceItemType.SPANS, - use_sentry_conventions=False, include_internal=False, ) diff --git a/tests/sentry/api/endpoints/test_project_trace_item_details.py b/tests/sentry/api/endpoints/test_project_trace_item_details.py index 397207da0577e4..d3f3218f7e8181 100644 --- a/tests/sentry/api/endpoints/test_project_trace_item_details.py +++ b/tests/sentry/api/endpoints/test_project_trace_item_details.py @@ -13,7 +13,6 @@ def test_convert_rpc_attribute_to_json_serializes_known_string_array_without_arr } ], SupportedTraceItemType.SPANS, - use_sentry_conventions=True, ) assert result == [ @@ -34,7 +33,6 @@ def test_convert_rpc_attribute_to_json_hides_unknown_array_without_array_flag() } ], SupportedTraceItemType.SPANS, - use_sentry_conventions=True, ) assert result == [] @@ -63,7 +61,6 @@ def test_convert_rpc_attribute_to_json_exposes_array_with_array_flag() -> None: } ], SupportedTraceItemType.SPANS, - use_sentry_conventions=True, include_arrays=True, ) @@ -77,8 +74,8 @@ def test_convert_rpc_attribute_to_json_exposes_array_with_array_flag() -> None: class TestReplacementAttributeFiltering: - """When use_sentry_conventions is off, replacement attributes should only be - hidden if a deprecated source attribute is also present in the response.""" + """Replacement attributes should only be hidden if a deprecated source + attribute is also present in the response.""" @pytest.mark.parametrize( "attr_name,attr_value", @@ -94,7 +91,6 @@ def test_replacement_attribute_shown_when_no_deprecated_source( result = convert_rpc_attribute_to_json( [{"name": attr_name, "value": attr_value}], SupportedTraceItemType.SPANS, - use_sentry_conventions=False, ) assert len(result) == 1 @@ -107,7 +103,6 @@ def test_replacement_attribute_hidden_when_deprecated_source_present(self) -> No {"name": "gen_ai.usage.input_tokens", "value": {"valInt": "42"}}, ], SupportedTraceItemType.SPANS, - use_sentry_conventions=False, ) names = [r["name"] for r in result] @@ -123,7 +118,6 @@ def test_replacement_array_shown_when_no_deprecated_source(self) -> None: } ], SupportedTraceItemType.SPANS, - use_sentry_conventions=False, ) assert len(result) == 1 diff --git a/tests/snuba/api/endpoints/test_organization_trace_item_attributes.py b/tests/snuba/api/endpoints/test_organization_trace_item_attributes.py index 7863f449a9a9eb..bf84efc03eb512 100644 --- a/tests/snuba/api/endpoints/test_organization_trace_item_attributes.py +++ b/tests/snuba/api/endpoints/test_organization_trace_item_attributes.py @@ -748,102 +748,6 @@ def test_pagination(self) -> None: assert links["previous"]["href"] is not None - def test_tags_list_sentry_conventions(self) -> None: - for tag in [ - "foo", - "bar", - "baz", - "lcp", - "fcp", - "http.decoded_response_content_length", - "http.response_content_length", - "http.response_transfer_size", - "http.response.body.size", - ]: - self.store_segment( - self.project.id, - uuid4().hex, - uuid4().hex, - span_id=uuid4().hex[:16], - organization_id=self.organization.id, - parent_span_id=None, - timestamp=before_now(days=0, minutes=10).replace(microsecond=0), - transaction="foo", - duration=100, - exclusive_time=100, - measurements={tag: 0}, - ) - - response = self.do_request( - { - "attributeType": "number", - }, - features={ - "organizations:visibility-explore-view": True, - "organizations:performance-sentry-conventions-fields": True, - }, - ) - assert response.status_code == 200, response.data - assert sorted(response.data, key=itemgetter("key")) == sorted( - [ - { - "key": "tags[bar,number]", - "name": "bar", - "attributeType": "number", - "attributeSource": {"source_type": "user"}, - }, - { - "key": "tags[baz,number]", - "name": "baz", - "attributeType": "number", - "attributeSource": {"source_type": "user"}, - }, - { - "key": "browser.web_vital.fcp.value", - "name": "browser.web_vital.fcp.value", - "attributeType": "number", - "attributeSource": {"source_type": "sentry"}, - }, - { - "key": "tags[foo,number]", - "name": "foo", - "attributeType": "number", - "attributeSource": {"source_type": "user"}, - }, - { - "key": "http.decoded_response_content_length", - "name": "http.decoded_response_content_length", - "attributeType": "number", - "attributeSource": {"source_type": "sentry"}, - }, - { - "key": "http.response.body.size", - "name": "http.response.body.size", - "attributeType": "number", - "attributeSource": {"source_type": "sentry"}, - }, - { - "key": "http.response.size", - "name": "http.response.size", - "attributeType": "number", - "attributeSource": {"source_type": "sentry"}, - }, - { - "key": "browser.web_vital.lcp.value", - "name": "browser.web_vital.lcp.value", - "attributeType": "number", - "attributeSource": {"source_type": "sentry"}, - }, - { - "key": "span.duration", - "name": "span.duration", - "attributeType": "number", - "attributeSource": {"source_type": "sentry"}, - }, - ], - key=itemgetter("key"), - ) - def test_attribute_collision(self) -> None: self.store_segment( self.project.id, diff --git a/tests/snuba/api/endpoints/test_project_trace_item_details.py b/tests/snuba/api/endpoints/test_project_trace_item_details.py index dc29c5c6f079c3..4ce37d52e3f21b 100644 --- a/tests/snuba/api/endpoints/test_project_trace_item_details.py +++ b/tests/snuba/api/endpoints/test_project_trace_item_details.py @@ -313,76 +313,6 @@ def test_simple_using_spans_item_type(self) -> None: == self.one_min_ago.replace(microsecond=0, tzinfo=None).isoformat() + "Z" ) - def test_simple_using_spans_item_type_with_sentry_conventions(self) -> None: - span_1 = self.create_span( - {"description": "foo", "sentry_tags": {"status": "success"}}, - measurements={ - "code.lineno": {"value": 420}, - "http.response_content_length": {"value": 100}, - "http.response.body.size": {"value": 100}, - }, - start_ts=self.one_min_ago, - ) - span_1["trace_id"] = self.trace_uuid - item_id = span_1["span_id"] - - self.store_span(span_1) - - trace_details_response = self.do_request( - "spans", - item_id, - features={ - "organizations:discover-basic": True, - "organizations:performance-sentry-conventions-fields": True, - }, - ) - assert trace_details_response.status_code == 200, trace_details_response.content - assert trace_details_response.data["attributes"] == [ - {"name": "is_transaction", "type": "bool", "value": False}, - {"name": "code.lineno", "type": "float", "value": 420.0}, - {"name": "http.response.body.size", "type": "float", "value": 100.0}, - { - "name": "precise.finish_ts", - "type": "float", - "value": pytest.approx(self.one_min_ago.timestamp()), - }, - { - "name": "precise.start_ts", - "type": "float", - "value": pytest.approx(self.one_min_ago.timestamp()), - }, - { - "name": "received", - "type": "float", - "value": pytest.approx(self.one_min_ago.timestamp()), - }, - {"name": "span.self_time", "type": "float", "value": 1000.0}, - {"name": "project_id", "type": "int", "value": str(self.project.id)}, - {"name": "span.duration", "type": "int", "value": "1000"}, - {"name": "parent_span", "type": "str", "value": span_1["parent_span_id"]}, - {"name": "profile.id", "type": "str", "value": span_1["profile_id"]}, - {"name": "sdk.name", "type": "str", "value": "sentry.test.sdk"}, - {"name": "sdk.version", "type": "str", "value": "1.0"}, - { - "name": "sentry.segment.id", - "type": "str", - "value": span_1["segment_id"], - }, - {"name": "span.description", "type": "str", "value": "foo"}, - {"name": "span.status", "type": "str", "value": "success"}, - {"name": "trace", "type": "str", "value": self.trace_uuid}, - { - "name": "transaction.event_id", - "type": "str", - "value": span_1["event_id"], - }, - ] - assert trace_details_response.data["itemId"] == item_id - assert ( - trace_details_response.data["timestamp"] - == self.one_min_ago.replace(microsecond=0, tzinfo=None).isoformat() + "Z" - ) - def test_logs_with_a_meta_key(self) -> None: log = self.create_ourlog( {