Skip to content

Commit

Permalink
REPL Telemetry for Terminal REPL and Native REPL (#23941)
Browse files Browse the repository at this point in the history
Resolves: #23740 

Also organize Telemetry for Terminal REPL vs. Native REPL.
Now we can sort them out with new attribute 'replType' on the REPL
Event.

With this PR:
- (EventName.REPL, { replType: 'Terminal' }) for when people launch
Terminal REPL via Command Palette, Manually type Python in terminal
(tried to account for all Python cases that will trigger REPL).
- (EventName.REPL, { replType: 'Native' }) for when people launch Native
REPL via Command Palette.

---------

Co-authored-by: Karthik Nadig <[email protected]>
  • Loading branch information
anthonykim1 and karthiknadig authored Aug 13, 2024
1 parent f417024 commit c13bb07
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/client/extensionActivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { logAndNotifyOnLegacySettings } from './logging/settingLogs';
import { DebuggerTypeName } from './debugger/constants';
import { StopWatch } from './common/utils/stopWatch';
import { registerReplCommands, registerReplExecuteOnEnter, registerStartNativeReplCommand } from './repl/replCommands';
import { registerTriggerForTerminalREPL } from './terminals/codeExecution/terminalReplWatcher';

export async function activateComponents(
// `ext` is passed to any extra activation funcs.
Expand Down Expand Up @@ -108,6 +109,7 @@ export function activateFeatures(ext: ExtensionState, _components: Components):
);
const executionHelper = ext.legacyIOC.serviceContainer.get<ICodeExecutionHelper>(ICodeExecutionHelper);
const commandManager = ext.legacyIOC.serviceContainer.get<ICommandManager>(ICommandManager);
registerTriggerForTerminalREPL(ext.disposables);
registerStartNativeReplCommand(ext.disposables, interpreterService);
registerReplCommands(ext.disposables, interpreterService, executionHelper, commandManager);
registerReplExecuteOnEnter(ext.disposables, interpreterService, commandManager);
Expand Down
2 changes: 1 addition & 1 deletion src/client/providers/replProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class ReplProvider implements Disposable {
this.disposables.push(disposable);
}

@captureTelemetry(EventName.REPL)
@captureTelemetry(EventName.REPL, { replType: 'Terminal' })
private async commandHandler() {
const resource = this.activeResourceService.getActiveResource();
const interpreterService = this.serviceContainer.get<IInterpreterService>(IInterpreterService);
Expand Down
4 changes: 3 additions & 1 deletion src/client/repl/replCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
isMultiLineText,
} from './replUtils';
import { registerCommand } from '../common/vscodeApis/commandApis';
import { sendTelemetryEvent } from '../telemetry';
import { EventName } from '../telemetry/constants';

/**
* Register Start Native REPL command in the command palette
Expand All @@ -30,6 +32,7 @@ export async function registerStartNativeReplCommand(
): Promise<void> {
disposables.push(
registerCommand(Commands.Start_Native_REPL, async (uri: Uri) => {
sendTelemetryEvent(EventName.REPL, undefined, { replType: 'Native' });
const interpreter = await getActiveInterpreter(uri, interpreterService);
if (interpreter) {
if (interpreter) {
Expand Down Expand Up @@ -61,7 +64,6 @@ export async function registerReplCommands(
await executeInTerminal();
return;
}

const interpreter = await getActiveInterpreter(uri, interpreterService);

if (interpreter) {
Expand Down
9 changes: 7 additions & 2 deletions src/client/telemetry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2305,10 +2305,15 @@ export interface IEventNamePropertyMapping {
*/
/* __GDPR__
"repl" : {
"duration" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "karthiknadig" }
"duration" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "anthonykim1" }
}
*/
[EventName.REPL]: never | undefined;
[EventName.REPL]: {
/**
* Whether the user launched the Terminal REPL or Native REPL
*/
replType: 'Terminal' | 'Native';
};
/**
* Telemetry event sent if and when user configure tests command. This command can be trigerred from multiple places in the extension. (Command palette, prompt etc.)
*/
Expand Down
19 changes: 19 additions & 0 deletions src/client/terminals/codeExecution/terminalReplWatcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Disposable, TerminalShellExecutionStartEvent } from 'vscode';
import { onDidStartTerminalShellExecution } from '../../common/vscodeApis/windowApis';
import { sendTelemetryEvent } from '../../telemetry';
import { EventName } from '../../telemetry/constants';

function checkREPLCommand(command: string): boolean {
const lower = command.toLowerCase().trimStart();
return lower.startsWith('python ') || lower.startsWith('py ');
}

export function registerTriggerForTerminalREPL(disposables: Disposable[]): void {
disposables.push(
onDidStartTerminalShellExecution(async (e: TerminalShellExecutionStartEvent) => {
if (e.execution.commandLine.isTrusted && checkREPLCommand(e.execution.commandLine.value)) {
sendTelemetryEvent(EventName.REPL, undefined, { replType: 'Terminal' });
}
}),
);
}

0 comments on commit c13bb07

Please sign in to comment.