mirror of
https://github.com/cdr/code-server.git
synced 2026-03-31 02:25:39 +02:00
* Update Code to 1.113.0 * Use CI build targets The target we have been using has started throwing all sorts of errors during the build (even without any of our patches). After checking the VS Code repo I think these are the ones we should actually be using. They are way faster, too. --------- Co-authored-by: Asher <ash@coder.com>
171 lines
7.3 KiB
Diff
171 lines
7.3 KiB
Diff
Add support for telemetry endpoint
|
|
|
|
To test:
|
|
1. Create a mock API using [RequestBin](https://requestbin.io/) or [Beeceptor](https://beeceptor.com/)
|
|
2. Run code-server with `CS_TELEMETRY_URL` set:
|
|
i.e. `CS_TELEMETRY_URL="https://requestbin.io/1ebub9z1" ./code-server-<version>-macos-amd64/bin/code-server`
|
|
NOTE: it has to be a production build.
|
|
3. Load code-server in browser an do things (i.e. open a file)
|
|
4. Refresh RequestBin and you should see logs
|
|
|
|
Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts
|
|
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
|
|
@@ -4,6 +4,7 @@
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { hostname, release } from 'os';
|
|
+import { promises as fs } from 'fs';
|
|
import { Emitter, Event } from '../../base/common/event.js';
|
|
import { DisposableStore, toDisposable } from '../../base/common/lifecycle.js';
|
|
import { Schemas } from '../../base/common/network.js';
|
|
@@ -65,6 +66,7 @@ import { IExtensionsScannerService } fro
|
|
import { ExtensionsScannerService } from './extensionsScannerService.js';
|
|
import { IExtensionsProfileScannerService } from '../../platform/extensionManagement/common/extensionsProfileScannerService.js';
|
|
import { IUserDataProfilesService } from '../../platform/userDataProfile/common/userDataProfile.js';
|
|
+import { TelemetryClient } from './telemetryClient.js';
|
|
import { NullPolicyService } from '../../platform/policy/common/policy.js';
|
|
import { OneDataSystemAppender } from '../../platform/telemetry/node/1dsAppender.js';
|
|
import { LoggerService } from '../../platform/log/node/loggerService.js';
|
|
@@ -172,11 +174,23 @@ export async function setupServerService
|
|
const requestService = new RequestService('remote', configurationService, environmentService, logService);
|
|
services.set(IRequestService, requestService);
|
|
|
|
+ let isContainer = undefined;
|
|
+ try {
|
|
+ await fs.stat('/run/.containerenv');
|
|
+ isContainer = true;
|
|
+ } catch (error) { /* Does not exist, probably. */ }
|
|
+ if (!isContainer) {
|
|
+ try {
|
|
+ const content = await fs.readFile('/proc/self/cgroup', 'utf8')
|
|
+ isContainer = content.includes('docker');
|
|
+ } catch (error) { /* Permission denied, probably. */ }
|
|
+ }
|
|
+
|
|
let oneDsAppender: ITelemetryAppender = NullAppender;
|
|
const isInternal = isInternalTelemetry(productService, configurationService);
|
|
if (supportsTelemetry(productService, environmentService)) {
|
|
- if (!isLoggingOnly(productService, environmentService) && productService.aiConfig?.ariaKey) {
|
|
- oneDsAppender = new OneDataSystemAppender(requestService, isInternal, eventPrefix, null, productService.aiConfig.ariaKey);
|
|
+ if (!isLoggingOnly(productService, environmentService) && productService.telemetryEndpoint) {
|
|
+ oneDsAppender = new OneDataSystemAppender(requestService, isInternal, eventPrefix, null, () => new TelemetryClient(productService.telemetryEndpoint!, machineId, isContainer));
|
|
disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
|
|
}
|
|
|
|
Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
|
|
@@ -0,0 +1,71 @@
|
|
+import { AppInsightsCore, IExtendedTelemetryItem, ITelemetryItem } from '@microsoft/1ds-core-js';
|
|
+import * as https from 'https';
|
|
+import * as http from 'http';
|
|
+import * as os from 'os';
|
|
+
|
|
+interface SystemInfo {
|
|
+ measurements: Record<string, number | undefined>;
|
|
+ properties: Record<string, string | boolean | null | undefined>;
|
|
+}
|
|
+
|
|
+export class TelemetryClient extends AppInsightsCore {
|
|
+ private readonly systemInfo: SystemInfo = {
|
|
+ measurements: {},
|
|
+ properties: {},
|
|
+ };
|
|
+
|
|
+ public constructor(
|
|
+ private readonly endpoint: string,
|
|
+ machineId: string,
|
|
+ isContainer: boolean | undefined) {
|
|
+ super();
|
|
+
|
|
+ // os.cpus() can take a very long time sometimes (personally I see 1-2
|
|
+ // seconds in a Coder workspace). This adds up significantly, especially
|
|
+ // when many telemetry requests are sent during startup, which can cause
|
|
+ // connection timeouts. Try to cache as much as we can.
|
|
+ try {
|
|
+ const cpus = os.cpus();
|
|
+ this.systemInfo.measurements.cores = cpus.length;
|
|
+ this.systemInfo.properties['common.cpuModel'] = cpus[0].model;
|
|
+ } catch (error) {}
|
|
+
|
|
+ try {
|
|
+ this.systemInfo.properties['common.shell'] = os.userInfo().shell;
|
|
+ this.systemInfo.properties['common.release'] = os.release();
|
|
+ this.systemInfo.properties['common.arch'] = os.arch();
|
|
+ } catch (error) {}
|
|
+
|
|
+ this.systemInfo.properties['common.remoteMachineId'] = machineId;
|
|
+ this.systemInfo.properties['common.isContainer'] = isContainer;
|
|
+ }
|
|
+
|
|
+ public override track(item: IExtendedTelemetryItem | ITelemetryItem): void {
|
|
+ const options = item.baseData || {}
|
|
+ options.measurements = {
|
|
+ ...(options.measurements || {}),
|
|
+ ...this.systemInfo.measurements,
|
|
+ }
|
|
+ options.properties = {
|
|
+ ...(options.properties || {}),
|
|
+ ...this.systemInfo.properties,
|
|
+ }
|
|
+
|
|
+ try {
|
|
+ options.measurements.memoryFree = os.freemem();
|
|
+ options.measurements.memoryTotal = os.totalmem();
|
|
+ } catch (error) {}
|
|
+
|
|
+ try {
|
|
+ const request = (/^http:/.test(this.endpoint) ? http : https).request(this.endpoint, {
|
|
+ method: 'POST',
|
|
+ headers: {
|
|
+ 'Content-Type': 'application/json',
|
|
+ },
|
|
+ });
|
|
+ request.on('error', () => { /* We don't care. */ });
|
|
+ request.write(JSON.stringify(options));
|
|
+ request.end();
|
|
+ } catch (error) {}
|
|
+ }
|
|
+}
|
|
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
|
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
|
@@ -348,6 +348,8 @@ export class WebClientServer {
|
|
scope: vscodeBase + '/',
|
|
path: rootBase + '/_static/out/browser/serviceWorker.js',
|
|
},
|
|
+ enableTelemetry: this._productService.enableTelemetry,
|
|
+ telemetryEndpoint: this._productService.telemetryEndpoint,
|
|
embedderIdentifier: 'server-distro',
|
|
extensionsGallery: this._productService.extensionsGallery,
|
|
};
|
|
Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
|
|
+++ code-server/lib/vscode/src/vs/base/common/product.ts
|
|
@@ -74,6 +74,7 @@ export interface IProductConfiguration {
|
|
readonly path: string;
|
|
readonly scope: string;
|
|
}
|
|
+ readonly telemetryEndpoint?: string
|
|
|
|
readonly version: string;
|
|
readonly date?: string;
|
|
Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/platform/product/common/product.ts
|
|
+++ code-server/lib/vscode/src/vs/platform/product/common/product.ts
|
|
@@ -58,7 +58,8 @@ else if (globalThis._VSCODE_PRODUCT_JSON
|
|
resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
|
|
controlUrl: "",
|
|
recommendationsUrl: "",
|
|
- })
|
|
+ }),
|
|
+ telemetryEndpoint: env.CS_TELEMETRY_URL || product.telemetryEndpoint || "https://v1.telemetry.coder.com/track",
|
|
});
|
|
}
|
|
|