From 47a5cd84021d32c45c2beab0eed1eb692fabe48f Mon Sep 17 00:00:00 2001 From: Paula Date: Fri, 19 Jul 2024 17:02:53 -0700 Subject: [PATCH] Add missing telemetry and extra logging (#391) * Add missing telemetry and extra logging * fix lint * Add more log and telemetry * Add more logging * fix lint * add telemery for inline --- .../application/debugSessionTelemetry.ts | 10 +++++-- src/extension/debugger/adapter/factory.ts | 1 + .../dynamicdebugConfigurationService.ts | 4 +++ .../launch.json/launchJsonReader.ts | 5 +++- .../configuration/resolvers/attach.ts | 2 ++ .../debugger/configuration/resolvers/base.ts | 4 +++ .../configuration/resolvers/launch.ts | 2 ++ .../hooks/childProcessAttachService.ts | 2 ++ .../debugger/hooks/debugpySocketsHandler.ts | 2 ++ .../inlineValue/pythonInlineValueProvider.ts | 3 ++ src/extension/extensionInit.ts | 3 ++ src/extension/telemetry/constants.ts | 4 +++ src/extension/telemetry/index.ts | 30 +++++++++++++++++++ 13 files changed, 68 insertions(+), 4 deletions(-) diff --git a/src/extension/common/application/debugSessionTelemetry.ts b/src/extension/common/application/debugSessionTelemetry.ts index f7baa461..756d0be4 100644 --- a/src/extension/common/application/debugSessionTelemetry.ts +++ b/src/extension/common/application/debugSessionTelemetry.ts @@ -41,17 +41,21 @@ class TelemetryTracker implements DebugAdapterTracker { this.sendTelemetry(EventName.DEBUG_SESSION_STOP); } - public onError?(_error: Error): void { - this.sendTelemetry(EventName.DEBUG_SESSION_ERROR); + public onError?(error: Error): void { + this.sendTelemetry(EventName.DEBUG_SESSION_ERROR, error); } - private sendTelemetry(eventName: EventName): void { + private sendTelemetry

( + eventName: EventName, + properties?: P[E], + ): void { if (eventName === EventName.DEBUG_SESSION_START) { this.timer.reset(); } const telemetryProps = { trigger: this.trigger, console: this.console, + ...properties, }; sendTelemetryEvent(eventName as keyof IEventNamePropertyMapping, this.timer.elapsedTime, telemetryProps); } diff --git a/src/extension/debugger/adapter/factory.ts b/src/extension/debugger/adapter/factory.ts index 7910137f..16bb50e0 100644 --- a/src/extension/debugger/adapter/factory.ts +++ b/src/extension/debugger/adapter/factory.ts @@ -149,6 +149,7 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac } private async showDeprecatedPythonMessage() { + sendTelemetryEvent(EventName.DEBUGGER_PYTHON_37_DEPRECATED); const notificationPromptEnabled = this.persistentState.createGlobalPersistentState( debugStateKeys.doNotShowAgain, false, diff --git a/src/extension/debugger/configuration/dynamicdebugConfigurationService.ts b/src/extension/debugger/configuration/dynamicdebugConfigurationService.ts index 44f8f2d9..00f590d3 100644 --- a/src/extension/debugger/configuration/dynamicdebugConfigurationService.ts +++ b/src/extension/debugger/configuration/dynamicdebugConfigurationService.ts @@ -10,6 +10,8 @@ import { IDynamicDebugConfigurationService } from '../types'; import { DebuggerTypeName } from '../../constants'; import { replaceAll } from '../../common/stringUtils'; import { getDjangoPaths, getFastApiPaths, getFlaskPaths } from './utils/configuration'; +import { sendTelemetryEvent } from '../../telemetry'; +import { EventName } from '../../telemetry/constants'; const workspaceFolderToken = '${workspaceFolder}'; @@ -74,6 +76,8 @@ export class DynamicPythonDebugConfigurationService implements IDynamicDebugConf }); } + sendTelemetryEvent(EventName.DEBUGGER_DYNAMIC_CONFIGURATION, undefined, { providers: providers }); + return providers; } } diff --git a/src/extension/debugger/configuration/launch.json/launchJsonReader.ts b/src/extension/debugger/configuration/launch.json/launchJsonReader.ts index ebef8c0a..e2cad8b2 100644 --- a/src/extension/debugger/configuration/launch.json/launchJsonReader.ts +++ b/src/extension/debugger/configuration/launch.json/launchJsonReader.ts @@ -6,8 +6,10 @@ import * as fs from 'fs-extra'; import { parse } from 'jsonc-parser'; import { DebugConfiguration, Uri, WorkspaceFolder } from 'vscode'; import { getConfiguration, getWorkspaceFolder } from '../../../common/vscodeapi'; +import { traceLog } from '../../../common/log/logging'; export async function getConfigurationsForWorkspace(workspace: WorkspaceFolder): Promise { + traceLog('Getting configurations for workspace'); const filename = path.join(workspace.uri.fsPath, '.vscode', 'launch.json'); if (!(await fs.pathExists(filename))) { // Check launch config in the workspace file @@ -15,6 +17,7 @@ export async function getConfigurationsForWorkspace(workspace: WorkspaceFolder): if (!codeWorkspaceConfig.configurations || !Array.isArray(codeWorkspaceConfig.configurations)) { return []; } + traceLog('Using configuration in workspace'); return codeWorkspaceConfig.configurations; } @@ -26,7 +29,7 @@ export async function getConfigurationsForWorkspace(workspace: WorkspaceFolder): if (!parsed.version) { throw Error('Missing field in launch.json: version'); } - // We do not bother ensuring each item is a DebugConfiguration... + traceLog('Using configuration in launch.json'); return parsed.configurations; } diff --git a/src/extension/debugger/configuration/resolvers/attach.ts b/src/extension/debugger/configuration/resolvers/attach.ts index 12fffe8f..b2446183 100644 --- a/src/extension/debugger/configuration/resolvers/attach.ts +++ b/src/extension/debugger/configuration/resolvers/attach.ts @@ -8,6 +8,7 @@ import { getOSType, OSType } from '../../../common/platform'; import { AttachRequestArguments, DebugOptions, PathMapping } from '../../../types'; import { BaseConfigurationResolver } from './base'; import { getConfiguration } from '../../../common/vscodeapi'; +import { traceLog } from '../../../common/log/logging'; export class AttachConfigurationResolver extends BaseConfigurationResolver { public async resolveDebugConfigurationWithSubstitutedVariables( @@ -15,6 +16,7 @@ export class AttachConfigurationResolver extends BaseConfigurationResolver { + traceLog('Resolving attach configuration with substituted variables'); const workspaceFolder = AttachConfigurationResolver.getWorkspaceFolder(folder); await this.provideAttachDefaults(workspaceFolder, debugConfiguration as AttachRequestArguments); diff --git a/src/extension/debugger/configuration/resolvers/base.ts b/src/extension/debugger/configuration/resolvers/base.ts index 160c6fc5..bda2a7a3 100644 --- a/src/extension/debugger/configuration/resolvers/base.ts +++ b/src/extension/debugger/configuration/resolvers/base.ts @@ -16,6 +16,7 @@ import { resolveVariables } from '../utils/common'; import { getProgram } from './helper'; import { getSettingsPythonPath, getInterpreterDetails } from '../../../common/python'; import { getOSType, OSType } from '../../../common/platform'; +import { traceLog } from '../../../common/log/logging'; export abstract class BaseConfigurationResolver implements IDebugConfigurationResolver @@ -62,14 +63,17 @@ export abstract class BaseConfigurationResolver const workspaceFolders = getWorkspaceFolders(); if (!Array.isArray(workspaceFolders) || workspaceFolders.length === 0) { + traceLog('No workspace folder found'); return program ? Uri.file(path.dirname(program)) : undefined; } if (workspaceFolders.length === 1) { + traceLog('Using the only workspaceFolder found: ', workspaceFolders[0].uri.fsPath); return workspaceFolders[0].uri; } if (program) { const workspaceFolder = getVSCodeWorkspaceFolder(Uri.file(program)); if (workspaceFolder) { + traceLog('Using workspaceFolder found for the program: ', workspaceFolder.uri.fsPath); return workspaceFolder.uri; } } diff --git a/src/extension/debugger/configuration/resolvers/launch.ts b/src/extension/debugger/configuration/resolvers/launch.ts index 423d5d9d..257c72fd 100644 --- a/src/extension/debugger/configuration/resolvers/launch.ts +++ b/src/extension/debugger/configuration/resolvers/launch.ts @@ -12,6 +12,7 @@ import { resolveVariables } from '../utils/common'; import { BaseConfigurationResolver } from './base'; import { getDebugEnvironmentVariables, getProgram } from './helper'; import { getConfiguration } from '../../../common/vscodeapi'; +import { traceLog } from '../../../common/log/logging'; export class LaunchConfigurationResolver extends BaseConfigurationResolver { public async resolveDebugConfiguration( @@ -51,6 +52,7 @@ export class LaunchConfigurationResolver extends BaseConfigurationResolver { + traceLog('Resolving launch configuration with substituted variables'); const workspaceFolder = LaunchConfigurationResolver.getWorkspaceFolder(folder); await this.provideLaunchDefaults(workspaceFolder, debugConfiguration); diff --git a/src/extension/debugger/hooks/childProcessAttachService.ts b/src/extension/debugger/hooks/childProcessAttachService.ts index 9b175b7e..901ad577 100644 --- a/src/extension/debugger/hooks/childProcessAttachService.ts +++ b/src/extension/debugger/hooks/childProcessAttachService.ts @@ -10,6 +10,7 @@ import { AttachRequestArguments } from '../../types'; import { IChildProcessAttachService } from './types'; import { getWorkspaceFolders, showErrorMessage } from '../../common/vscodeapi'; import { noop } from '../../common/utils/misc'; +import { traceLog } from '../../common/log/logging'; /** * This class is responsible for attaching the debugger to any @@ -27,6 +28,7 @@ export class ChildProcessAttachService implements IChildProcessAttachService { lifecycleManagedByParent: true, }; const folder = this.getRelatedWorkspaceFolder(debugConfig); + traceLog('Start debugger in the attach child proccess'); const launched = await debug.startDebugging(folder, debugConfig, debugSessionOption); if (!launched) { showErrorMessage(l10n.t('Failed to launch debugger for child process {0}', debugConfig.subProcessId!)).then( diff --git a/src/extension/debugger/hooks/debugpySocketsHandler.ts b/src/extension/debugger/hooks/debugpySocketsHandler.ts index 56492e9f..3d5eaee1 100644 --- a/src/extension/debugger/hooks/debugpySocketsHandler.ts +++ b/src/extension/debugger/hooks/debugpySocketsHandler.ts @@ -10,6 +10,7 @@ import { DebuggerEvents } from './constants'; import { DebuggerTypeName } from '../../constants'; import { DebugPortAttributesProvider } from '../debugPort/portAttributesProvider'; import { IDebugSessionEventHandlers } from './types'; +import { traceLog } from '../../common/log/logging'; /** * This class is responsible for register ports using by debugpy in the portProvider. @@ -30,6 +31,7 @@ export class DebugpySocketsHandler implements IDebugSessionEventHandlers { } if (event.event === DebuggerEvents.DebugpySockets) { + traceLog("Received 'debugpySockets' event from debugpy."); let portSocket = event.body.sockets.find((socket: { [x: string]: any }) => { return socket['internal'] === false; }); diff --git a/src/extension/debugger/inlineValue/pythonInlineValueProvider.ts b/src/extension/debugger/inlineValue/pythonInlineValueProvider.ts index f71a37d6..204c9ffd 100644 --- a/src/extension/debugger/inlineValue/pythonInlineValueProvider.ts +++ b/src/extension/debugger/inlineValue/pythonInlineValueProvider.ts @@ -11,6 +11,8 @@ import { InlineValueEvaluatableExpression, } from 'vscode'; import { customRequest } from '../../common/vscodeapi'; +import { sendTelemetryEvent } from '../../telemetry'; +import { EventName } from '../../telemetry/constants'; export class PythonInlineValueProvider implements InlineValuesProvider { public async provideInlineValues( @@ -100,6 +102,7 @@ export class PythonInlineValueProvider implements InlineValuesProvider { } } } + sendTelemetryEvent(EventName.DEBUGGER_SHOW_PYTHON_INLINE_VALUES); return allValues; } } diff --git a/src/extension/extensionInit.ts b/src/extension/extensionInit.ts index 6f5a75b4..84ce22e0 100644 --- a/src/extension/extensionInit.ts +++ b/src/extension/extensionInit.ts @@ -50,6 +50,7 @@ import { buildApi } from './api'; import { IExtensionApi } from './apiTypes'; import { registerHexDebugVisualizationTreeProvider } from './debugger/visualizers/inlineHexDecoder'; import { PythonInlineValueProvider } from './debugger/inlineValue/pythonInlineValueProvider'; +import { traceLog } from './common/log/logging'; export async function registerDebugger(context: IExtensionContext): Promise { const childProcessAttachService = new ChildProcessAttachService(); @@ -83,6 +84,7 @@ export async function registerDebugger(context: IExtensionContext): Promise { + traceLog("Debugging using the editor button 'Debug in terminal'"); sendTelemetryEvent(EventName.DEBUG_IN_TERMINAL_BUTTON); const interpreter = await getInterpreterDetails(file); if (!interpreter.path) { @@ -96,6 +98,7 @@ export async function registerDebugger(context: IExtensionContext): Promise { + traceLog("Debugging using the editor button 'Debug using the launch.json'"); sendTelemetryEvent(EventName.DEBUG_USING_LAUNCH_CONFIG_BUTTON); const interpreter = await getInterpreterDetails(file); diff --git a/src/extension/telemetry/constants.ts b/src/extension/telemetry/constants.ts index 861d0217..94ff6643 100644 --- a/src/extension/telemetry/constants.ts +++ b/src/extension/telemetry/constants.ts @@ -13,11 +13,15 @@ export enum EventName { DEBUG_SESSION_START = 'DEBUG_SESSION.START', DEBUG_SESSION_STOP = 'DEBUG_SESSION.STOP', DEBUG_SESSION_USER_CODE_RUNNING = 'DEBUG_SESSION.USER_CODE_RUNNING', + DEBUG_SHOW_INLINE_HEX_VALUE = 'DEBUG.SHOW_INLINE_HEX_VALUE', DEBUGGER = 'DEBUGGER', DEBUGGER_ATTACH_TO_CHILD_PROCESS = 'DEBUGGER.ATTACH_TO_CHILD_PROCESS', DEBUGGER_ATTACH_TO_LOCAL_PROCESS = 'DEBUGGER.ATTACH_TO_LOCAL_PROCESS', DEBUGGER_CONFIGURATION_PROMPTS = 'DEBUGGER.CONFIGURATION.PROMPTS', DEBUGGER_CONFIGURATION_PROMPTS_IN_LAUNCH_JSON = 'DEBUGGER.CONFIGURATION.PROMPTS.IN.LAUNCH.JSON', + DEBUGGER_DYNAMIC_CONFIGURATION = 'DEBUGGER.DYNAMIC_CONFIGURATION', ENVFILE_VARIABLE_SUBSTITUTION = 'ENVFILE_VARIABLE_SUBSTITUTION', USE_REPORT_ISSUE_COMMAND = 'USE_REPORT_ISSUE_COMMAND', + DEBUGGER_PYTHON_37_DEPRECATED = 'DEBUGGER_PYTHON_37_DEPRECATED', + DEBUGGER_SHOW_PYTHON_INLINE_VALUES = 'DEBUGGER_SHOW_PYTHON_INLINE_VALUES', } diff --git a/src/extension/telemetry/index.ts b/src/extension/telemetry/index.ts index ed8da5c1..569230c2 100644 --- a/src/extension/telemetry/index.ts +++ b/src/extension/telemetry/index.ts @@ -11,6 +11,7 @@ import { DebugConfigurationType } from '../debugger/types'; import { EventName } from './constants'; import { isPromise } from '../common/utils/async'; import { getTelemetryReporter } from './reporter'; +import { DebugConfiguration } from 'vscode'; /** * Checks whether telemetry is supported. @@ -346,6 +347,7 @@ export interface IEventNamePropertyMapping { * @type {ConsoleType} */ console?: ConsoleType; + error?: Error; }; /** * Telemetry captured after stopping debug session. @@ -660,4 +662,32 @@ export interface IEventNamePropertyMapping { "use_report_issue_command" : { "owner": "paulacamargo25" } */ [EventName.USE_REPORT_ISSUE_COMMAND]: unknown; + /** + * Telemetry event sent when providing dynamic configuration for debugger + */ + /* __GDPR__ + "debugger_dynamic_config" : { "owner": "paulacamargo25" } + */ + [EventName.DEBUGGER_DYNAMIC_CONFIGURATION]: { + /** + * Providers of dynamic configurations + * + * @type {DebugConfiguration[]} + */ + providers: DebugConfiguration[]; + }; + /** + * Telemetry event sent when the debugger is running with a non supports python versions minor than 3.7. + */ + /* __GDPR__ + "DEBUGGER_PYTHON_37_DEPRECATED" : { "owner": "paulacamargo25" } + */ + [EventName.DEBUGGER_PYTHON_37_DEPRECATED]: never | undefined; + /** + * Telemetry event sent when displaying inline values in the debugger. + */ + /* __GDPR__ + "DEBUGGER_SHOW_PYTHON_INLINE_VALUES" : { "owner": "paulacamargo25" } + */ + [EventName.DEBUGGER_SHOW_PYTHON_INLINE_VALUES]: never | undefined; }