diff --git a/src/sentry/api/endpoints/organization_tags.py b/src/sentry/api/endpoints/organization_tags.py index 0049ad6ed94c2a..3d0d8dea9860c3 100644 --- a/src/sentry/api/endpoints/organization_tags.py +++ b/src/sentry/api/endpoints/organization_tags.py @@ -75,15 +75,23 @@ def get(self, request: Request, organization: Organization) -> Response: # Filter out device.class from tags since it's already specified as a field in the frontend. # This prevents the tag from being displayed twice. - results = [tag for tag in results if tag.key != "device.class"] + final_results = [] + for tag in results: + if tag.key == "device.class": + continue + # the events dataset has special handling of the column "status" that breaks when users also send + # the tag "status". So we need to be explicit its a tag in these cases + elif dataset == Dataset.Events and tag.key == "status": + tag.key = "tags[status]" + final_results.append(tag) # Setting the tag for now since the measurement is still experimental - sentry_sdk.set_tag("custom_tags.count", len(results)) + sentry_sdk.set_tag("custom_tags.count", len(final_results)) sentry_sdk.set_tag( "custom_tags.count.grouped", - format_grouped_length(len(results), [1, 10, 50, 100]), + format_grouped_length(len(final_results), [1, 10, 50, 100]), ) sentry_sdk.set_tag("dataset_queried", dataset.value) - set_span_attribute("custom_tags.count", len(results)) + set_span_attribute("custom_tags.count", len(final_results)) - return Response(serialize(results, request.user)) + return Response(serialize(final_results, request.user)) diff --git a/tests/snuba/api/endpoints/test_organization_tags.py b/tests/snuba/api/endpoints/test_organization_tags.py index 6f86744422ce0c..e3b3b40b327458 100644 --- a/tests/snuba/api/endpoints/test_organization_tags.py +++ b/tests/snuba/api/endpoints/test_organization_tags.py @@ -441,6 +441,38 @@ def test_different_times_retrieves_cache(self) -> None: assert original_data == cached_data + def test_overlapping_tag(self) -> None: + user = self.create_user() + org = self.create_organization() + team = self.create_team(organization=org) + self.create_member(organization=org, user=user, teams=[team]) + + self.login_as(user=user) + + project = self.create_project(organization=org, teams=[team]) + self.store_event( + data={ + "event_id": "a" * 32, + "tags": {"status": "404", "project": "test"}, + "timestamp": self.min_ago, + }, + project_id=project.id, + ) + + url = reverse( + "sentry-api-0-organization-tags", kwargs={"organization_id_or_slug": org.slug} + ) + + response = self.client.get(url, {"statsPeriod": "14d", "dataset": "events"}, format="json") + + assert response.status_code == 200, response.content + data = response.data + data.sort(key=lambda val: val["name"]) + assert data == [ + {"name": "Level", "key": "level", "totalValues": 1}, + {"name": "Status", "key": "status", "totalValues": 1}, + ] + class ReplayOrganizationTagsTest(APITestCase, ReplaysSnubaTestCase): def test_dataset_replays(self) -> None: