feat(autopilot): Add trace data detector#107589
Conversation
src/sentry/autopilot/tasks.py
Outdated
| """ | ||
| try: | ||
| organization = Organization.objects.get(id=organization_id) | ||
| project = Project.objects.get(id=project_id) |
There was a problem hiding this comment.
This should probably also query for active projects only
| project = Project.objects.get(id=project_id) | |
| project = Project.objects.get(id=project_id, status=ObjectStatus.ACTIVE) |
| "trace_id": trace_id, | ||
| }, | ||
| ) | ||
| return None |
There was a problem hiding this comment.
Bit of a nit but I think it's useful: since we have so much defensive logic, this has become quite unwieldy and hard to read - can we factor out the logical parts into functions to make it more easily readable?
From what I can tell this task does this with a lot of o11y:
trace_metadata = sample_trace_for_instrumentation_analysis(project)
eap_trace = get_trace_waterfall(trace_id=trace_id,organization_id=organization.id)
client = SeerExplorerClient(
organization,
user=None,
category_key=AutopilotDetectorName.TRACE_INSTRUMENTATION,
category_value=str(trace_id),
intelligence_level="medium",
)
check_trace_length()
prompt = _build_instrumentation_prompt(trace_json, project.slug)
create_instrumentation_issue(
project_id=project.id,
detector_name=AutopilotDetectorName.TRACE_INSTRUMENTATION,
title=issue.title,
subtitle=issue.subcategory,
description=f"{issue.explanation}\n\n"
f"**Impact**: {issue.impact}\n\n"
f"**Evidence**: {issue.evidence}\n\n"
f"**Missing Telemetry**: {issue.missing_telemetry or 'Not specified'}\n\n"
f"**Affected Spans**: {', '.join(issue.offender_span_ids)}",
)
There was a problem hiding this comment.
yeah agree, that should be solved nicer. I have a follow-up task to split tasks.py into multiple files. Then I would also split this one up and it remains clear to which detector the single util functions belong.
tests/sentry/autopilot/test_tasks.py
Outdated
| trace_id="abc123", | ||
| transaction_name="GET /api/users", | ||
| ) | ||
| mock_get_traces.return_value = [expected_trace] |
There was a problem hiding this comment.
Instead of mocks, we should be using the test factories made available to actually ingest traces, etc. and then retrieve them from storage
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
First draft of the trace based instrumentation issue detector. This PR's main focus is on creating the framework (fetching data, handling responses). The prompt is to be treated as a placeholder and will undergo further optimizations in follow-up PRs.
First draft of the trace based instrumentation issue detector. This PR's main focus is on creating the framework (fetching data, handling responses). The prompt is to be treated as a placeholder and will undergo further optimizations in follow-up PRs.
First draft of the trace based instrumentation issue detector.
This PR's main focus is on creating the framework (fetching data, handling responses).
The prompt is to be treated as a placeholder and will undergo further optimizations in follow-up PRs.