Skip to content

Conversation

@shashjar
Copy link
Member

@shashjar shashjar commented Dec 26, 2025

The RelatedIssuesEndpoint has logic which can retrieve issues associated with the same trace as the one included in the request. This PR adds logic which uses an EndpointTraceItemTable RPC query to retrieve trace-connected issues.

Tested locally to ensure that the reads are succeeding and the results are matching that of the legacy Snuba read path:

sentry.issues.related.trace_connected: Snuba results: [18, 19]

sentry.utils.snuba_rpc: Running a EndpointTraceItemTable RPC query (
  rpc_query={
    'meta': {
      'organizationId': '1',
      'referrer': 'api.issues.related_issues',
      'projectIds': ['1', '2', '3'],
      'startTimestamp': '2025-09-30T21:07:44.639036Z',
      'endTimestamp': '2025-12-29T21:07:44.639036Z',
      'traceItemType': 'TRACE_ITEM_TYPE_OCCURRENCE',
      'downsampledStorageConfig': {'mode': 'MODE_HIGHEST_ACCURACY'}
    },
    'columns': [
      {'key': {'type': 'TYPE_INT', 'name': 'group_id'}, 'label': 'group_id'},
      {'aggregation': {'aggregate': 'FUNCTION_COUNT', 'key': {'type': 'TYPE_INT', 'name': 'sentry.project_id'}, 'label': 'count()', 'extrapolationMode': 'EXTRAPOLATION_MODE_SAMPLE_WEIGHTED'}, 'label': 'count()'}
    ],
    'filter': {
      'comparisonFilter': {
        'key': {'type': 'TYPE_STRING', 'name': 'sentry.trace_id'},
        'op': 'OP_EQUALS',
        'value': {'valStr': '4bf92f3577b34da6a3ce929d0e0e4736'}
      }
    },
    'groupBy': [{'type': 'TYPE_INT', 'name': 'group_id'}],
    'limit': 100,
    'pageToken': {'offset': '0'}
  }
  referrer='api.issues.related_issues'
  organization_id=1
  trace_item_type=7
)

sentry.utils.snuba_rpc: Table RPC query response (
  rpc_rows=3
  organization_id=1
  page_token=offset: 3
  meta=request_id: "941d7f60e1374414a81690b59f5fe218"
  query_info { stats { progress_bytes: 780 } metadata { } }
  downsampled_storage_meta { }
)

sentry.issues.related.trace_connected: Raw EAP results: {
  'data': [
    {'group_id': 18, 'count()': 2.0},
    {'group_id': 19, 'count()': 1.0},
    {'group_id': 17, 'count()': 3.0}
  ],
  'meta': {'fields': {'group_id': 'integer', 'count()': 'integer'}, 'full_scan': True, 'bytes_scanned': 780},
  'confidence': [{'count()': 'high'}, {'count()': 'high'}, {'count()': 'high'}]
}

sentry.issues.related.trace_connected: EAP results: [18, 19]

sentry.issues.related.trace_connected: Snuba results same as EAP results: True

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Dec 26, 2025
result = Occurrences.run_table_query(
params=snuba_params,
query_string=f"trace:{trace_id}",
selected_columns=["group_id", "count()"],
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a count() here in order to get distinct group IDs back

@shashjar shashjar requested review from a team and thetruecpaul December 29, 2025 21:15
@shashjar shashjar marked this pull request as ready for review December 29, 2025 21:16
@shashjar shashjar requested review from a team as code owners December 29, 2025 21:16
@shashjar shashjar removed request for a team December 29, 2025 21:17
Copy link
Contributor

@thetruecpaul thetruecpaul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some nits/ Qs

gid = int(group_id)
if gid != exclude_group_id:
group_ids.add(gid)
return list(group_ids)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any expectation of ordering from this endpoint?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe so, since the Snuba implementation also relies on a set. But this does raise a good point in that our Snuba/EAP result comparisons will potentially mismatch even when the group ID sets are the same, since we're comparing the lists instead of the sets. Going to refactor these functions to return the set values so we can check_and_choose on those instead, and then the endpoint can convert to list before returning.

except Exception:
logger.exception(
"Fetching trace connected issues from EAP failed",
extra={
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you log the actual exception message as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe logger.exception automatically captures the exception value when used in an except block

projects=projects,
exclude_group_id=group.id,
)
issues = EAPOccurrencesComparator.check_and_choose(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Is there a way to do a reasonable-comparison here? (EAP subset of Snuba?)
  • Can you add is-null-result here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, good idea. I'll refactor to do the exact match comparison using the set versions, and then also add a reasonable match comparator checking if the EAP version is a subset of the Snuba version. And sure, I'll add the is_experimental_data_a_null_result param for when the EAP result is empty.

@@ -0,0 +1,155 @@
from unittest import mock
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I see you've added empty file tests/sentry/issues/related/__init__.py. Is this intentional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I believe necessary for the directory to be picked up as a py module

@shashjar shashjar merged commit b8772bc into master Dec 31, 2025
65 checks passed
@shashjar shashjar deleted the double-read-trace-connected-issues-from-eap-for-related-issues branch December 31, 2025 18:55
@github-actions github-actions bot locked and limited conversation to collaborators Jan 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants