mirror of
https://github.com/cdr/code-server.git
synced 2025-12-06 16:34:35 +01:00
* Update VS Code to 1.92.2
* Use server-main.js to load VS Code
It looks like the bootstrap files are now bundled so we can no longer
require them. We could make them included again, but maybe it is better
to go through the main entrypoint anyway because it includes some nls
stuff which is maybe necessary.
This also fixes what looks like a bug where we could create two servers
if two requests came in. I am not sure what the practical consequences
of that would be, but it will no longer do that.
* Drop es2020 patch
Unfortunately, VS Code will not load with this. It seems to be because
`this` is being used in static properties, and it becomes `void 0` for
some reason under the es2020 target. For example:
static PREFIX_BY_CATEGORY = `${this.PREFIX}${this.SCOPE_PREFIX}`;
becomes
AbstractGotoSymbolQuickAccessProvider.PREFIX_BY_CATEGORY = `${(void 0).PREFIX}${(void 0).SCOPE_PREFIX}`;
Which, obviously, will not work.
Older versions of Safari (and maybe other browsers) are likely affected.
* Fix display language
* Update Playwright
I think maybe because of the dropped es2020 patch that Webkit is now
failing because it is too old.
* Do not wait for networkidle in e2e tests
I am not sure what is going on but some tests on Webkit are timing out
and it seems the page is loaded but something is still trying to
download. Not good, but for now try to at least get the tests passing.
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 'vs/base/common/event';
|
|
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
|
import { Schemas } from 'vs/base/common/network';
|
|
@@ -65,6 +66,7 @@ import { IExtensionsScannerService } fro
|
|
import { ExtensionsScannerService } from 'vs/server/node/extensionsScannerService';
|
|
import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService';
|
|
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
|
|
+import { TelemetryClient } from 'vs/server/node/telemetryClient';
|
|
import { NullPolicyService } from 'vs/platform/policy/common/policy';
|
|
import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender';
|
|
import { LoggerService } from 'vs/platform/log/node/loggerService';
|
|
@@ -147,11 +149,23 @@ export async function setupServerService
|
|
const requestService = new RequestService(configurationService, environmentService, logService, loggerService);
|
|
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
|
|
@@ -317,6 +317,8 @@ export class WebClientServer {
|
|
scope: vscodeBase + '/',
|
|
path: base + '/_static/out/browser/serviceWorker.js',
|
|
},
|
|
+ enableTelemetry: this._productService.enableTelemetry,
|
|
+ telemetryEndpoint: this._productService.telemetryEndpoint,
|
|
embedderIdentifier: 'server-distro',
|
|
extensionsGallery: this._productService.extensionsGallery,
|
|
} satisfies Partial<IProductConfiguration>;
|
|
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
|
|
@@ -64,6 +64,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
|
|
@@ -55,7 +55,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",
|
|
});
|
|
}
|
|
|