Skip to content

Add PET version, build ID, and commit SHA to telemetry#1574

Merged
StellaHuang95 merged 2 commits into
microsoft:mainfrom
StellaHuang95:pet-info-telemetry
Jun 10, 2026
Merged

Add PET version, build ID, and commit SHA to telemetry#1574
StellaHuang95 merged 2 commits into
microsoft:mainfrom
StellaHuang95:pet-info-telemetry

Conversation

@StellaHuang95

Copy link
Copy Markdown
Contributor

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):

Supersedes / replaces:

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 #470 / #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/:

# 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.

Stamp every PET telemetry event with the running binary's identity so we
can correlate user-reported issues and performance regressions back to a
specific PET commit.

- Adds a fire-and-forget `info` JSON-RPC call once per PET process start
  and caches the response (petVersion, buildId, commitSha) for the
  process's lifetime.
- Spreads those three fields into PET_REFRESH, PET_RESOLVE, and
  PET_PROCESS_RESTART telemetry events.
- Pairs with PET PRs microsoft/python-environment-tools#470 and microsoft#473 which
  added the `info` request and the commit SHA field.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@StellaHuang95 StellaHuang95 merged commit 7fb4c06 into microsoft:main Jun 10, 2026
40 of 44 checks passed
@StellaHuang95 StellaHuang95 deleted the pet-info-telemetry branch June 10, 2026 21:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants