Files
code/src/vs/platform/telemetry/common/serverTelemetryService.ts
T
zeekayandHanzo Dev d5f28e6ed9 one contribution, one directory — finish the upstream merge
The rebrand renamed platform/void and contrib/void/browser to code; upstream then
moved platform/void into contrib/void/{common,electron-main}. Git could not see
those as the same move, so the merge kept both sides and the contribution came out
split across three directories — browser/ under contrib/code, common/ and
electron-main/ under contrib/void, a pre-move copy under platform/code. Every
../common/x.js import out of browser/ dangled. Shared-file conflicts were settled
by replacing upstream's lines instead of keeping both, so extHost.protocol lost
MainThreadChatStatus and ExtHostMcp and telemetryService lost the body of _log.

The fork's only change to src/ is that rename, so the tree it should have is
upstream's with the rename applied. This is that tree. What upstream deleted goes
with it: inlineDiffsService and the InlineDiff extension host API.

buildreact joins the gate because react/out is generated rather than committed and
the workbench imports its mount functions from there — the order HOW_TO_CONTRIBUTE
already gives. compile alone reported 281 errors; ci, buildreact and compile
together finish with 0.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-10 00:07:08 -07:00

73 lines
3.6 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IConfigurationService } from '../../configuration/common/configuration.js';
import { refineServiceDecorator } from '../../instantiation/common/instantiation.js';
import { IProductService } from '../../product/common/productService.js';
import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from './gdprTypings.js';
import { ITelemetryData, ITelemetryService, TelemetryLevel } from './telemetry.js';
import { ITelemetryServiceConfig, TelemetryService } from './telemetryService.js';
import { NullTelemetryServiceShape } from './telemetryUtils.js';
export interface IServerTelemetryService extends ITelemetryService {
updateInjectedTelemetryLevel(telemetryLevel: TelemetryLevel): Promise<void>;
}
export class ServerTelemetryService extends TelemetryService implements IServerTelemetryService {
// Because we cannot read the workspace config on the remote site
// the ServerTelemetryService is responsible for knowing its telemetry level
// this is done through IPC calls and initial value injections
private _injectedTelemetryLevel: TelemetryLevel;
constructor(
config: ITelemetryServiceConfig,
injectedTelemetryLevel: TelemetryLevel,
@IConfigurationService _configurationService: IConfigurationService,
@IProductService _productService: IProductService
) {
super(config, _configurationService, _productService);
this._injectedTelemetryLevel = injectedTelemetryLevel;
}
override publicLog(eventName: string, data?: ITelemetryData) {
if (this._injectedTelemetryLevel < TelemetryLevel.USAGE) {
return;
}
return super.publicLog(eventName, data);
}
override publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>) {
return this.publicLog(eventName, data as ITelemetryData | undefined);
}
override publicLogError(errorEventName: string, data?: ITelemetryData) {
if (this._injectedTelemetryLevel < TelemetryLevel.ERROR) {
return Promise.resolve(undefined);
}
return super.publicLogError(errorEventName, data);
}
override publicLogError2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>) {
return this.publicLogError(eventName, data as ITelemetryData | undefined);
}
async updateInjectedTelemetryLevel(telemetryLevel: TelemetryLevel): Promise<void> {
if (telemetryLevel === undefined) {
this._injectedTelemetryLevel = TelemetryLevel.NONE;
throw new Error('Telemetry level cannot be undefined. This will cause infinite looping!');
}
// We always take the most restrictive level because we don't want multiple clients to connect and send data when one client does not consent
this._injectedTelemetryLevel = this._injectedTelemetryLevel ? Math.min(this._injectedTelemetryLevel, telemetryLevel) : telemetryLevel;
if (this._injectedTelemetryLevel === TelemetryLevel.NONE) {
this.dispose();
}
}
}
export const ServerNullTelemetryService = new class extends NullTelemetryServiceShape implements IServerTelemetryService {
async updateInjectedTelemetryLevel(): Promise<void> { return; } // No-op, telemetry is already disabled
};
export const IServerTelemetryService = refineServiceDecorator<ITelemetryService, IServerTelemetryService>(ITelemetryService);