Skip to content

Commit 10cf7f0

Browse files
authored
chore: add distro info to telemetry on linux (microsoft#185261)
1 parent e2470cf commit 10cf7f0

File tree

3 files changed

+101
-1
lines changed

3 files changed

+101
-1
lines changed

.eslintrc.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@
233233
"electron",
234234
"events",
235235
"fs",
236+
"fs/promises",
236237
"graceful-fs",
237238
"http",
238239
"https",
@@ -244,6 +245,7 @@
244245
"os",
245246
"path",
246247
"perf_hooks",
248+
"readline",
247249
"stream",
248250
"string_decoder",
249251
"tas-client-umd",

src/vs/base/node/osReleaseInfo.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { constants as FSConstants } from 'fs';
7+
import { open, FileHandle } from 'fs/promises';
8+
import { createInterface as readLines } from 'readline';
9+
import * as Platform from 'vs/base/common/platform';
10+
11+
type ReleaseInfo = {
12+
id: string;
13+
id_like?: string;
14+
version_id?: string;
15+
};
16+
17+
export async function getOSReleaseInfo(errorLogger: (error: any) => void): Promise<ReleaseInfo | undefined> {
18+
if (Platform.isMacintosh || Platform.isWindows) {
19+
return;
20+
}
21+
22+
// Extract release information on linux based systems
23+
// using the identifiers specified in
24+
// https://www.freedesktop.org/software/systemd/man/os-release.html
25+
let handle: FileHandle | undefined;
26+
for (const filePath of ['/etc/os-release', '/usr/lib/os-release', '/etc/lsb-release']) {
27+
try {
28+
handle = await open(filePath, FSConstants.R_OK);
29+
break;
30+
} catch (err) { }
31+
}
32+
33+
if (!handle) {
34+
errorLogger('Unable to retrieve release information from known identifier paths.');
35+
return;
36+
}
37+
38+
try {
39+
const osReleaseKeys = new Set([
40+
'ID',
41+
'DISTRIB_ID',
42+
'ID_LIKE',
43+
'VERSION_ID',
44+
'DISTRIB_RELEASE',
45+
]);
46+
const releaseInfo: ReleaseInfo = {
47+
id: 'unknown'
48+
};
49+
50+
for await (const line of readLines({ input: handle.createReadStream(), crlfDelay: Infinity })) {
51+
if (!line.includes('=')) {
52+
continue;
53+
}
54+
const key = line.split('=')[0].toUpperCase().trim();
55+
if (osReleaseKeys.has(key)) {
56+
const value = line.split('=')[1].replace(/"/g, '').toLowerCase().trim();
57+
if (key === 'ID' || key === 'DISTRIB_ID') {
58+
releaseInfo.id = value;
59+
} else if (key === 'ID_LIKE') {
60+
releaseInfo.id_like = value;
61+
} else if (key === 'VERSION_ID' || key === 'DISTRIB_RELEASE') {
62+
releaseInfo.version_id = value;
63+
}
64+
}
65+
}
66+
67+
return releaseInfo;
68+
} catch (err) {
69+
errorLogger(err);
70+
}
71+
72+
return;
73+
}

src/vs/server/node/remoteExtensionHostAgentServer.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import * as platform from 'vs/base/common/platform';
2222
import { createRegExp, escapeRegExpCharacters } from 'vs/base/common/strings';
2323
import { URI } from 'vs/base/common/uri';
2424
import { generateUuid } from 'vs/base/common/uuid';
25+
import { getOSReleaseInfo } from 'vs/base/node/osReleaseInfo';
2526
import { findFreePort } from 'vs/base/node/ports';
2627
import { addUNCHostToAllowlist, disableUNCAccessRestrictions } from 'vs/base/node/unc';
2728
import { PersistentProtocol } from 'vs/base/parts/ipc/common/ipc.net';
@@ -788,7 +789,7 @@ export async function createServer(address: string | net.AddressInfo | null, arg
788789
const vscodeServerListenTime: number = (<any>global).vscodeServerListenTime;
789790
const vscodeServerCodeLoadedTime: number = (<any>global).vscodeServerCodeLoadedTime;
790791

791-
instantiationService.invokeFunction((accessor) => {
792+
instantiationService.invokeFunction(async (accessor) => {
792793
const telemetryService = accessor.get(ITelemetryService);
793794

794795
type ServerStartClassification = {
@@ -811,6 +812,30 @@ export async function createServer(address: string | net.AddressInfo | null, arg
811812
codeLoadedTime: vscodeServerCodeLoadedTime,
812813
readyTime: currentTime
813814
});
815+
816+
if (platform.isLinux) {
817+
const logService = accessor.get(ILogService);
818+
const releaseInfo = await getOSReleaseInfo(logService.error.bind(logService));
819+
if (releaseInfo) {
820+
type ServerPlatformInfoClassification = {
821+
platformId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the operating system without any version information.' };
822+
platformVersionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the operating system version excluding any name information or release code.' };
823+
platformIdLike: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the operating system the current OS derivate is closely related to.' };
824+
owner: 'deepak1556';
825+
comment: 'Provides insight into the distro information on Linux.';
826+
};
827+
type ServerPlatformInfoEvent = {
828+
platformId: string;
829+
platformVersionId: string | undefined;
830+
platformIdLike: string | undefined;
831+
};
832+
telemetryService.publicLog2<ServerPlatformInfoEvent, ServerPlatformInfoClassification>('serverPlatformInfo', {
833+
platformId: releaseInfo.id,
834+
platformVersionId: releaseInfo.version_id,
835+
platformIdLike: releaseInfo.id_like
836+
});
837+
}
838+
}
814839
});
815840

816841
if (args['print-startup-performance']) {

0 commit comments

Comments
 (0)