Skip to content

Commit 53fb3d8

Browse files
committed
Implement telemetry
1 parent 045e4a9 commit 53fb3d8

File tree

1 file changed

+105
-25
lines changed

1 file changed

+105
-25
lines changed

patches/telemetry.diff

Lines changed: 105 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,135 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
44
===================================================================
55
--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts
66
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
7-
@@ -73,6 +73,7 @@ import { ExtensionsProfileScannerService
7+
@@ -71,6 +71,7 @@ import { IExtensionsScannerService } fro
8+
import { ExtensionsScannerService } from 'vs/server/node/extensionsScannerService';
9+
import { ExtensionsProfileScannerService, IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService';
810
import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
11+
+import { TelemetryClient } from "vs/server/node/telemetryClient";
912
import { NullPolicyService } from 'vs/platform/policy/common/policy';
1013
import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender';
11-
+import { TelemetryClient } from './telemetryClient';
1214

13-
const eventPrefix = 'monacoworkbench';
14-
15-
@@ -134,10 +135,15 @@ export async function setupServerService
15+
@@ -133,10 +134,13 @@ export async function setupServerService
16+
const machineId = await getMachineId();
1617
const isInternal = isInternalTelemetry(productService, configurationService);
1718
if (supportsTelemetry(productService, environmentService)) {
18-
if (productService.aiConfig && productService.aiConfig.ariaKey) {
19-
- oneDsAppender = new OneDataSystemAppender(isInternal, eventPrefix, null, productService.aiConfig.ariaKey);
19+
- if (productService.aiConfig && productService.aiConfig.ariaKey) {
20+
+ const telemetryEndpoint = process.env.CS_TELEMETRY_URL || "https://v1.telemetry.coder.com/track";
21+
+ if (telemetryEndpoint) {
22+
+ oneDsAppender = new OneDataSystemAppender(false, eventPrefix, null, () => new TelemetryClient(telemetryEndpoint));
23+
+ } else if (productService.aiConfig && productService.aiConfig.ariaKey) {
24+
oneDsAppender = new OneDataSystemAppender(isInternal, eventPrefix, null, productService.aiConfig.ariaKey);
2025
- disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
21-
+ const telemetryEndpoint = process.env.CS_TELEMETRY_URL || "https://v1.telemetry.coder.com/track";
22-
+ if (telemetryEndpoint) {
23-
+ oneDsAppender = new OneDataSystemAppender(false, eventPrefix, null, () => new TelemetryClient(telemetryEndpoint) as any);
24-
+ disposables.add(toDisposable(() => oneDsAppender!.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
25-
+ } else if (productService.aiConfig && productService.aiConfig.ariaKey) {
26-
+ oneDsAppender = new OneDataSystemAppender(isInternal, eventPrefix, null, productService.aiConfig.ariaKey);
27-
+ disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
28-
+ }
2926
}
30-
-
27+
+ disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
28+
3129
const config: ITelemetryServiceConfig = {
3230
appenders: [oneDsAppender],
33-
commonProperties: resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version + '-remote', machineId, isInternal, environmentService.installSourcePath, 'remoteAgent'),
3431
Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
3532
===================================================================
3633
--- /dev/null
3734
+++ code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
38-
@@ -0,0 +1,17 @@
35+
@@ -0,0 +1,49 @@
3936
+import { AppInsightsCore, IExtendedTelemetryItem, ITelemetryItem } from '@microsoft/1ds-core-js';
37+
+import * as https from 'https';
38+
+import * as http from 'http';
39+
+import * as os from 'os';
4040
+
41-
+
42-
+// Unable to use implements because TypeScript tells you a private property is
43-
+// missing but if you add it then it complains they have different private
44-
+// properties. Uncommenting it during development can be helpful though to see
45-
+// if anything is missing.
4641
+export class TelemetryClient extends AppInsightsCore {
4742
+ public constructor(private readonly endpoint: string) {
4843
+ super();
49-
+ // Nothing to do.
5044
+ }
5145
+
5246
+ public override track(item: IExtendedTelemetryItem | ITelemetryItem): void {
53-
+ console.log(this.endpoint);
47+
+ const options = item.baseData || {}
48+
+ if (!options.properties) {
49+
+ options.properties = {};
50+
+ }
51+
+ if (!options.measurements) {
52+
+ options.measurements = {};
53+
+ }
54+
+
55+
+ try {
56+
+ const cpus = os.cpus();
57+
+ options.measurements.cores = cpus.length;
58+
+ options.properties['common.cpuModel'] = cpus[0].model;
59+
+ } catch (error) {}
60+
+
61+
+ try {
62+
+ options.measurements.memoryFree = os.freemem();
63+
+ options.measurements.memoryTotal = os.totalmem();
64+
+ } catch (error) {}
65+
+
66+
+ try {
67+
+ options.properties['common.shell'] = os.userInfo().shell;
68+
+ options.properties['common.release'] = os.release();
69+
+ options.properties['common.arch'] = os.arch();
70+
+ } catch (error) {}
71+
+
72+
+ try {
73+
+ const request = (/^http:/.test(this.endpoint) ? http : https).request(this.endpoint, {
74+
+ method: 'POST',
75+
+ headers: {
76+
+ 'Content-Type': 'application/json',
77+
+ },
78+
+ });
79+
+ request.on('error', () => { /* We don't care. */ });
80+
+ request.write(JSON.stringify(options));
81+
+ request.end();
82+
+ } catch (error) {}
5483
+ }
5584
+}
85+
Index: code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
86+
===================================================================
87+
--- code-server.orig/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
88+
+++ code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
89+
@@ -38,26 +38,30 @@ export class TelemetryService extends Di
90+
) {
91+
super();
92+
93+
- if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.ariaKey) {
94+
+ if (supportsTelemetry(productService, environmentService)) {
95+
// If remote server is present send telemetry through that, else use the client side appender
96+
const appenders = [];
97+
const isInternal = isInternalTelemetry(productService, configurationService);
98+
- const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new OneDataSystemWebAppender(isInternal, 'monacoworkbench', null, productService.aiConfig?.ariaKey);
99+
- appenders.push(telemetryProvider);
100+
- appenders.push(new TelemetryLogAppender(loggerService, environmentService));
101+
- const config: ITelemetryServiceConfig = {
102+
- appenders,
103+
- commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, isInternal, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
104+
- sendErrorTelemetry: this.sendErrorTelemetry,
105+
- };
106+
- this.impl = this._register(new BaseTelemetryService(config, configurationService, productService));
107+
+ const telemetryProvider: ITelemetryAppender | undefined = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : productService.aiConfig?.ariaKey ? new OneDataSystemWebAppender(isInternal, 'monacoworkbench', null, productService.aiConfig?.ariaKey) : undefined;
108+
+ if (telemetryProvider) {
109+
+ appenders.push(telemetryProvider);
110+
+ appenders.push(new TelemetryLogAppender(loggerService, environmentService));
111+
+ const config: ITelemetryServiceConfig = {
112+
+ appenders,
113+
+ commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, isInternal, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
114+
+ sendErrorTelemetry: this.sendErrorTelemetry,
115+
+ };
116+
+ this.impl = this._register(new BaseTelemetryService(config, configurationService, productService));
117+
118+
- if (getTelemetryLevel(configurationService) !== TelemetryLevel.NONE) {
119+
- // If we cannot fetch the endpoint it means it is down and we should not send any telemetry.
120+
- // This is most likely due to ad blockers
121+
- fetch(telemetryEndpointUrl, { method: 'POST' }).catch(err => {
122+
- this.impl = NullTelemetryService;
123+
- });
124+
+ if (remoteAgentService.getConnection() === null && getTelemetryLevel(configurationService) !== TelemetryLevel.NONE) {
125+
+ // If we cannot fetch the endpoint it means it is down and we should not send any telemetry.
126+
+ // This is most likely due to ad blockers
127+
+ fetch(telemetryEndpointUrl, { method: 'POST' }).catch(err => {
128+
+ this.impl = NullTelemetryService;
129+
+ });
130+
+ }
131+
+ } else {
132+
+ this.impl = NullTelemetryService;
133+
}
134+
} else {
135+
this.impl = NullTelemetryService;
56136
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
57137
===================================================================
58138
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts

0 commit comments

Comments
 (0)