Skip to content

Commit 3c77fd4

Browse files
authored
ref(explorer): cleanup old issue rpc (#104922)
1 parent 08da41c commit 3c77fd4

File tree

4 files changed

+2
-670
lines changed

4 files changed

+2
-670
lines changed

src/sentry/seer/endpoints/organization_seer_rpc.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
from sentry.seer.explorer.tools import (
5252
execute_table_query,
5353
execute_timeseries_query,
54-
get_issue_and_event_details,
5554
get_issue_and_event_details_v2,
5655
get_log_attributes_for_trace,
5756
get_metric_attributes_for_trace,
@@ -100,7 +99,6 @@
10099
"get_trace_waterfall": rpc_get_trace_waterfall,
101100
"get_repository_definition": get_repository_definition,
102101
"execute_timeseries_query": map_org_id_param(execute_timeseries_query),
103-
"get_issue_and_event_details": get_issue_and_event_details,
104102
"get_issue_and_event_details_v2": get_issue_and_event_details_v2,
105103
"get_profile_flamegraph": rpc_get_profile_flamegraph,
106104
"get_replay_metadata": get_replay_metadata,

src/sentry/seer/endpoints/seer_rpc.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@
8787
from sentry.seer.explorer.tools import (
8888
execute_table_query,
8989
execute_timeseries_query,
90-
get_issue_and_event_details,
9190
get_issue_and_event_details_v2,
9291
get_log_attributes_for_trace,
9392
get_metric_attributes_for_trace,
@@ -1028,7 +1027,6 @@ def check_repository_integrations_status(*, repository_integrations: list[dict[s
10281027
"get_profiles_for_trace": rpc_get_profiles_for_trace,
10291028
"get_issues_for_transaction": rpc_get_issues_for_transaction,
10301029
"get_trace_waterfall": rpc_get_trace_waterfall,
1031-
"get_issue_and_event_details": get_issue_and_event_details,
10321030
"get_issue_and_event_details_v2": get_issue_and_event_details_v2,
10331031
"get_profile_flamegraph": rpc_get_profile_flamegraph,
10341032
"execute_table_query": execute_table_query,

src/sentry/seer/explorer/tools.py

Lines changed: 2 additions & 261 deletions
Original file line numberDiff line numberDiff line change
@@ -648,41 +648,6 @@ def _get_issue_event_timeseries(
648648
return data, stats_period, interval
649649

650650

651-
def _get_trace_with_spans(
652-
trace_ids: list[str], organization: Organization, start: datetime, end: datetime
653-
) -> str | None:
654-
"""
655-
Given a list of trace IDs, return a trace ID with at least one span (non-deterministic).
656-
"""
657-
# Allow errors if start is outside retention.
658-
_, start = outside_retention_with_modified_start(start, end, organization)
659-
660-
if not trace_ids:
661-
return None
662-
663-
if len(trace_ids) == 1:
664-
query = f"trace:{trace_ids[0]}"
665-
else:
666-
query = f"trace:[{','.join(trace_ids)}]"
667-
668-
# Table query for a single item that has one of the trace IDs.
669-
result = execute_table_query(
670-
org_id=organization.id,
671-
dataset="spans",
672-
per_page=1,
673-
fields=["trace"],
674-
query=query,
675-
sort="-timestamp",
676-
start=start.isoformat(),
677-
end=end.isoformat(),
678-
)
679-
680-
if not result or not result.get("data"):
681-
return None
682-
683-
return result["data"][0]["trace"]
684-
685-
686651
def _get_recommended_event(
687652
group: Group,
688653
organization: Organization,
@@ -907,7 +872,7 @@ def get_issue_and_event_details_v2(
907872

908873
if group is None:
909874
logger.warning(
910-
"get_issue_and_event_details: Missing group",
875+
"get_issue_and_event_details_v2: Missing group",
911876
extra={
912877
"organization_id": organization_id,
913878
"project_slug": project_slug,
@@ -919,7 +884,7 @@ def get_issue_and_event_details_v2(
919884

920885
if event is None:
921886
logger.warning(
922-
"get_issue_and_event_details: Missing event",
887+
"get_issue_and_event_details_v2: Missing event",
923888
extra={
924889
"organization_id": organization_id,
925890
"project_slug": project_slug,
@@ -937,230 +902,6 @@ def get_issue_and_event_details_v2(
937902
return get_issue_and_event_response(event, None, organization)
938903

939904

940-
def get_issue_and_event_details(
941-
*,
942-
organization_id: int,
943-
issue_id: str | None,
944-
selected_event: str,
945-
) -> dict[str, Any] | None:
946-
"""
947-
Tool to get details for a Sentry issue and one of its associated events. null issue_id can be passed so the
948-
is issue is looked up from the event. We assume the event is always associated with an issue, otherwise None is returned.
949-
950-
Args:
951-
organization_id: The ID of the organization to query.
952-
issue_id: The issue/group ID (numeric) or short ID (string) to look up. If None, we fill this in with the event's `group` property.
953-
selected_event:
954-
If issue_id is provided, this is the event to return and must exist in the issue - the options are "oldest", "latest", "recommended", or a UUID.
955-
If issue_id is not provided, this must be a UUID.
956-
957-
Returns:
958-
A dict containing:
959-
Issue fields: aside from `issue` these are nullable if an error occurred.
960-
`issue`: Serialized issue details.
961-
`tags_overview`: A summary of all tags in the issue.
962-
`event_timeseries`: Event counts over time for the issue.
963-
`timeseries_stats_period`: The stats period used for the event timeseries.
964-
`timeseries_interval`: The interval used for the event timeseries.
965-
966-
Event fields:
967-
`event`: Serialized event details.
968-
`event_id`: The event ID of the selected event.
969-
`event_trace_id`: The trace ID of the selected event. Nullable.
970-
`project_id`: The event and issue's project ID.
971-
`project_slug`: The event and issue's project slug.
972-
973-
Returns None when the requested event or issue is not found, or an error occurred.
974-
"""
975-
try:
976-
organization = Organization.objects.get(id=organization_id)
977-
except Organization.DoesNotExist:
978-
logger.warning(
979-
"Organization does not exist",
980-
extra={"organization_id": organization_id, "issue_id": issue_id},
981-
)
982-
return None
983-
984-
org_project_ids = list(
985-
Project.objects.filter(organization=organization, status=ObjectStatus.ACTIVE).values_list(
986-
"id", flat=True
987-
)
988-
)
989-
if not org_project_ids:
990-
return None
991-
992-
event: Event | GroupEvent | None = None
993-
group: Group
994-
995-
# Fetch the group object.
996-
if issue_id is None:
997-
# If issue_id is not provided, first find the event. Then use this to fetch the group.
998-
uuid.UUID(selected_event) # Raises ValueError if not valid UUID
999-
# We can't use get_event_by_id since we don't know the exact project yet.
1000-
events_result = eventstore.backend.get_events(
1001-
filter=eventstore.Filter(
1002-
event_ids=[selected_event],
1003-
organization_id=organization_id,
1004-
project_ids=org_project_ids,
1005-
),
1006-
limit=1,
1007-
tenant_ids={"organization_id": organization_id},
1008-
)
1009-
if not events_result:
1010-
logger.warning(
1011-
"Could not find the requested event ID",
1012-
extra={
1013-
"organization_id": organization_id,
1014-
"issue_id": issue_id,
1015-
"selected_event": selected_event,
1016-
},
1017-
)
1018-
return None
1019-
1020-
event = events_result[0]
1021-
assert event is not None
1022-
if event.group is None:
1023-
logger.warning(
1024-
"Event is not associated with a group",
1025-
extra={"organization_id": organization_id, "event_id": event.event_id},
1026-
)
1027-
return None
1028-
1029-
group = event.group
1030-
1031-
else:
1032-
# Fetch the group from issue_id.
1033-
try:
1034-
if issue_id.isdigit():
1035-
group = Group.objects.get(project_id__in=org_project_ids, id=int(issue_id))
1036-
else:
1037-
group = Group.objects.by_qualified_short_id(organization_id, issue_id)
1038-
1039-
except Group.DoesNotExist:
1040-
logger.warning(
1041-
"Requested issue does not exist for organization",
1042-
extra={"organization_id": organization_id, "issue_id": issue_id},
1043-
)
1044-
return None
1045-
1046-
# Get the issue data, tags overview, and event count timeseries.
1047-
serialized_group = dict(serialize(group, user=None, serializer=GroupSerializer()))
1048-
# Add issueTypeDescription as it provides better context for LLMs. Note the initial type should be BaseGroupSerializerResponse.
1049-
serialized_group["issueTypeDescription"] = group.issue_type.description
1050-
1051-
try:
1052-
tags_overview = get_all_tags_overview(group)
1053-
except Exception:
1054-
logger.exception(
1055-
"Failed to get tags overview for issue",
1056-
extra={"organization_id": organization_id, "issue_id": issue_id},
1057-
)
1058-
tags_overview = None
1059-
1060-
ts_result = _get_issue_event_timeseries(
1061-
organization=organization,
1062-
project_id=group.project_id,
1063-
issue_short_id=group.qualified_short_id,
1064-
first_seen_delta=datetime.now(UTC) - group.first_seen,
1065-
issue_category=group.issue_category,
1066-
)
1067-
if ts_result:
1068-
timeseries, timeseries_stats_period, timeseries_interval = ts_result
1069-
else:
1070-
timeseries, timeseries_stats_period, timeseries_interval = None, None, None
1071-
1072-
# Fetch event from group, if not already fetched.
1073-
if event is None:
1074-
if selected_event == "oldest":
1075-
event = group.get_oldest_event()
1076-
elif selected_event == "latest":
1077-
event = group.get_latest_event()
1078-
elif selected_event == "recommended":
1079-
event = group.get_recommended_event()
1080-
else:
1081-
uuid.UUID(selected_event) # Raises ValueError if not valid UUID
1082-
event = eventstore.backend.get_event_by_id(
1083-
project_id=group.project_id,
1084-
event_id=selected_event,
1085-
group_id=group.id,
1086-
tenant_ids={"organization_id": organization_id},
1087-
)
1088-
1089-
# If the recommended event (default when agent doesn't specify an event) doesn't have a useful trace, try finding a different event.
1090-
try:
1091-
if selected_event == "recommended" and (
1092-
event is None
1093-
or event.trace_id is None
1094-
or _get_trace_with_spans(
1095-
[event.trace_id],
1096-
organization,
1097-
group.first_seen - timedelta(days=1),
1098-
group.last_seen + timedelta(days=1),
1099-
)
1100-
is None
1101-
):
1102-
logger.info(
1103-
"No spans found for recommended event, trying a different event.",
1104-
extra={
1105-
"organization_id": organization_id,
1106-
"issue_id": group.id,
1107-
"recommended_event_id": event.event_id if event else None,
1108-
"event_trace_id": event.trace_id if event else None,
1109-
},
1110-
)
1111-
1112-
candidate_event = _get_recommended_event(group, organization)
1113-
if candidate_event:
1114-
event = candidate_event
1115-
1116-
logger.info(
1117-
"Replaced recommended event with an event with spans.",
1118-
extra={
1119-
"organization_id": organization_id,
1120-
"issue_id": group.id,
1121-
"candidate_event_id": candidate_event.event_id,
1122-
"candidate_event_trace_id": candidate_event.trace_id,
1123-
},
1124-
)
1125-
1126-
except Exception:
1127-
logger.exception(
1128-
"Error getting event with valid trace",
1129-
extra={
1130-
"organization_id": organization_id,
1131-
"issue_id": group.id,
1132-
"selected_event": selected_event,
1133-
},
1134-
)
1135-
1136-
if event is None:
1137-
logger.warning(
1138-
"Could not find the selected event.",
1139-
extra={
1140-
"organization_id": organization_id,
1141-
"issue_id": issue_id,
1142-
"selected_event": selected_event,
1143-
},
1144-
)
1145-
return None
1146-
1147-
# Serialize event.
1148-
serialized_event = serialize(event, user=None, serializer=EventSerializer())
1149-
1150-
return {
1151-
"issue": serialized_group,
1152-
"event_timeseries": timeseries,
1153-
"timeseries_stats_period": timeseries_stats_period,
1154-
"timeseries_interval": timeseries_interval,
1155-
"tags_overview": tags_overview,
1156-
"event": serialized_event,
1157-
"event_id": event.event_id,
1158-
"event_trace_id": event.trace_id,
1159-
"project_id": event.project_id,
1160-
"project_slug": event.project.slug,
1161-
}
1162-
1163-
1164905
def get_replay_metadata(
1165906
*,
1166907
replay_id: str,

0 commit comments

Comments
 (0)