Skip to content

Commit 8deed65

Browse files
authored
Allow the ability to opt out of cleaning (microsoft#166136)
* Add the ability to opt out of data cleaning * Comment * Update to Joh's suggested solution
1 parent 6e3dbd4 commit 8deed65

File tree

10 files changed

+42
-27
lines changed

10 files changed

+42
-27
lines changed

src/vs/platform/telemetry/common/serverTelemetryService.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ export class ServerTelemetryService extends TelemetryService implements IServerT
3030
this._injectedTelemetryLevel = injectedTelemetryLevel;
3131
}
3232

33-
override publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<void> {
33+
override publicLog(eventName: string, data?: ITelemetryData): Promise<void> {
3434
if (this._injectedTelemetryLevel < TelemetryLevel.USAGE) {
3535
return Promise.resolve(undefined);
3636
}
37-
return super.publicLog(eventName, data, anonymizeFilePaths);
37+
return super.publicLog(eventName, data);
3838
}
3939

40-
override publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>, anonymizeFilePaths?: boolean): Promise<void> {
41-
return this.publicLog(eventName, data as ITelemetryData | undefined, anonymizeFilePaths);
40+
override publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>): Promise<void> {
41+
return this.publicLog(eventName, data as ITelemetryData | undefined);
4242
}
4343

4444
override publicLogError(errorEventName: string, data?: ITelemetryData): Promise<void> {

src/vs/platform/telemetry/common/telemetry.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ export interface ITelemetryService {
3434
/**
3535
* @deprecated Use publicLog2 and the typescript GDPR annotation where possible
3636
*/
37-
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<void>;
37+
publicLog(eventName: string, data?: ITelemetryData): Promise<void>;
3838

3939
/**
4040
* Sends a telemetry event that has been privacy approved.
4141
* Do not call this unless you have been given approval.
4242
*/
43-
publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>, anonymizeFilePaths?: boolean): Promise<void>;
43+
publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>): Promise<void>;
4444

4545
/**
4646
* @deprecated Use publicLogError2 and the typescript GDPR annotation where possible

src/vs/platform/telemetry/common/telemetryService.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export class TelemetryService implements ITelemetryService {
102102
this._disposables.dispose();
103103
}
104104

105-
private _log(eventName: string, eventLevel: TelemetryLevel, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<any> {
105+
private _log(eventName: string, eventLevel: TelemetryLevel, data?: ITelemetryData): Promise<any> {
106106
// don't send events when the user is optout
107107
if (this.telemetryLevel.value < eventLevel) {
108108
return Promise.resolve(undefined);
@@ -128,12 +128,12 @@ export class TelemetryService implements ITelemetryService {
128128
});
129129
}
130130

131-
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<any> {
132-
return this._log(eventName, TelemetryLevel.USAGE, data, anonymizeFilePaths);
131+
publicLog(eventName: string, data?: ITelemetryData): Promise<any> {
132+
return this._log(eventName, TelemetryLevel.USAGE, data);
133133
}
134134

135-
publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>, anonymizeFilePaths?: boolean): Promise<any> {
136-
return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths);
135+
publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>): Promise<any> {
136+
return this.publicLog(eventName, data as ITelemetryData);
137137
}
138138

139139
publicLogError(errorEventName: string, data?: ITelemetryData): Promise<any> {
@@ -142,7 +142,7 @@ export class TelemetryService implements ITelemetryService {
142142
}
143143

144144
// Send error event and anonymize paths
145-
return this._log(errorEventName, TelemetryLevel.ERROR, data, true);
145+
return this._log(errorEventName, TelemetryLevel.ERROR, data);
146146
}
147147

148148
publicLogError2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>): Promise<any> {

src/vs/platform/telemetry/common/telemetryUtils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ import { verifyMicrosoftInternalDomain } from 'vs/platform/telemetry/common/comm
1515
import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings';
1616
import { ICustomEndpointTelemetryService, ITelemetryData, ITelemetryEndpoint, ITelemetryInfo, ITelemetryService, TelemetryConfiguration, TelemetryLevel, TELEMETRY_OLD_SETTING_ID, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry';
1717

18+
/**
19+
* A special class used to denoate a telemetry value which should not be clean.
20+
* This is because that value is "Trusted" not to contain identifiable information such as paths
21+
*/
22+
export class TrustedTelemetryValue {
23+
constructor(public readonly value: any) { }
24+
}
25+
1826
export class NullTelemetryServiceShape implements ITelemetryService {
1927
declare readonly _serviceBrand: undefined;
2028
readonly sendErrorTelemetry = false;
@@ -399,6 +407,12 @@ function removePropertiesWithPossibleUserInfo(property: string): string {
399407
*/
400408
export function cleanData(data: Record<string, any>, cleanUpPatterns: RegExp[]): Record<string, any> {
401409
return cloneAndChange(data, value => {
410+
411+
// If it's a trusted value it means it's okay to skip cleaning so we don't clean it
412+
if (value instanceof TrustedTelemetryValue) {
413+
return value.value;
414+
}
415+
402416
// We only know how to clean strings
403417
if (typeof value === 'string') {
404418
let updatedProperty = value;

src/vs/platform/telemetry/test/browser/telemetryService.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,8 @@ suite('TelemetryService', () => {
224224
return Promise.all(this.promises);
225225
}
226226

227-
override publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<void> {
228-
const p = super.publicLog(eventName, data, anonymizeFilePaths);
227+
override publicLog(eventName: string, data?: ITelemetryData): Promise<void> {
228+
const p = super.publicLog(eventName, data);
229229
// publicLog is called from the ctor and therefore promises can be undefined
230230
this.promises = this.promises ?? [];
231231
this.promises.push(p);

src/vs/workbench/browser/parts/editor/editorGroupView.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'
5353
import { isLinux, isMacintosh, isNative, isWindows } from 'vs/base/common/platform';
5454
import { ILogService } from 'vs/platform/log/common/log';
5555
import { getProgressBarStyles } from 'vs/platform/theme/browser/defaultStyles';
56+
import { TrustedTelemetryValue } from 'vs/platform/telemetry/common/telemetryUtils';
5657

5758
export class EditorGroupView extends Themable implements IEditorGroupView {
5859

@@ -642,7 +643,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
642643
// Remove query parameters from the resource extension
643644
const queryStringLocation = resourceExt.indexOf('?');
644645
resourceExt = queryStringLocation !== -1 ? resourceExt.substr(0, queryStringLocation) : resourceExt;
645-
descriptor['resource'] = { mimeType: getMimeTypes(resource).join(', '), scheme: resource.scheme, ext: resourceExt, path: hash(path) };
646+
descriptor['resource'] = { mimeType: new TrustedTelemetryValue(getMimeTypes(resource).join(', ')), scheme: resource.scheme, ext: resourceExt, path: hash(path) };
646647

647648
/* __GDPR__FRAGMENT__
648649
"EditorTelemetryDescriptor" : {

src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
1515
import { language } from 'vs/base/common/platform';
1616
import { Disposable } from 'vs/base/common/lifecycle';
1717
import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry';
18-
import { configurationTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
18+
import { configurationTelemetry, TrustedTelemetryValue } from 'vs/platform/telemetry/common/telemetryUtils';
1919
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
2020
import { ITextFileService, ITextFileSaveEvent, ITextFileResolveEvent } from 'vs/workbench/services/textfile/common/textfiles';
2121
import { extname, basename, isEqual, isEqualOrParent } from 'vs/base/common/resources';
@@ -28,7 +28,7 @@ import { ViewContainerLocation } from 'vs/workbench/common/views';
2828
import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
2929

3030
type TelemetryData = {
31-
mimeType: string;
31+
mimeType: TrustedTelemetryValue;
3232
ext: string;
3333
path: number;
3434
reason?: number;
@@ -216,7 +216,7 @@ export class TelemetryContribution extends Disposable implements IWorkbenchContr
216216
const fileName = basename(resource);
217217
const path = resource.scheme === Schemas.file ? resource.fsPath : resource.path;
218218
const telemetryData = {
219-
mimeType: getMimeTypes(resource).join(', '),
219+
mimeType: new TrustedTelemetryValue(getMimeTypes(resource).join(', ')),
220220
ext,
221221
path: hash(path),
222222
reason,

src/vs/workbench/services/extensions/common/extensionHostManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class ExtensionHostManager extends Disposable implements IExtensionHostManager {
165165
if (err && err.stack) {
166166
failureTelemetryEvent.errorStack = err.stack;
167167
}
168-
this._telemetryService.publicLog2<ExtensionHostStartupEvent, ExtensionHostStartupClassification>('extensionHostStartup', failureTelemetryEvent, true);
168+
this._telemetryService.publicLog2<ExtensionHostStartupEvent, ExtensionHostStartupClassification>('extensionHostStartup', failureTelemetryEvent);
169169

170170
return null;
171171
}

src/vs/workbench/services/telemetry/browser/telemetryService.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,12 @@ export class TelemetryService extends Disposable implements ITelemetryService {
8787
return this.impl.telemetryLevel;
8888
}
8989

90-
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<void> {
91-
return this.impl.publicLog(eventName, data, anonymizeFilePaths);
90+
publicLog(eventName: string, data?: ITelemetryData): Promise<void> {
91+
return this.impl.publicLog(eventName, data);
9292
}
9393

94-
publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>, anonymizeFilePaths?: boolean) {
95-
return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths);
94+
publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>) {
95+
return this.publicLog(eventName, data as ITelemetryData);
9696
}
9797

9898
publicLogError(errorEventName: string, data?: ITelemetryData): Promise<void> {

src/vs/workbench/services/telemetry/electron-sandbox/telemetryService.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ export class TelemetryService extends Disposable implements ITelemetryService {
6262
return this.impl.telemetryLevel;
6363
}
6464

65-
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<void> {
66-
return this.impl.publicLog(eventName, data, anonymizeFilePaths);
65+
publicLog(eventName: string, data?: ITelemetryData): Promise<void> {
66+
return this.impl.publicLog(eventName, data);
6767
}
6868

69-
publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>, anonymizeFilePaths?: boolean) {
70-
return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths);
69+
publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>) {
70+
return this.publicLog(eventName, data as ITelemetryData);
7171
}
7272

7373
publicLogError(errorEventName: string, data?: ITelemetryData): Promise<void> {

0 commit comments

Comments
 (0)