Repository: getsentry/sentry
Pull request: feat(flags): Add audit log flag filtering
Allows responses to be filtered by flag.

Closes: https://github.com/getsentry/sentry/issues/78933

Problem statement:
Add ability to filter by flag when querying the flag audit log
When showing the suspect feature flags table its important that the API response returned only shows flags which were captured by the error event.  Extraneous events could force pagination and make showing the table prohibitively difficult.

Hints from issue discussion:

Commit message: Add flag filtering

Patch to review:
diff --git a/src/sentry/flags/docs/api.md b/src/sentry/flags/docs/api.md
index 5667acfaf81aa7..13a227ba4861ec 100644
--- a/src/sentry/flags/docs/api.md
+++ b/src/sentry/flags/docs/api.md
@@ -13,6 +13,7 @@ This document is structured by resource with each resource having actions that c
 ## Flag Logs [/organizations/<organization_id_or_slug>/flags/logs/]
 
 - Parameters
+  - flag (optional, string) - The flag to filter the result by. Can be specified multiple times.
   - start (optional, string) - ISO 8601 format (`YYYY-MM-DDTHH:mm:ss.sssZ`)
   - end (optional, string) - ISO 8601 format. Required if `start` is set.
   - statsPeriod (optional, string) - A positive integer suffixed with a unit type.
diff --git a/src/sentry/flags/endpoints/logs.py b/src/sentry/flags/endpoints/logs.py
index 8da767df45f7f9..45dfeea606ec21 100644
--- a/src/sentry/flags/endpoints/logs.py
+++ b/src/sentry/flags/endpoints/logs.py
@@ -61,6 +61,10 @@ def get(self, request: Request, organization: Organization) -> Response:
             organization_id=organization.id,
         )
 
+        flags = request.GET.getlist("flag")
+        if flags:
+            queryset = queryset.filter(flag__in=flags)
+
         return self.paginate(
             request=request,
             queryset=queryset,
diff --git a/tests/sentry/flags/endpoints/test_logs.py b/tests/sentry/flags/endpoints/test_logs.py
index 6efc54bde2f70d..92f6587f5c93a6 100644
--- a/tests/sentry/flags/endpoints/test_logs.py
+++ b/tests/sentry/flags/endpoints/test_logs.py
@@ -36,7 +36,6 @@ def test_get(self):
 
             result = response.json()
             assert len(result["data"]) == 1
-            assert result["data"][0]["id"] == 1
             assert result["data"][0]["action"] == "created"
             assert "created_at" in result["data"][0]
             assert result["data"][0]["created_by"] == "a@b.com"
@@ -44,6 +43,35 @@ def test_get(self):
             assert result["data"][0]["flag"] == "hello"
             assert result["data"][0]["tags"] == {"commit_sha": "123"}
 
+    def test_get_filter_by_flag(self):
+        FlagAuditLogModel(
+            action=0,
+            created_at=datetime.now(timezone.utc),
+            created_by="a@b.com",
+            created_by_type=0,
+            flag="hello",
+            organization_id=self.organization.id,
+            tags={},
+        ).save()
+
+        FlagAuditLogModel(
+            action=0,
+            created_at=datetime.now(timezone.utc),
+            created_by="a@b.com",
+            created_by_type=0,
+            flag="world",
+            organization_id=self.organization.id,
+            tags={},
+        ).save()
+
+        with self.feature(self.features):
+            response = self.client.get(self.url + "?flag=world")
+            assert response.status_code == 200
+
+            result = response.json()
+            assert len(result["data"]) == 1
+            assert result["data"][0]["flag"] == "world"
+
     def test_get_unauthorized_organization(self):
         org = self.create_organization()
         url = reverse(self.endpoint, args=(org.id,))
@@ -125,7 +153,6 @@ def test_get(self):
             assert response.status_code == 200
 
             result = response.json()
-            assert result["data"]["id"] == 4
             assert result["data"]["action"] == "created"
             assert "created_at" in result["data"]
             assert result["data"]["created_by"] == "a@b.com"


Code review comments:
diff_hunk: @@ -13,6 +13,7 @@ This document is structured by resource with each resource having actions that c
 ## Flag Logs [/organizations/<organization_id_or_slug>/flags/logs/]
 
 - Parameters
+  - flag (optional, string) - The flag to filter the result by. Can be specified multiple times.
path: src/sentry/flags/docs/api.md
text: @user1:
```suggestion
  - flag (optional, string) - The flag name to filter the result by. Can be specified multiple times.
```