Skip to content

Commit 3256564

Browse files
Rename PEP723 telemetry events to inlineScript
Trying an alphabetic prefix to debug why these events aren't reaching Kusto. The data platform team confirmed every other event from a test session arrived but the two PEP 723 ones were dropped without an explanation; one guess is the digits in the name/GDPR key are tripping something in ingestion. No behavior change otherwise — events are now inlineScript.detected / inlineScript.edited and the GDPR keys match the wire names exactly. Also aligned the enum names, jsdoc, test titles, and the comment in extension.ts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 28494bc commit 3256564

4 files changed

Lines changed: 49 additions & 49 deletions

File tree

src/common/telemetry/constants.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -212,24 +212,24 @@ export enum EventNames {
212212
/**
213213
* Telemetry event fired once per session, per URI, the first time a `.py`
214214
* file with a valid PEP 723 `# /// script` block is observed by the lazy
215-
* detector. Used to size the population of users who actually see PEP 723
216-
* files — the denominator for the "view vs edit" question.
215+
* detector. Used to size the population of users who actually see inline
216+
* script files — the denominator for the "view vs edit" question.
217217
* Properties:
218218
* - trigger: 'open' | 'save' (which workspace event surfaced the file)
219219
* - hasRequiresPython: boolean (whether the block declares `requires-python`)
220220
* Measures:
221221
* - dependencyCount: number (number of entries in the `dependencies` list)
222222
*/
223-
PEP723_DETECTED = 'PEP723.DETECTED',
223+
INLINE_SCRIPT_DETECTED = 'inlineScript.detected',
224224
/**
225225
* Telemetry event fired once per session, per URI, the first time a `.py`
226-
* file that previously raised a `PEP723.DETECTED` event receives a real
227-
* text edit. Together with `PEP723.DETECTED` this measures the fraction
228-
* of users who do more than view PEP 723 scripts.
226+
* file that previously raised an `inlineScript.detected` event receives a
227+
* real text edit. Together with `inlineScript.detected` this measures the
228+
* fraction of users who do more than view inline script files.
229229
* Measures:
230230
* - duration: number (ms between the detection and the first edit)
231231
*/
232-
PEP723_EDITED = 'PEP723.EDITED',
232+
INLINE_SCRIPT_EDITED = 'inlineScript.edited',
233233
}
234234

235235
// Map all events to their properties
@@ -707,23 +707,23 @@ export interface IEventNamePropertyMapping {
707707
};
708708

709709
/* __GDPR__
710-
"pep723.detected": {
710+
"inlineScript.detected": {
711711
"trigger": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "StellaHuang95" },
712712
"hasRequiresPython": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "StellaHuang95" },
713713
"dependencyCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "StellaHuang95" }
714714
}
715715
*/
716-
[EventNames.PEP723_DETECTED]: {
716+
[EventNames.INLINE_SCRIPT_DETECTED]: {
717717
trigger: 'open' | 'save';
718718
hasRequiresPython: boolean;
719719
// Goes through the measures payload (numeric); listed here for GDPR only.
720720
dependencyCount?: number;
721721
};
722722

723723
/* __GDPR__
724-
"pep723.edited": {
724+
"inlineScript.edited": {
725725
"<duration>": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "StellaHuang95" }
726726
}
727727
*/
728-
[EventNames.PEP723_EDITED]: never | undefined;
728+
[EventNames.INLINE_SCRIPT_EDITED]: never | undefined;
729729
}

src/extension.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
207207
);
208208

209209
// Silent observer for `.py` files that declare PEP 723 inline
210-
// script metadata. Emits anonymized telemetry (PEP723.DETECTED /
211-
// PEP723.EDITED) but does not register projects or surface any UI.
210+
// script metadata. Emits anonymized telemetry (inlineScript.detected /
211+
// inlineScript.edited) but does not register projects or surface any UI.
212212
const inlineScriptLazyDetector = new InlineScriptLazyDetector();
213213
inlineScriptLazyDetector.activate();
214214
context.subscriptions.push(inlineScriptLazyDetector);

src/features/inlineScriptLazyDetector.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ import {
2121
* every eligible `.py` file the user opens or saves and emits two
2222
* anonymized telemetry events:
2323
*
24-
* - `PEP723.DETECTED` once per (URI, session) the first time a
24+
* - `inlineScript.detected` once per (URI, session) the first time a
2525
* valid `# /// script` block is observed. This is the denominator
26-
* for the "how many users actually see PEP 723 files" question.
27-
* - `PEP723.EDITED` once per (URI, session) the first time a
26+
* for the "how many users actually see inline script files" question.
27+
* - `inlineScript.edited` once per (URI, session) the first time a
2828
* previously-detected file receives a real text edit. Together
29-
* with `DETECTED` this distinguishes viewers from editors.
29+
* with `inlineScript.detected` this distinguishes viewers from editors.
3030
*
3131
* No URIs, file paths, or file content are sent. The detector does
3232
* not register projects, surface UI, or otherwise change extension
@@ -41,11 +41,11 @@ export class InlineScriptLazyDetector implements Disposable {
4141
// doesn't double-process the same file.
4242
private readonly inFlight = new Map<string, Promise<void>>();
4343
// URIs (as `uri.toString()`) for which we have already emitted
44-
// `PEP723.DETECTED` in this session. Used to dedup the detection
45-
// event across repeat opens/saves and to gate `PEP723.EDITED` so
44+
// `inlineScript.detected` in this session. Used to dedup the detection
45+
// event across repeat opens/saves and to gate `inlineScript.edited` so
4646
// the latter only fires for files we already counted as detected.
4747
private readonly detectedUris = new Set<string>();
48-
// URIs for which we have already emitted `PEP723.EDITED` in this
48+
// URIs for which we have already emitted `inlineScript.edited` in this
4949
// session. Each detected file emits at most one edited event.
5050
private readonly editedUris = new Set<string>();
5151
// Wall-clock ms (from `Date.now`) at which each URI's detection
@@ -178,7 +178,7 @@ export class InlineScriptLazyDetector implements Disposable {
178178
this.detectionAtMs.set(key, Date.now());
179179
traceVerbose(`inlineScriptLazyDetector: detected inline script metadata in ${uri.fsPath} (${trigger})`);
180180
sendTelemetryEvent(
181-
EventNames.PEP723_DETECTED,
181+
EventNames.INLINE_SCRIPT_DETECTED,
182182
{ dependencyCount: metadata.dependencies?.length ?? 0 },
183183
{
184184
trigger,
@@ -194,11 +194,11 @@ export class InlineScriptLazyDetector implements Disposable {
194194
}
195195

196196
/**
197-
* Emit `PEP723.EDITED` the first time a previously-detected URI
197+
* Emit `inlineScript.edited` the first time a previously-detected URI
198198
* receives a real content change. The handler is hot (fires on
199199
* every keystroke in every text document workspace-wide) so it
200200
* bails out as cheaply as possible for the common case where the
201-
* file is not a tracked PEP 723 script.
201+
* file is not a tracked inline script.
202202
*/
203203
private handleChange(e: TextDocumentChangeEvent): void {
204204
if (this.disposed) {
@@ -222,7 +222,7 @@ export class InlineScriptLazyDetector implements Disposable {
222222
traceVerbose(
223223
`inlineScriptLazyDetector: first edit observed on ${e.document.uri.fsPath} (${duration}ms after detection)`,
224224
);
225-
sendTelemetryEvent(EventNames.PEP723_EDITED, duration);
225+
sendTelemetryEvent(EventNames.INLINE_SCRIPT_EDITED, duration);
226226
}
227227
}
228228

src/test/features/inlineScriptLazyDetector.unit.test.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ suite('InlineScriptLazyDetector', () => {
120120
changeListener!(makeChange(uri, changes));
121121
}
122122

123-
// Filter `sendTelemetryStub.getCalls()` to a single PEP 723 event name.
123+
// Filter `sendTelemetryStub.getCalls()` to a single inline script event name.
124124
function callsFor(name: EventNames): sinon.SinonSpyCall[] {
125125
return sendTelemetryStub.getCalls().filter((c) => c.args[0] === name);
126126
}
@@ -224,7 +224,7 @@ suite('InlineScriptLazyDetector', () => {
224224
// further work — including the detection telemetry event.
225225
resolveRead!(VALID_METADATA);
226226
await assert.doesNotReject(inFlight ?? Promise.resolve());
227-
assert.strictEqual(callsFor(EventNames.PEP723_DETECTED).length, 0, 'no detection event after dispose');
227+
assert.strictEqual(callsFor(EventNames.INLINE_SCRIPT_DETECTED).length, 0, 'no detection event after dispose');
228228
});
229229

230230
// ---------- catch-up replay over `getOpenTextDocuments` ----------
@@ -271,47 +271,47 @@ suite('InlineScriptLazyDetector', () => {
271271
assert.ok(readMetadataStub.notCalled, 'dispose() must clear the pending setImmediate handle');
272272
});
273273

274-
// ---------- PEP723.DETECTED telemetry ----------
274+
// ---------- inlineScript.detected telemetry ----------
275275

276-
test('PEP723.DETECTED fires once with trigger=open + dependencyCount + hasRequiresPython', async () => {
276+
test('inlineScript.detected fires once with trigger=open + dependencyCount + hasRequiresPython', async () => {
277277
const uri = Uri.file(path.resolve('/ws/detect.py'));
278278
readMetadataStub.resolves(VALID_METADATA);
279279
const detector = new InlineScriptLazyDetector();
280280
detector.activate();
281281
await fireOpen(uri);
282282

283-
const detectedCalls = callsFor(EventNames.PEP723_DETECTED);
283+
const detectedCalls = callsFor(EventNames.INLINE_SCRIPT_DETECTED);
284284
assert.strictEqual(detectedCalls.length, 1, 'detection event should fire exactly once');
285285
const [, measures, properties] = detectedCalls[0].args;
286286
assert.deepStrictEqual(measures, { dependencyCount: 2 });
287287
assert.deepStrictEqual(properties, { trigger: 'open', hasRequiresPython: true });
288288
detector.dispose();
289289
});
290290

291-
test('PEP723.DETECTED fires with trigger=save when surfaced by a save event', async () => {
291+
test('inlineScript.detected fires with trigger=save when surfaced by a save event', async () => {
292292
const uri = Uri.file(path.resolve('/ws/detectOnSave.py'));
293293
readMetadataStub.resolves(VALID_METADATA);
294294
const detector = new InlineScriptLazyDetector();
295295
detector.activate();
296296
await fireSave(uri);
297297

298-
const detectedCalls = callsFor(EventNames.PEP723_DETECTED);
298+
const detectedCalls = callsFor(EventNames.INLINE_SCRIPT_DETECTED);
299299
assert.strictEqual(detectedCalls.length, 1);
300300
assert.strictEqual(detectedCalls[0].args[2].trigger, 'save');
301301
detector.dispose();
302302
});
303303

304-
test('PEP723.DETECTED does not fire when the file has no metadata block', async () => {
304+
test('inlineScript.detected does not fire when the file has no metadata block', async () => {
305305
const uri = Uri.file(path.resolve('/ws/plain.py'));
306306
readMetadataStub.resolves(undefined);
307307
const detector = new InlineScriptLazyDetector();
308308
detector.activate();
309309
await fireOpen(uri);
310-
assert.strictEqual(callsFor(EventNames.PEP723_DETECTED).length, 0);
310+
assert.strictEqual(callsFor(EventNames.INLINE_SCRIPT_DETECTED).length, 0);
311311
detector.dispose();
312312
});
313313

314-
test('PEP723.DETECTED is deduplicated across repeated opens and saves of the same URI', async () => {
314+
test('inlineScript.detected is deduplicated across repeated opens and saves of the same URI', async () => {
315315
const uri = Uri.file(path.resolve('/ws/repeat.py'));
316316
readMetadataStub.resolves(VALID_METADATA);
317317
const detector = new InlineScriptLazyDetector();
@@ -320,11 +320,11 @@ suite('InlineScriptLazyDetector', () => {
320320
await fireSave(uri);
321321
await fireSave(uri);
322322
await fireOpen(uri);
323-
assert.strictEqual(callsFor(EventNames.PEP723_DETECTED).length, 1, 'detection event must dedup per session');
323+
assert.strictEqual(callsFor(EventNames.INLINE_SCRIPT_DETECTED).length, 1, 'detection event must dedup per session');
324324
detector.dispose();
325325
});
326326

327-
test('PEP723.DETECTED reports hasRequiresPython=false when not declared', async () => {
327+
test('inlineScript.detected reports hasRequiresPython=false when not declared', async () => {
328328
const uri = Uri.file(path.resolve('/ws/noPython.py'));
329329
readMetadataStub.resolves({
330330
requiresPython: undefined,
@@ -336,23 +336,23 @@ suite('InlineScriptLazyDetector', () => {
336336
detector.activate();
337337
await fireOpen(uri);
338338

339-
const [, measures, properties] = callsFor(EventNames.PEP723_DETECTED)[0].args;
339+
const [, measures, properties] = callsFor(EventNames.INLINE_SCRIPT_DETECTED)[0].args;
340340
assert.deepStrictEqual(measures, { dependencyCount: 0 });
341341
assert.deepStrictEqual(properties, { trigger: 'open', hasRequiresPython: false });
342342
detector.dispose();
343343
});
344344

345-
// ---------- PEP723.EDITED telemetry ----------
345+
// ---------- inlineScript.edited telemetry ----------
346346

347-
test('PEP723.EDITED fires once on first content change after detection', async () => {
347+
test('inlineScript.edited fires once on first content change after detection', async () => {
348348
const uri = Uri.file(path.resolve('/ws/edit.py'));
349349
readMetadataStub.resolves(VALID_METADATA);
350350
const detector = new InlineScriptLazyDetector();
351351
detector.activate();
352352
await fireOpen(uri);
353353
fireChange(uri);
354354

355-
const editedCalls = callsFor(EventNames.PEP723_EDITED);
355+
const editedCalls = callsFor(EventNames.INLINE_SCRIPT_EDITED);
356356
assert.strictEqual(editedCalls.length, 1, 'edited event should fire exactly once');
357357
// Second arg is the measure (number → { duration }); accept either form.
358358
const measureArg = editedCalls[0].args[1];
@@ -361,7 +361,7 @@ suite('InlineScriptLazyDetector', () => {
361361
detector.dispose();
362362
});
363363

364-
test('PEP723.EDITED is deduplicated across repeated edits of the same URI', async () => {
364+
test('inlineScript.edited is deduplicated across repeated edits of the same URI', async () => {
365365
const uri = Uri.file(path.resolve('/ws/multiEdit.py'));
366366
readMetadataStub.resolves(VALID_METADATA);
367367
const detector = new InlineScriptLazyDetector();
@@ -370,22 +370,22 @@ suite('InlineScriptLazyDetector', () => {
370370
fireChange(uri);
371371
fireChange(uri);
372372
fireChange(uri);
373-
assert.strictEqual(callsFor(EventNames.PEP723_EDITED).length, 1);
373+
assert.strictEqual(callsFor(EventNames.INLINE_SCRIPT_EDITED).length, 1);
374374
detector.dispose();
375375
});
376376

377-
test('PEP723.EDITED does not fire for changes on a URI that was never detected', async () => {
377+
test('inlineScript.edited does not fire for changes on a URI that was never detected', async () => {
378378
const uri = Uri.file(path.resolve('/ws/notDetected.py'));
379379
readMetadataStub.resolves(undefined);
380380
const detector = new InlineScriptLazyDetector();
381381
detector.activate();
382382
await fireOpen(uri);
383383
fireChange(uri);
384-
assert.strictEqual(callsFor(EventNames.PEP723_EDITED).length, 0);
384+
assert.strictEqual(callsFor(EventNames.INLINE_SCRIPT_EDITED).length, 0);
385385
detector.dispose();
386386
});
387387

388-
test('PEP723.EDITED ignores change events with no content changes', async () => {
388+
test('inlineScript.edited ignores change events with no content changes', async () => {
389389
const uri = Uri.file(path.resolve('/ws/noOpChange.py'));
390390
readMetadataStub.resolves(VALID_METADATA);
391391
const detector = new InlineScriptLazyDetector();
@@ -395,14 +395,14 @@ suite('InlineScriptLazyDetector', () => {
395395
// array for things like dirty-state toggles; that's not a user
396396
// edit and must not count.
397397
fireChange(uri, []);
398-
assert.strictEqual(callsFor(EventNames.PEP723_EDITED).length, 0);
398+
assert.strictEqual(callsFor(EventNames.INLINE_SCRIPT_EDITED).length, 0);
399399
// A real edit still counts after the no-op was ignored.
400400
fireChange(uri);
401-
assert.strictEqual(callsFor(EventNames.PEP723_EDITED).length, 1);
401+
assert.strictEqual(callsFor(EventNames.INLINE_SCRIPT_EDITED).length, 1);
402402
detector.dispose();
403403
});
404404

405-
test('PEP723.EDITED is suppressed after dispose()', async () => {
405+
test('inlineScript.edited is suppressed after dispose()', async () => {
406406
const uri = Uri.file(path.resolve('/ws/disposedEdit.py'));
407407
readMetadataStub.resolves(VALID_METADATA);
408408
const detector = new InlineScriptLazyDetector();
@@ -411,7 +411,7 @@ suite('InlineScriptLazyDetector', () => {
411411
const grabbedChangeListener = changeListener!;
412412
detector.dispose();
413413
grabbedChangeListener(makeChange(uri));
414-
assert.strictEqual(callsFor(EventNames.PEP723_EDITED).length, 0);
414+
assert.strictEqual(callsFor(EventNames.INLINE_SCRIPT_EDITED).length, 0);
415415
});
416416
});
417417

0 commit comments

Comments
 (0)