Skip to content

Capture count of envs collected #23471

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

Merged
merged 3 commits into from
May 23, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { traceError, traceInfo, traceVerbose } from '../../../../logging';
import { sendTelemetryEvent } from '../../../../telemetry';
import { EventName } from '../../../../telemetry/constants';
import { normalizePath } from '../../../common/externalDependencies';
import { PythonEnvInfo } from '../../info';
import { PythonEnvInfo, PythonEnvKind } from '../../info';
import { getEnvPath } from '../../info/env';
import {
GetRefreshEnvironmentsOptions,
Expand Down Expand Up @@ -54,7 +54,11 @@ export class EnvsCollectionService extends PythonEnvsWatcher<PythonEnvCollection
return this.progressPromises.get(stage)?.promise;
}

constructor(private readonly cache: IEnvsCollectionCache, private readonly locator: IResolvingLocator) {
constructor(
private readonly cache: IEnvsCollectionCache,
private readonly locator: IResolvingLocator,
private readonly usingNativeLocator: boolean,
) {
super();
this.locator.onChanged((event) => {
const query: PythonLocatorQuery | undefined = event.providerId
Expand Down Expand Up @@ -258,12 +262,46 @@ export class EnvsCollectionService extends PythonEnvsWatcher<PythonEnvCollection

private sendTelemetry(query: PythonLocatorQuery | undefined, stopWatch: StopWatch) {
if (!query && !this.hasRefreshFinished(query)) {
const envs = this.cache.getAllEnvs();
const environmentsWithoutPython = envs.filter(
(e) => getEnvPath(e.executable.filename, e.location).pathType === 'envFolderPath',
).length;
const activeStateEnvs = envs.filter((e) => e.kind === PythonEnvKind.ActiveState).length;
const condaEnvs = envs.filter((e) => e.kind === PythonEnvKind.Conda).length;
const customEnvs = envs.filter((e) => e.kind === PythonEnvKind.Custom).length;
const hatchEnvs = envs.filter((e) => e.kind === PythonEnvKind.Hatch).length;
const microsoftStoreEnvs = envs.filter((e) => e.kind === PythonEnvKind.MicrosoftStore).length;
const otherGlobalEnvs = envs.filter((e) => e.kind === PythonEnvKind.OtherGlobal).length;
const otherVirtualEnvs = envs.filter((e) => e.kind === PythonEnvKind.OtherVirtual).length;
const pipEnvEnvs = envs.filter((e) => e.kind === PythonEnvKind.Pipenv).length;
const poetryEnvs = envs.filter((e) => e.kind === PythonEnvKind.Poetry).length;
const pyenvEnvs = envs.filter((e) => e.kind === PythonEnvKind.Pyenv).length;
const systemEnvs = envs.filter((e) => e.kind === PythonEnvKind.System).length;
const unknownEnvs = envs.filter((e) => e.kind === PythonEnvKind.Unknown).length;
const venvEnvs = envs.filter((e) => e.kind === PythonEnvKind.Venv).length;
const virtualEnvEnvs = envs.filter((e) => e.kind === PythonEnvKind.VirtualEnv).length;
const virtualEnvWrapperEnvs = envs.filter((e) => e.kind === PythonEnvKind.VirtualEnvWrapper).length;

// Intent is to capture time taken for discovery of all envs to complete the first time.
sendTelemetryEvent(EventName.PYTHON_INTERPRETER_DISCOVERY, stopWatch.elapsedTime, {
interpreters: this.cache.getAllEnvs().length,
environmentsWithoutPython: this.cache
.getAllEnvs()
.filter((e) => getEnvPath(e.executable.filename, e.location).pathType === 'envFolderPath').length,
usingNativeLocator: this.usingNativeLocator,
environmentsWithoutPython,
activeStateEnvs,
condaEnvs,
customEnvs,
hatchEnvs,
microsoftStoreEnvs,
otherGlobalEnvs,
otherVirtualEnvs,
pipEnvEnvs,
poetryEnvs,
pyenvEnvs,
systemEnvs,
unknownEnvs,
venvEnvs,
virtualEnvEnvs,
virtualEnvWrapperEnvs,
});
}
this.hasRefreshFinishedForQuery.set(query, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
} from '../common/nativePythonFinder';
import { disposeAll } from '../../../../common/utils/resourceLifecycle';
import { StopWatch } from '../../../../common/utils/stopWatch';
import { sendTelemetryEvent } from '../../../../telemetry';
import { EventName } from '../../../../telemetry/constants';

function categoryToKind(category: string): PythonEnvKind {
switch (category.toLowerCase()) {
Expand Down Expand Up @@ -106,6 +108,7 @@ export class NativeLocator implements ILocator<BasicEnvInfo>, IDisposable {
const disposable = new Disposable(() => disposeAll(disposables));
this.disposables.push(disposable);
promise.finally(() => disposable.dispose());
let environmentsWithoutPython = 0;
disposables.push(
this.finder.onDidFindPythonEnvironment((data: NativeEnvInfo) => {
// TODO: What if executable is undefined?
Expand All @@ -121,6 +124,8 @@ export class NativeLocator implements ILocator<BasicEnvInfo>, IDisposable {
searchLocation: data.projectPath ? Uri.file(data.projectPath) : undefined,
identifiedUsingNativeLocator: true,
});
} else {
environmentsWithoutPython += 1;
}
}),
this.finder.onDidFindEnvironmentManager((data: NativeEnvManagerInfo) => {
Expand All @@ -147,6 +152,7 @@ export class NativeLocator implements ILocator<BasicEnvInfo>, IDisposable {
`Finished searching for Python environments using Native Locator: ${stopWatch.elapsedTime} milliseconds`,
);
yield* envs;
sendTelemetry(envs, environmentsWithoutPython, stopWatch);
traceInfo(
`Finished yielding Python environments using Native Locator: ${stopWatch.elapsedTime} milliseconds`,
);
Expand All @@ -155,3 +161,42 @@ export class NativeLocator implements ILocator<BasicEnvInfo>, IDisposable {
return iterator();
}
}

function sendTelemetry(envs: BasicEnvInfo[], environmentsWithoutPython: number, stopWatch: StopWatch) {
const activeStateEnvs = envs.filter((e) => e.kind === PythonEnvKind.ActiveState).length;
const condaEnvs = envs.filter((e) => e.kind === PythonEnvKind.Conda).length;
const customEnvs = envs.filter((e) => e.kind === PythonEnvKind.Custom).length;
const hatchEnvs = envs.filter((e) => e.kind === PythonEnvKind.Hatch).length;
const microsoftStoreEnvs = envs.filter((e) => e.kind === PythonEnvKind.MicrosoftStore).length;
const otherGlobalEnvs = envs.filter((e) => e.kind === PythonEnvKind.OtherGlobal).length;
const otherVirtualEnvs = envs.filter((e) => e.kind === PythonEnvKind.OtherVirtual).length;
const pipEnvEnvs = envs.filter((e) => e.kind === PythonEnvKind.Pipenv).length;
const poetryEnvs = envs.filter((e) => e.kind === PythonEnvKind.Poetry).length;
const pyenvEnvs = envs.filter((e) => e.kind === PythonEnvKind.Pyenv).length;
const systemEnvs = envs.filter((e) => e.kind === PythonEnvKind.System).length;
const unknownEnvs = envs.filter((e) => e.kind === PythonEnvKind.Unknown).length;
const venvEnvs = envs.filter((e) => e.kind === PythonEnvKind.Venv).length;
const virtualEnvEnvs = envs.filter((e) => e.kind === PythonEnvKind.VirtualEnv).length;
const virtualEnvWrapperEnvs = envs.filter((e) => e.kind === PythonEnvKind.VirtualEnvWrapper).length;

// Intent is to capture time taken for discovery of all envs to complete the first time.
sendTelemetryEvent(EventName.PYTHON_INTERPRETER_DISCOVERY, stopWatch.elapsedTime, {
interpreters: envs.length,
environmentsWithoutPython,
activeStateEnvs,
condaEnvs,
customEnvs,
hatchEnvs,
microsoftStoreEnvs,
otherGlobalEnvs,
otherVirtualEnvs,
pipEnvEnvs,
poetryEnvs,
pyenvEnvs,
systemEnvs,
unknownEnvs,
venvEnvs,
virtualEnvEnvs,
virtualEnvWrapperEnvs,
});
}
1 change: 1 addition & 0 deletions src/client/pythonEnvironments/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ async function createLocator(
await createCollectionCache(ext),
// This is shared.
resolvingLocator,
useNativeLocator(),
);
return caching;
}
Expand Down
1 change: 1 addition & 0 deletions src/client/telemetry/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export enum EventName {
ENVIRONMENT_WITHOUT_PYTHON_SELECTED = 'ENVIRONMENT_WITHOUT_PYTHON_SELECTED',
PYTHON_ENVIRONMENTS_API = 'PYTHON_ENVIRONMENTS_API',
PYTHON_INTERPRETER_DISCOVERY = 'PYTHON_INTERPRETER_DISCOVERY',
PYTHON_INTERPRETER_DISCOVERY_NATIVE = 'PYTHON_INTERPRETER_DISCOVERY_NATIVE',
PYTHON_INTERPRETER_AUTO_SELECTION = 'PYTHON_INTERPRETER_AUTO_SELECTION',
PYTHON_INTERPRETER_ACTIVATION_ENVIRONMENT_VARIABLES = 'PYTHON_INTERPRETER.ACTIVATION_ENVIRONMENT_VARIABLES',
PYTHON_INTERPRETER_ACTIVATION_FOR_RUNNING_CODE = 'PYTHON_INTERPRETER_ACTIVATION_FOR_RUNNING_CODE',
Expand Down
175 changes: 175 additions & 0 deletions src/client/telemetry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1144,9 +1144,124 @@ export interface IEventNamePropertyMapping {
"duration" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "karrtikr" },
"interpreters" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true , "owner": "karrtikr"},
"environmentsWithoutPython" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "karrtikr" }
"usingNativeLocator" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "donjayamanne" }
"activeStateEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"condaEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"customEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"hatchEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"microsoftStoreEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"otherGlobalEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"otherVirtualEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"pipEnvEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"poetryEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"pyenvEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"systemEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"unknownEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"venvEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"virtualEnvEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"virtualEnvWrapperEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
}
*/
[EventName.PYTHON_INTERPRETER_DISCOVERY]: {
/**
* The number of the interpreters discovered
*/
interpreters?: number;
/**
* Whether or not we're using the native locator.
*/
usingNativeLocator?: boolean;
/**
* The number of environments discovered not containing an interpreter
*/
environmentsWithoutPython?: number;
/**
* Number of environments of a specific type
*/
activeStateEnvs?: number;
/**
* Number of environments of a specific type
*/
condaEnvs?: number;
/**
* Number of environments of a specific type
*/
customEnvs?: number;
/**
* Number of environments of a specific type
*/
hatchEnvs?: number;
/**
* Number of environments of a specific type
*/
microsoftStoreEnvs?: number;
/**
* Number of environments of a specific type
*/
otherGlobalEnvs?: number;
/**
* Number of environments of a specific type
*/
otherVirtualEnvs?: number;
/**
* Number of environments of a specific type
*/
pipEnvEnvs?: number;
/**
* Number of environments of a specific type
*/
poetryEnvs?: number;
/**
* Number of environments of a specific type
*/
pyenvEnvs?: number;
/**
* Number of environments of a specific type
*/
systemEnvs?: number;
/**
* Number of environments of a specific type
*/
unknownEnvs?: number;
/**
* Number of environments of a specific type
*/
venvEnvs?: number;
/**
* Number of environments of a specific type
*/
virtualEnvEnvs?: number;
/**
* Number of environments of a specific type
*/
virtualEnvWrapperEnvs?: number;
};
/**
* Telemetry event sent when discovery of all python environments using the native locator(virtualenv, conda, pipenv etc.) finishes.
*/
/* __GDPR__
"python_interpreter_discovery_native" : {
"duration" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"interpreters" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true , "owner": "donjayamanne"},
"environmentsWithoutPython" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" }
"activeStateEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"condaEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"customEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"hatchEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"microsoftStoreEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"otherGlobalEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"otherVirtualEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"pipEnvEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"poetryEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"pyenvEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"systemEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"unknownEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"venvEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"virtualEnvEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
"virtualEnvWrapperEnvs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "donjayamanne" },
}
*/
[EventName.PYTHON_INTERPRETER_DISCOVERY_NATIVE]: {
/**
* The number of the interpreters discovered
*/
Expand All @@ -1155,6 +1270,66 @@ export interface IEventNamePropertyMapping {
* The number of environments discovered not containing an interpreter
*/
environmentsWithoutPython?: number;
/**
* Number of environments of a specific type
*/
activeStateEnvs?: number;
/**
* Number of environments of a specific type
*/
condaEnvs?: number;
/**
* Number of environments of a specific type
*/
customEnvs?: number;
/**
* Number of environments of a specific type
*/
hatchEnvs?: number;
/**
* Number of environments of a specific type
*/
microsoftStoreEnvs?: number;
/**
* Number of environments of a specific type
*/
otherGlobalEnvs?: number;
/**
* Number of environments of a specific type
*/
otherVirtualEnvs?: number;
/**
* Number of environments of a specific type
*/
pipEnvEnvs?: number;
/**
* Number of environments of a specific type
*/
poetryEnvs?: number;
/**
* Number of environments of a specific type
*/
pyenvEnvs?: number;
/**
* Number of environments of a specific type
*/
systemEnvs?: number;
/**
* Number of environments of a specific type
*/
unknownEnvs?: number;
/**
* Number of environments of a specific type
*/
venvEnvs?: number;
/**
* Number of environments of a specific type
*/
virtualEnvEnvs?: number;
/**
* Number of environments of a specific type
*/
virtualEnvWrapperEnvs?: number;
};
/**
* Telemetry event sent with details when user clicks the prompt with the following message:
Expand Down
Loading
Loading