Commit 7fb4c06
Add PET version, build ID, and commit SHA to telemetry (microsoft#1574)
## Context
PET (Python Environment Tools) is the Rust JSON-RPC service this
extension uses to discover Python environments. PET ships independently
of the extension and is bundled as a binary inside the VSIX, so the PET
version a user is running can drift from the extension version. When we
see a performance regression or a failure in PET telemetry today, we
have no way to map it back to the **exact PET source code** the user is
running — we know `pet --version` (already telemetered via
`PET.VERSION`) but a single PET version line can correspond to many
commits across multiple builds.
This PR closes that gap by stamping every PET telemetry event with the
binary's `petVersion`, `petBuildId`, and `petCommitSha`, sourced
directly from the running PET process via a new `info` JSON-RPC request.
We can then `summarize by petCommitSha` in Kusto and join straight to
git log to find the offending change.
## Related PRs
PET side (both merged):
- microsoft/python-environment-tools#470 — adds the `info` JSON-RPC
request returning `petVersion` and optional `buildId`
- microsoft/python-environment-tools#473 — extends the `info` response
with optional `commitSha` baked in from CI env vars (`PET_COMMIT_SHA` /
`BUILD_SOURCEVERSION` / `GITHUB_SHA`)
Supersedes / replaces:
- microsoft#1548 — earlier draft that only added `petVersion` + `petBuildId` and
accidentally corrupted the enum docstring for `PET_RESOLVE` /
`MIGRATION_SYSTEM_ENV_MANAGER`. Please close.
## What this PR does
1. **Defines a typed `NativePetInfo` interface** matching PET's `info`
response shape (`petVersion: string`, `buildId?: string`, `commitSha?:
string`).
2. **Sends one `info` RPC per PET process start** in
`kickoffInfoFetch(connection)`, called immediately after
`connection.listen()` inside `start()`. The call is **fire-and-forget**
with a 2 s timeout — `start()` does not await it, so discovery is never
blocked. The response is cached in `this.petInfo` for the lifetime of
that PET process. `this.petInfo` is reset to `undefined` on every
`start()` (initial spawn + every crash-recovery restart).
3. **Guards against stale responses** via `connection !==
this.connection` checks in both `.then` and `.catch`, so a late reply
from a previous PET process can't clobber the cache of a newer one after
a restart.
4. **Spreads `getPetInfoProperties()` into the six existing PET
telemetry call sites** (success + error paths of `PET_RESOLVE`,
`PET_REFRESH`, `PET_PROCESS_RESTART`). The helper always returns
concrete strings, defaulting each field to `'unknown'`, so Kusto
group-bys work without null handling.
5. **Adds GDPR comments + TypeScript types** for the three new fields on
`PET_RESOLVE`, `PET_REFRESH`, `PET_PROCESS_RESTART`. All classified as
`SystemMetaData` / `PerformanceAndHealth`.
## Files changed
| File | Why |
|---|---|
| `src/managers/common/nativePythonFinder.ts` | `INFO_TIMEOUT_MS`
constant, `NativePetInfo` interface, `petInfo` field, `kickoffInfoFetch`
+ `getPetInfoProperties` helpers, kickoff wiring in `start()`, payload
spread at six telemetry sites |
| `src/common/telemetry/constants.ts` | New `petVersion` / `petBuildId`
/ `petCommitSha` properties on `PET_RESOLVE`, `PET_REFRESH`,
`PET_PROCESS_RESTART` (GDPR blocks + TS types) |
## Compatibility with older PET binaries
The extension currently ships PET as a bundled binary (downloaded by the
Azure pipelines from PET CI artifacts). Until the PET release branch
picks up microsoft#470 / microsoft#473, the bundled binary won't have the `info` handler.
In that case:
- PET responds with JSON-RPC error code `-1` (`Failed to find handler
for request info`)
- `sendRequestWithTimeout` rejects → `.catch` swallows → `petInfo` stays
`undefined`
- All three telemetry properties report `'unknown'`
- One harmless `[pet] Failed to find handler for method: info` line
surfaces from PET's stderr into the Python Environments output channel
Discovery, refresh, resolve, and restart all continue to work normally.
No crash, no functional regression — just `'unknown'` values in
telemetry until PET catches up.
## Crash attribution semantics
A subtle but important detail of where the spread is placed: the
crashing PET's commit hash **is** captured in `PET_REFRESH` /
`PET_RESOLVE` error events because we call `sendTelemetryEvent(...,
...this.getPetInfoProperties())` **before** killing the process and
resetting the cache. So when a user reports "PET crashed during
refresh", we can identify which exact commit was running.
The `PET_PROCESS_RESTART` success event itself reports `'unknown'` for
the **new** PET (its `info` reply usually hasn't landed in the few ms
between `start()` and the telemetry call), but the new binary's identity
surfaces on the very next refresh/resolve.
## Performance impact
- One extra JSON-RPC roundtrip **per PET process lifetime** (typically
once per VS Code session), not per telemetry event
- ~3 string allocations per telemetry event from the spread — invisible
against existing payload assembly
- `kickoffInfoFetch` returns `void` synchronously; the response runs on
the microtask queue and never blocks refresh/resolve
- 2 s timeout caps the worst case if PET hangs entirely
## Validation
- `npm run lint` ✅
- `npx tsc -p . --noEmit` ✅
- `npm run compile-tests` ✅
- `npm run unittest` — 1141 passing, 2 pending (unchanged from baseline)
✅
- `npm run compile` (webpack production bundle) ✅
## Manual testing
To get non-`'unknown'` values locally, build PET from main and drop the
binary into `python-env-tools/bin/`:
```powershell
# In the PET repo:
$env:PET_COMMIT_SHA = (git rev-parse HEAD)
$env:PET_BUILD_ID = "local-dev"
cargo build --release --package pet
# In this repo:
Copy-Item <pet-repo>\target\release\pet.exe .\python-env-tools\bin\pet.exe -Force
```
Then F5 → open the Python Environments view → run `Python Environments:
Refresh Environments`. Set the Python Environments output channel to
Debug level to see the `[pet] info: { petVersion, buildId, commitSha }`
line confirming the cache was populated.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Eleanor Boyd <26030610+eleanorjboyd@users.noreply.github.com>1 parent 34c9e53 commit 7fb4c06
2 files changed
Lines changed: 106 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
593 | 593 | | |
594 | 594 | | |
595 | 595 | | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
596 | 599 | | |
597 | 600 | | |
598 | 601 | | |
| |||
615 | 618 | | |
616 | 619 | | |
617 | 620 | | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
618 | 627 | | |
619 | 628 | | |
620 | 629 | | |
| |||
639 | 648 | | |
640 | 649 | | |
641 | 650 | | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
642 | 654 | | |
643 | 655 | | |
644 | 656 | | |
| |||
654 | 666 | | |
655 | 667 | | |
656 | 668 | | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
657 | 675 | | |
658 | 676 | | |
659 | 677 | | |
660 | 678 | | |
661 | 679 | | |
662 | 680 | | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
663 | 684 | | |
664 | 685 | | |
665 | 686 | | |
666 | 687 | | |
667 | 688 | | |
668 | 689 | | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
669 | 696 | | |
670 | 697 | | |
671 | 698 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
| |||
265 | 266 | | |
266 | 267 | | |
267 | 268 | | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
268 | 280 | | |
269 | 281 | | |
270 | 282 | | |
| |||
322 | 334 | | |
323 | 335 | | |
324 | 336 | | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
325 | 344 | | |
326 | 345 | | |
327 | 346 | | |
| |||
353 | 372 | | |
354 | 373 | | |
355 | 374 | | |
356 | | - | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
357 | 379 | | |
358 | 380 | | |
359 | 381 | | |
| |||
376 | 398 | | |
377 | 399 | | |
378 | 400 | | |
| 401 | + | |
379 | 402 | | |
380 | 403 | | |
381 | 404 | | |
| |||
460 | 483 | | |
461 | 484 | | |
462 | 485 | | |
| 486 | + | |
463 | 487 | | |
464 | 488 | | |
465 | 489 | | |
| |||
468 | 492 | | |
469 | 493 | | |
470 | 494 | | |
471 | | - | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
472 | 502 | | |
473 | 503 | | |
474 | 504 | | |
| |||
701 | 731 | | |
702 | 732 | | |
703 | 733 | | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
704 | 739 | | |
705 | 740 | | |
706 | 741 | | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
707 | 782 | | |
708 | 783 | | |
709 | 784 | | |
| |||
840 | 915 | | |
841 | 916 | | |
842 | 917 | | |
| 918 | + | |
843 | 919 | | |
844 | 920 | | |
845 | 921 | | |
| |||
853 | 929 | | |
854 | 930 | | |
855 | 931 | | |
| 932 | + | |
856 | 933 | | |
857 | 934 | | |
858 | 935 | | |
| |||
0 commit comments