Track CLI invocation source and full command#1293
Conversation
|
There is two pending items though, would like to have an opinion on how to proceed
|
3d78b59 to
8d52688
Compare
|
Ok I think I'm gonna truncate the raw command to 2000 characters |
| exit_code = e.code if isinstance(e.code, int) else 1 | ||
| finally: | ||
| try: | ||
| send_command_tracking(argv=argv, exit_code=exit_code) |
There was a problem hiding this comment.
Can we invoke the CLI tracking asynchronously instead of blocking the execution?
There was a problem hiding this comment.
It is invoked when all the command is processed already, and the CLI is about to exit. Asynchronous execution here might not be needed.
There was a problem hiding this comment.
While it's true that tracking happens in the finally block after the command completes,
the HTTP request still blocks the CLI exit. This means every user waits an extra
50-200ms (or more with slow networks) for the tracking call to complete
There was a problem hiding this comment.
But since the CLI is about to exit, we have these options
- Forking: But forking will add extra overhead and might not be worth
- Daemon threads or asyncio process get killed the moment
sys.exit()is called
But these are not helpful unless we change the shutdown process some how.
I will add a short timeout, because if the server is unreachable, the cli will hang, this is more of an issue.
Addresses LCHUX-315. The backend can now identify whether CLI
invocations come from direct usage, our GitHub Action wrapper, or
another integration by reading the User-Agent header on every request.
- SMART_TESTS_CALLER env var (defaults to "cli") lets wrappers
identify themselves (e.g. github-action, jenkins-plugin)
- detect_ci_provider() auto-detects the CI environment from standard
env vars (GITHUB_ACTIONS, JENKINS_URL, CIRCLECI, CODEBUILD_BUILD_ID)
- Both values are appended to User-Agent as Caller/{value} CI/{value}
- Both values are also included in the cli_tracking payload
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add test_tracking.py covering detect_ci_provider() and caller/ ciProvider fields in tracking payloads - Add User-Agent tests for caller and CI provider segments - Replace clear=True with surgical env cleanup in test_http_client.py to avoid wiping SMART_TESTS_BASE_URL (same issue as PR #1279) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add send_command_tracking() to send a COMMAND_INVOCATION event with the full CLI argv, exit code, caller, and CI provider in metadata - Add _detect_command() to map argv to Command enum values; falls back to UNKNOWN for typos or unrecognized commands - Refactor TrackingClient: extract construct_payload() from _post_payload() so both send_command_tracking and existing methods share payload construction - Move caller/ciProvider into metadata JSONB (not top-level fields) - Add UNKNOWN and COMMAND_INVOCATION to respective enums Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Capture sys.argv and exit code, send COMMAND_INVOCATION tracking event after every CLI run (including typos and failures). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Caller and CI provider are now sent via cli_tracking metadata only. Remove Caller/ and CI/ segments from User-Agent header. Update test_tracking with tests for _detect_command, send_command_tracking, and caller/ciProvider in metadata. Revert test_http_client to original User-Agent assertions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add record attachment, inspect model, inspect subset, stats test_sessions, compare subsets, and get docs to both the Command enum and _COMMAND_MAP. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lues Also adds individual detection tests for the 7 newly mapped commands. If a new Command is added to the enum without updating _COMMAND_MAP, test_command_map_covers_all_enum_values will fail. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1c9cb77 to
228ca35
Compare
…considering option values as commands
…command identification
| metadata["stackTrace"] = stack_trace | ||
| metadata["organization"] = org or "" | ||
| metadata["workspace"] = workspace or "" | ||
| metadata["api"] = api |
There was a problem hiding this comment.
Why did you leave stackTrace and api in this method instead of putting them in construct_payload method?
There was a problem hiding this comment.
That was intentional because the stackTrace and api are visible to only send_error_event(). And that method can create a partial metadata dict with those values already. It is similar to other method like send_event() and send_command_tracking() where a partial metadata is generated with values under that specific method's scope.
Summary
COMMAND_INVOCATIONtracking event on every CLI invocation with the full command string (rawCommand), exit code, caller, and CI providerCommandenum, falls back toUNKNOWNfor typos)SMART_TESTS_CALLERenv var lets wrappers (e.g. GitHub Action) identify themselvesGITHUB_ACTIONS,JENKINS_URL,CIRCLECI,CODEBUILD_BUILD_ID)caller,ciProvider,exitCodesent insidemetadataJSONB — no DB migration neededTest plan
_detect_command()across all commands + typos + global optionssend_command_tracking()payload structurecaller/ciProviderin metadata for all event types