@@ -50,50 +50,66 @@ Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
5050===================================================================
5151--- /dev/null
5252+++ code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
53- @@ -0,0 +1,55 @@
53+ @@ -0,0 +1,71 @@
5454+ import { AppInsightsCore, IExtendedTelemetryItem, ITelemetryItem } from '@microsoft/1ds-core-js';
5555+ import * as https from 'https';
5656+ import * as http from 'http';
5757+ import * as os from 'os';
5858+
59+ + interface SystemInfo {
60+ + measurements: Record<string, number | undefined>;
61+ + properties: Record<string, string | boolean | null | undefined>;
62+ + }
63+ +
5964+ export class TelemetryClient extends AppInsightsCore {
65+ + private readonly systemInfo: SystemInfo = {
66+ + measurements: {},
67+ + properties: {},
68+ + };
69+ +
6070+ public constructor(
6171+ private readonly endpoint: string,
62- + private readonly machineId: string,
63- + private readonly isContainer: Boolean | undefined) {
72+ + machineId: string,
73+ + isContainer: boolean | undefined) {
6474+ super();
75+ +
76+ + // os.cpus() can take a very long time sometimes (personally I see 1-2
77+ + // seconds in a Coder workspace). This adds up significantly, especially
78+ + // when many telemetry requests are sent during startup, which can cause
79+ + // connection timeouts. Try to cache as much as we can.
80+ + try {
81+ + const cpus = os.cpus();
82+ + this.systemInfo.measurements.cores = cpus.length;
83+ + this.systemInfo.properties['common.cpuModel'] = cpus[0].model;
84+ + } catch (error) {}
85+ +
86+ + try {
87+ + this.systemInfo.properties['common.shell'] = os.userInfo().shell;
88+ + this.systemInfo.properties['common.release'] = os.release();
89+ + this.systemInfo.properties['common.arch'] = os.arch();
90+ + } catch (error) {}
91+ +
92+ + this.systemInfo.properties['common.remoteMachineId'] = machineId;
93+ + this.systemInfo.properties['common.isContainer'] = isContainer;
6594+ }
6695+
6796+ public override track(item: IExtendedTelemetryItem | ITelemetryItem): void {
6897+ const options = item.baseData || {}
69- + if (!options.properties) {
70- + options.properties = {};
98+ + options.measurements = {
99+ + ...(options.measurements || {}),
100+ + ...this.systemInfo.measurements,
71101+ }
72- + if (!options.measurements) {
73- + options.measurements = {};
102+ + options.properties = {
103+ + ...(options.properties || {}),
104+ + ...this.systemInfo.properties,
74105+ }
75106+
76107+ try {
77- + const cpus = os.cpus();
78- + options.measurements.cores = cpus.length;
79- + options.properties['common.cpuModel'] = cpus[0].model;
80- + } catch (error) {}
81- +
82- + try {
83108+ options.measurements.memoryFree = os.freemem();
84109+ options.measurements.memoryTotal = os.totalmem();
85110+ } catch (error) {}
86111+
87112+ try {
88- + options.properties['common.shell'] = os.userInfo().shell;
89- + options.properties['common.release'] = os.release();
90- + options.properties['common.arch'] = os.arch();
91- + } catch (error) {}
92- +
93- + options.properties['common.remoteMachineId'] = this.machineId;
94- + options.properties['common.isContainer'] = this.isContainer;
95- +
96- + try {
97113+ const request = (/^http:/.test(this.endpoint) ? http : https).request(this.endpoint, {
98114+ method: 'POST',
99115+ headers: {
0 commit comments