code-server/patches/telemetry.diff
Asher 5ce99f8d1c
chore: update Code to 1.68 (#5263)
* chore: update Code to 1.67

Was able to remove our changes to common/webview.ts since they are
upstream now.

Other than that no serious changes, just context diffs.

* chore: update Code to 1.68

- Upstream moved the web socket endpoint so change the Express route
  from / to *.  That will let web sockets work at any endpoint.
- Everything in the workbench config is basically the same but
  de-indented (upstream extracted it into a separate object which
  resulted in a de-indent), the ordering is slightly different, and
  instead of vscodeBase we now need vscodeBase + this._staticRoute since
  everything is served from a sub-path now.
- Move manifest link back to the root since that is where we host our
  manifest.
- Change RemoteAuthoritiesImpl to use the same path building method as
  in other places (+ instead of using URI.parse/join).
- Use existing host/port in RemoteAuthoritiesImpl and
  BrowserSocketFactory instead of patching them to use window.location
  (these are set from window.location to begin with so it should be the
  same result but with less patching).
- Since BrowserSocketFactory includes a sub-path now (endpoints were
  changed upstream to serve from /quality/commit instead of from the
  root) the patch there has changed to prepend the base to that
  path (instead of using the base directly).
- The workbench HTML now natively supports a base URL in the form of
  WORKBENCH_WEB_BASE_URL so no need for VS_BASE patches there anymore.
- Upstream added type="image/x-icon" so I did as well.
- Move the language patch to the end of the series so it is easier to
  eventually remove.
- Remove the existing NLS config in favor of one that supports
  extensions.
- Upstream deleted webview main.js and inlined it into the HTML so move
  that code (the parent origin check) into both those HTML files
  (index.html and index-no-csp.html).
- The remaining diff is from changes to the surrounding context or a
  line was changed slightly by upstream (for example renamed files or
  new arguments like to the remote authority resolver).

* fix: modify product.json before building

Code injects this into the client during the build process so it needs
to be updated before we build.

* fix: update inline script nonces

* Update HTML base path test

* fix: missing commit

Code overrides it with nothing.

The date is also already injected.

* fix: web extensions breaking when the commit changes

By just using the marketplace directly instead of going through the
backend.  I am not sure what the point is when searching extensions
already goes directly to the marketplace anyway.

But also remove the prefix that breaks this as well because otherwise
existing installations will break.
2022-06-21 21:51:46 +00:00

213 lines
8.7 KiB
Diff

Add support for telemetry endpoint
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
@@ -70,6 +70,7 @@ import { REMOTE_FILE_SYSTEM_CHANNEL_NAME
import { ExtensionHostStatusService, IExtensionHostStatusService } from 'vs/server/node/extensionHostStatusService';
import { IExtensionsScannerService } from 'vs/platform/extensionManagement/common/extensionsScannerService';
import { ExtensionsScannerService } from 'vs/server/node/extensionsScannerService';
+import { TelemetryClient } from "vs/server/node/telemetryClient";
import { NullPolicyService } from 'vs/platform/policy/common/policy';
const eventPrefix = 'monacoworkbench';
@@ -123,7 +124,11 @@ export async function setupServerService
let appInsightsAppender: ITelemetryAppender = NullAppender;
const machineId = await getMachineId();
if (supportsTelemetry(productService, environmentService)) {
- if (productService.aiConfig && productService.aiConfig.asimovKey) {
+ const telemetryEndpoint = process.env.CS_TELEMETRY_URL || "https://v1.telemetry.coder.com/track";
+ if (telemetryEndpoint) {
+ appInsightsAppender = new AppInsightsAppender(eventPrefix, null, () => new TelemetryClient(telemetryEndpoint) as any);
+ disposables.add(toDisposable(() => appInsightsAppender!.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
+ } else if (productService.aiConfig && productService.aiConfig.asimovKey) {
appInsightsAppender = new AppInsightsAppender(eventPrefix, null, productService.aiConfig.asimovKey);
disposables.add(toDisposable(() => appInsightsAppender!.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,135 @@
+import * as appInsights from 'applicationinsights';
+import * as https from 'https';
+import * as http from 'http';
+import * as os from 'os';
+
+class Channel {
+ public get _sender() {
+ throw new Error('unimplemented');
+ }
+ public get _buffer() {
+ throw new Error('unimplemented');
+ }
+
+ public setUseDiskRetryCaching(): void {
+ throw new Error('unimplemented');
+ }
+ public send(): void {
+ throw new Error('unimplemented');
+ }
+ public triggerSend(): void {
+ throw new Error('unimplemented');
+ }
+}
+
+// Unable to use implements because TypeScript tells you a private property is
+// missing but if you add it then it complains they have different private
+// properties. Uncommenting it during development can be helpful though to see
+// if anything is missing.
+export class TelemetryClient /* implements appInsights.TelemetryClient */ {
+ private _telemetryProcessors: any = undefined;
+ public context: any = undefined;
+ public commonProperties: any = undefined;
+ public config: any = {};
+ public quickPulseClient: any = undefined;
+
+ public channel: any = new Channel();
+
+ public constructor(private readonly endpoint: string) {
+ // Nothing to do.
+ }
+
+ public addTelemetryProcessor(): void {
+ throw new Error('unimplemented');
+ }
+
+ public clearTelemetryProcessors(): void {
+ if (this._telemetryProcessors) {
+ this._telemetryProcessors = undefined;
+ }
+ }
+
+ public runTelemetryProcessors(): void {
+ throw new Error('unimplemented');
+ }
+
+ public trackTrace(): void {
+ throw new Error('unimplemented');
+ }
+
+ public trackMetric(): void {
+ throw new Error('unimplemented');
+ }
+
+ public trackException(): void {
+ throw new Error('unimplemented');
+ }
+
+ public trackRequest(): void {
+ throw new Error('unimplemented');
+ }
+
+ public trackDependency(): void {
+ throw new Error('unimplemented');
+ }
+
+ public track(): void {
+ throw new Error('unimplemented');
+ }
+
+ public trackNodeHttpRequestSync(): void {
+ throw new Error('unimplemented');
+ }
+
+ public trackNodeHttpRequest(): void {
+ throw new Error('unimplemented');
+ }
+
+ public trackNodeHttpDependency(): void {
+ throw new Error('unimplemented');
+ }
+
+ public trackEvent(options: appInsights.Contracts.EventTelemetry): void {
+ if (!options.properties) {
+ options.properties = {};
+ }
+ if (!options.measurements) {
+ options.measurements = {};
+ }
+
+ try {
+ const cpus = os.cpus();
+ options.measurements.cores = cpus.length;
+ options.properties['common.cpuModel'] = cpus[0].model;
+ } catch (error) {}
+
+ try {
+ options.measurements.memoryFree = os.freemem();
+ options.measurements.memoryTotal = os.totalmem();
+ } catch (error) {}
+
+ try {
+ options.properties['common.shell'] = os.userInfo().shell;
+ options.properties['common.release'] = os.release();
+ options.properties['common.arch'] = os.arch();
+ } 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) {}
+ }
+
+ public flush(options: { callback: (v: string) => void }): void {
+ if (options.callback) {
+ options.callback('');
+ }
+ }
+}
Index: code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
@@ -120,16 +120,19 @@ export class TelemetryService extends Di
) {
super();
- if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.asimovKey) {
+ if (supportsTelemetry(productService, environmentService)) {
// If remote server is present send telemetry through that, else use the client side appender
- const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey);
- const config: ITelemetryServiceConfig = {
- appenders: [new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)],
- commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
- sendErrorTelemetry: this.sendErrorTelemetry,
- };
-
- this.impl = this._register(new BaseTelemetryService(config, configurationService, productService));
+ const telemetryProvider: ITelemetryAppender | undefined = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : productService.aiConfig?.asimovKey ? new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey) : undefined;
+ if (telemetryProvider) {
+ const config: ITelemetryServiceConfig = {
+ appenders: [new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)],
+ commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
+ sendErrorTelemetry: this.sendErrorTelemetry,
+ };
+ this.impl = this._register(new BaseTelemetryService(config, configurationService, productService));
+ } else {
+ this.impl = NullTelemetryService;
+ }
} else {
this.impl = NullTelemetryService;
}
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
@@ -320,6 +320,7 @@ export class WebClientServer {
scope: vscodeBase + '/',
path: base + '/_static/out/browser/serviceWorker.js',
},
+ enableTelemetry: this._productService.enableTelemetry,
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
},