From d40f415205b66c0b3c380be56374e14c9db6b266 Mon Sep 17 00:00:00 2001 From: HeeJae Chang Date: Tue, 21 Mar 2023 19:21:54 -0700 Subject: [PATCH] Share telemetry from core ext it turns out the new telemetry API removed a way to set extension id and version when telemetry reporter is created and it implicitly sets from extension reporter is created. the same way how LSP client is working. since we want to keep using the same extension id and etc for our telemetry, we need the reporter created from core ext. --- src/client/api.ts | 18 ++++-------------- src/client/browser/api.ts | 11 ++++------- src/client/browser/extension.ts | 6 ++++-- src/client/pylanceApi.ts | 26 ++++++++++++++++++++++++++ src/client/telemetry/index.ts | 2 +- 5 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 src/client/pylanceApi.ts diff --git a/src/client/api.ts b/src/client/api.ts index a2f2997c38d0..7ca30b2a6940 100644 --- a/src/client/api.ts +++ b/src/client/api.ts @@ -12,7 +12,6 @@ import { ILanguageServerOutputChannel } from './activation/types'; import { IExtensionApi } from './apiTypes'; import { isTestExecution, PYTHON_LANGUAGE } from './common/constants'; import { IConfigurationService, Resource } from './common/types'; -import { IEnvironmentVariablesProvider } from './common/variables/types'; import { getDebugpyLauncherArgs, getDebugpyPackagePath } from './debugger/extension/adapter/remoteLaunchers'; import { IInterpreterService } from './interpreter/contracts'; import { IServiceContainer, IServiceManager } from './ioc/types'; @@ -20,6 +19,8 @@ import { JupyterExtensionIntegration } from './jupyter/jupyterIntegration'; import { traceError } from './logging'; import { IDiscoveryAPI } from './pythonEnvironments/base/locator'; import { buildEnvironmentApi } from './environmentApi'; +import { ApiForPylance } from './pylanceApi'; +import { getTelemetryReporter } from './telemetry'; export function buildApi( ready: Promise, @@ -31,7 +32,6 @@ export function buildApi( const interpreterService = serviceContainer.get(IInterpreterService); serviceManager.addSingleton(JupyterExtensionIntegration, JupyterExtensionIntegration); const jupyterIntegration = serviceContainer.get(JupyterExtensionIntegration); - const envService = serviceContainer.get(IEnvironmentVariablesProvider); const outputChannel = serviceContainer.get(ILanguageServerOutputChannel); const api: IExtensionApi & { @@ -39,13 +39,7 @@ export function buildApi( * @deprecated Temporarily exposed for Pylance until we expose this API generally. Will be removed in an * iteration or two. */ - pylance: { - getPythonPathVar: (resource?: Uri) => Promise; - readonly onDidEnvironmentVariablesChange: Event; - createClient(...args: any[]): BaseLanguageClient; - start(client: BaseLanguageClient): Promise; - stop(client: BaseLanguageClient): Promise; - }; + pylance: ApiForPylance; } & { /** * @deprecated Use IExtensionApi.environments API instead. @@ -126,11 +120,6 @@ export function buildApi( : (noop as any), }, pylance: { - getPythonPathVar: async (resource?: Uri) => { - const envs = await envService.getEnvironmentVariables(resource); - return envs.PYTHONPATH; - }, - onDidEnvironmentVariablesChange: envService.onDidEnvironmentVariablesChange, createClient: (...args: any[]): BaseLanguageClient => { // Make sure we share output channel so that we can share one with // Jedi as well. @@ -141,6 +130,7 @@ export function buildApi( }, start: (client: BaseLanguageClient): Promise => client.start(), stop: (client: BaseLanguageClient): Promise => client.stop(), + getTelemetryReporter: () => getTelemetryReporter(), }, environments: buildEnvironmentApi(discoveryApi, serviceContainer), }; diff --git a/src/client/browser/api.ts b/src/client/browser/api.ts index 0536cbadb0bb..ac2df8d0ffed 100644 --- a/src/client/browser/api.ts +++ b/src/client/browser/api.ts @@ -6,21 +6,17 @@ import { BaseLanguageClient } from 'vscode-languageclient'; import { LanguageClient } from 'vscode-languageclient/browser'; import { PYTHON_LANGUAGE } from '../common/constants'; +import { ApiForPylance, TelemetryReporter } from '../pylanceApi'; export interface IBrowserExtensionApi { /** * @deprecated Temporarily exposed for Pylance until we expose this API generally. Will be removed in an * iteration or two. */ - pylance: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - createClient(...args: any[]): BaseLanguageClient; - start(client: BaseLanguageClient): Promise; - stop(client: BaseLanguageClient): Promise; - }; + pylance: ApiForPylance; } -export function buildApi(): IBrowserExtensionApi { +export function buildApi(reporter: TelemetryReporter): IBrowserExtensionApi { const api: IBrowserExtensionApi = { pylance: { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -28,6 +24,7 @@ export function buildApi(): IBrowserExtensionApi { new LanguageClient(PYTHON_LANGUAGE, 'Python Language Server', args[0], args[1]), start: (client: BaseLanguageClient): Promise => client.start(), stop: (client: BaseLanguageClient): Promise => client.stop(), + getTelemetryReporter: () => reporter, }, }; diff --git a/src/client/browser/extension.ts b/src/client/browser/extension.ts index e1ee59a677e4..6ab6440bbe09 100644 --- a/src/client/browser/extension.ts +++ b/src/client/browser/extension.ts @@ -21,10 +21,12 @@ let languageClient: LanguageClient | undefined; let pylanceApi: PylanceApi | undefined; export async function activate(context: vscode.ExtensionContext): Promise { + const reporter = getTelemetryReporter(); + const pylanceExtension = vscode.extensions.getExtension(PYLANCE_EXTENSION_ID); if (pylanceExtension) { await runPylance(context, pylanceExtension); - return buildApi(); + return buildApi(reporter); } const changeDisposable = vscode.extensions.onDidChange(async () => { @@ -35,7 +37,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { diff --git a/src/client/pylanceApi.ts b/src/client/pylanceApi.ts new file mode 100644 index 000000000000..b839d0d9c2b7 --- /dev/null +++ b/src/client/pylanceApi.ts @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { TelemetryEventMeasurements, TelemetryEventProperties } from '@vscode/extension-telemetry'; +import { BaseLanguageClient } from 'vscode-languageclient'; + +export interface TelemetryReporter { + sendTelemetryEvent( + eventName: string, + properties?: TelemetryEventProperties, + measurements?: TelemetryEventMeasurements, + ): void; + sendTelemetryErrorEvent( + eventName: string, + properties?: TelemetryEventProperties, + measurements?: TelemetryEventMeasurements, + ): void; +} + +export interface ApiForPylance { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + createClient(...args: any[]): BaseLanguageClient; + start(client: BaseLanguageClient): Promise; + stop(client: BaseLanguageClient): Promise; + getTelemetryReporter(): TelemetryReporter; +} diff --git a/src/client/telemetry/index.ts b/src/client/telemetry/index.ts index d9091cced48f..74f1ddf0ecf4 100644 --- a/src/client/telemetry/index.ts +++ b/src/client/telemetry/index.ts @@ -76,7 +76,7 @@ export function _resetSharedProperties(): void { } let telemetryReporter: TelemetryReporter | undefined; -function getTelemetryReporter() { +export function getTelemetryReporter(): TelemetryReporter { if (!isTestExecution() && telemetryReporter) { return telemetryReporter; }