Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding telemetry for debugger time-to-start performance #7323

Merged
merged 2 commits into from
Sep 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/3 Code Health/7332.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add telemetry to measure debugger start up performance.
43 changes: 42 additions & 1 deletion src/client/datascience/debugLocationTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { injectable } from 'inversify';
import { DebugSession, Event, EventEmitter } from 'vscode';
import { DebugProtocol } from 'vscode-debugprotocol';

import { StopWatch } from '../common/utils/stopWatch';
import { AttachRequestArguments, ConsoleType, LaunchRequestArguments, TriggerType } from '../debugger/types';
import { sendTelemetryEvent } from '../telemetry';
import { EventName } from '../telemetry/constants';
import { IDebugLocation, IDebugLocationTracker } from './types';

// When a python debugging session is active keep track of the current debug location
Expand All @@ -13,10 +17,16 @@ export class DebugLocationTracker implements IDebugLocationTracker {
private waitingForStackTrace: boolean = false;
private _debugLocation: IDebugLocation | undefined;
private debugLocationUpdatedEvent: EventEmitter<void> = new EventEmitter<void>();
private trigger: TriggerType = 'launch';
private console: ConsoleType | undefined;
private timer = new StopWatch();

public setDebugSession(_targetSession: DebugSession) {
public setDebugSession(targetSession: DebugSession) {
this.DebugLocation = undefined;
this.waitingForStackTrace = false;
this.trigger = targetSession.configuration.type as TriggerType;
const debugConfiguration = targetSession.configuration as Partial<LaunchRequestArguments & AttachRequestArguments>;
this.console = debugConfiguration.console;
}

public get debugLocationUpdated(): Event<void> {
Expand All @@ -27,8 +37,20 @@ export class DebugLocationTracker implements IDebugLocationTracker {
return this._debugLocation;
}

public onWillStartSession() {
this.sendTelemetry(EventName.DEBUG_SESSION_START);
}

// tslint:disable-next-line:no-any
public onDidSendMessage(message: DebugProtocol.ProtocolMessage) {
if (message.type === 'response') {
const response = message as DebugProtocol.Response;
if (response.command === 'configurationDone') {
// "configurationDone" response is sent immediately after user code starts running.
this.sendTelemetry(EventName.DEBUG_SESSION_USER_CODE_RUNNING);
}
}

if (this.isStopEvent(message)) {
// Some type of stop, wait to see our next stack trace to find our location
this.waitingForStackTrace = true;
Expand All @@ -51,6 +73,14 @@ export class DebugLocationTracker implements IDebugLocationTracker {

}

public onWillStopSession() {
this.sendTelemetry(EventName.DEBUG_SESSION_STOP);
}

public onError?(_error: Error) {
this.sendTelemetry(EventName.DEBUG_SESSION_ERROR);
}

// Set our new location and fire our debug event
private set DebugLocation(newLocation: IDebugLocation | undefined) {
const oldLocation = this._debugLocation;
Expand Down Expand Up @@ -116,4 +146,15 @@ export class DebugLocationTracker implements IDebugLocationTracker {

return false;
}

private sendTelemetry(eventName: EventName) {
if (eventName === EventName.DEBUG_SESSION_START) {
this.timer.reset();
}
const telemetryProps = {
trigger: this.trigger,
console: this.console
};
sendTelemetryEvent(eventName, this.timer.elapsedTime, telemetryProps);
}
}
2 changes: 2 additions & 0 deletions src/client/debugger/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,5 @@ export interface AttachRequestArguments extends DebugProtocol.AttachRequestArgum
export interface DebugConfigurationArguments extends LaunchRequestArguments, AttachRequestArguments { }

export type ConsoleType = 'internalConsole' | 'integratedTerminal' | 'externalTerminal';

export type TriggerType = 'launch' | 'attach' | 'test';
4 changes: 4 additions & 0 deletions src/client/telemetry/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export enum EventName {
WORKSPACE_SYMBOLS_GO_TO = 'WORKSPACE_SYMBOLS.GO_TO',
EXECUTION_CODE = 'EXECUTION_CODE',
EXECUTION_DJANGO = 'EXECUTION_DJANGO',
DEBUG_SESSION_ERROR = 'DEBUG_SESSION.ERROR',
DEBUG_SESSION_START = 'DEBUG_SESSION.START',
DEBUG_SESSION_STOP = 'DEBUG_SESSION.STOP',
DEBUG_SESSION_USER_CODE_RUNNING = 'DEBUG_SESSION.USER_CODE_RUNNING',
DEBUGGER = 'DEBUGGER',
DEBUGGER_ATTACH_TO_CHILD_PROCESS = 'DEBUGGER.ATTACH_TO_CHILD_PROCESS',
DEBUGGER_CONFIGURATION_PROMPTS = 'DEBUGGER.CONFIGURATION.PROMPTS',
Expand Down
98 changes: 95 additions & 3 deletions src/client/telemetry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { TerminalShellType } from '../common/terminal/types';
import { StopWatch } from '../common/utils/stopWatch';
import { Telemetry } from '../datascience/constants';
import { DebugConfigurationType } from '../debugger/extension/types';
import { ConsoleType } from '../debugger/types';
import { ConsoleType, TriggerType } from '../debugger/types';
import { AutoSelectionRule } from '../interpreter/autoSelection/types';
import { InterpreterType } from '../interpreter/contracts';
import { LinterId } from '../linters/types';
Expand Down Expand Up @@ -267,6 +267,98 @@ export interface IEventNamePropertyMapping {
*/
enabled: boolean;
};
/**
* Telemetry captured before starting debug session.
*/
[EventName.DEBUG_SESSION_START]: {
/**
* Trigger for starting the debugger.
* - `launch`: Launch/start new code and debug it.
* - `attach`: Attach to an exiting python process (remote debugging).
* - `test`: Debugging python tests.
*
* @type {TriggerType}
*/
trigger: TriggerType;
/**
* Type of console used.
* -`internalConsole`: Use VS Code debug console (no shells/terminals).
* - `integratedTerminal`: Use VS Code terminal.
* - `externalTerminal`: Use an External terminal.
*
* @type {ConsoleType}
*/
console?: ConsoleType;
};
/**
* Telemetry captured when debug session runs into an error.
*/
[EventName.DEBUG_SESSION_ERROR]: {
/**
* Trigger for starting the debugger.
* - `launch`: Launch/start new code and debug it.
* - `attach`: Attach to an exiting python process (remote debugging).
* - `test`: Debugging python tests.
*
* @type {TriggerType}
*/
trigger: TriggerType;
/**
* Type of console used.
* -`internalConsole`: Use VS Code debug console (no shells/terminals).
* - `integratedTerminal`: Use VS Code terminal.
* - `externalTerminal`: Use an External terminal.
*
* @type {ConsoleType}
*/
console?: ConsoleType;
};
/**
* Telemetry captured after stopping debug session.
*/
[EventName.DEBUG_SESSION_STOP]: {
/**
* Trigger for starting the debugger.
* - `launch`: Launch/start new code and debug it.
* - `attach`: Attach to an exiting python process (remote debugging).
* - `test`: Debugging python tests.
*
* @type {TriggerType}
*/
trigger: TriggerType;
/**
* Type of console used.
* -`internalConsole`: Use VS Code debug console (no shells/terminals).
* - `integratedTerminal`: Use VS Code terminal.
* - `externalTerminal`: Use an External terminal.
*
* @type {ConsoleType}
*/
console?: ConsoleType;
};
/**
* Telemetry captured when user code starts running after loading the debugger.
*/
[EventName.DEBUG_SESSION_USER_CODE_RUNNING]: {
/**
* Trigger for starting the debugger.
* - `launch`: Launch/start new code and debug it.
* - `attach`: Attach to an exiting python process (remote debugging).
* - `test`: Debugging python tests.
*
* @type {TriggerType}
*/
trigger: TriggerType;
/**
* Type of console used.
* -`internalConsole`: Use VS Code debug console (no shells/terminals).
* - `integratedTerminal`: Use VS Code terminal.
* - `externalTerminal`: Use an External terminal.
*
* @type {ConsoleType}
*/
console?: ConsoleType;
};
/**
* Telemetry captured when starting the debugger.
*/
Expand All @@ -277,9 +369,9 @@ export interface IEventNamePropertyMapping {
* - `attach`: Attach to an exiting python process (remote debugging).
* - `test`: Debugging python tests.
*
* @type {('launch' | 'attach' | 'test')}
* @type {TriggerType}
*/
trigger: 'launch' | 'attach' | 'test';
trigger: TriggerType;
/**
* Type of console used.
* -`internalConsole`: Use VS Code debug console (no shells/terminals).
Expand Down