Path: blob/main/src/vs/platform/dataChannel/browser/forwardingTelemetryService.ts
4777 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { ClassifiedEvent, OmitMetadata, IGDPRProperty, StrictPropertyCheck } from '../../telemetry/common/gdprTypings.js';6import { ITelemetryData, ITelemetryService, TelemetryLevel } from '../../telemetry/common/telemetry.js';7import { IDataChannelService } from '../common/dataChannel.js';89export class InterceptingTelemetryService implements ITelemetryService {10_serviceBrand: undefined;1112constructor(13private readonly _baseService: ITelemetryService,14private readonly _intercept: (eventName: string, data?: ITelemetryData) => void,15) { }1617get telemetryLevel(): TelemetryLevel {18return this._baseService.telemetryLevel;19}2021get sessionId(): string {22return this._baseService.sessionId;23}2425get machineId(): string {26return this._baseService.machineId;27}2829get sqmId(): string {30return this._baseService.sqmId;31}3233get devDeviceId(): string {34return this._baseService.devDeviceId;35}3637get firstSessionDate(): string {38return this._baseService.firstSessionDate;39}4041get msftInternal(): boolean | undefined {42return this._baseService.msftInternal;43}4445get sendErrorTelemetry(): boolean {46return this._baseService.sendErrorTelemetry;47}4849publicLog(eventName: string, data?: ITelemetryData): void {50this._intercept(eventName, data);51this._baseService.publicLog(eventName, data);52}5354publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>): void {55this._intercept(eventName, data);56this._baseService.publicLog2(eventName, data);57}5859publicLogError(errorEventName: string, data?: ITelemetryData): void {60this._intercept(errorEventName, data);61this._baseService.publicLogError(errorEventName, data);62}6364publicLogError2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>): void {65this._intercept(eventName, data);66this._baseService.publicLogError2(eventName, data);67}6869setExperimentProperty(name: string, value: string): void {70this._baseService.setExperimentProperty(name, value);71}72}7374export interface IEditTelemetryData {75eventName: string;76data: Record<string, unknown>;77}7879export class DataChannelForwardingTelemetryService extends InterceptingTelemetryService {80constructor(81@ITelemetryService telemetryService: ITelemetryService,82@IDataChannelService dataChannelService: IDataChannelService,83) {84super(telemetryService, (eventName, data) => {85// filter for extension86let forward = true;87if (data && shouldForwardToChannel in data) {88forward = Boolean(data[shouldForwardToChannel]);89}9091if (forward) {92dataChannelService.getDataChannel<IEditTelemetryData>('editTelemetry').sendData({ eventName, data: data ?? {} });93}94});95}96}9798const shouldForwardToChannel = Symbol('shouldForwardToChannel');99export function forwardToChannelIf(value: boolean): Record<string, unknown> {100return {101// This will not be sent via telemetry, it is just a marker102[shouldForwardToChannel]: value103};104}105106export function isCopilotLikeExtension(extensionId: string | undefined): boolean {107if (!extensionId) {108return false;109}110const extIdLowerCase = extensionId.toLowerCase();111return extIdLowerCase === 'github.copilot' || extIdLowerCase === 'github.copilot-chat';112}113114115