mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from master
This commit is contained in:
@@ -2,9 +2,7 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export const ITelemetryService = createDecorator<ITelemetryService>('telemetryService');
|
||||
@@ -29,9 +27,9 @@ export interface ITelemetryService {
|
||||
* Sends a telemetry event that has been privacy approved.
|
||||
* Do not call this unless you have been given approval.
|
||||
*/
|
||||
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): TPromise<void>;
|
||||
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Thenable<void>;
|
||||
|
||||
getTelemetryInfo(): TPromise<ITelemetryInfo>;
|
||||
getTelemetryInfo(): Thenable<ITelemetryInfo>;
|
||||
|
||||
isOptedIn: boolean;
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
export interface ITelemetryLog {
|
||||
eventName: string;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
export interface ITelemetryAppenderChannel extends IChannel {
|
||||
call(command: 'log', data: ITelemetryLog): TPromise<void>;
|
||||
call(command: string, arg: any): TPromise<any>;
|
||||
}
|
||||
|
||||
export class TelemetryAppenderChannel implements ITelemetryAppenderChannel {
|
||||
|
||||
constructor(private appender: ITelemetryAppender) { }
|
||||
|
||||
listen<T>(event: string, arg?: any): Event<T> {
|
||||
throw new Error('No events');
|
||||
}
|
||||
|
||||
call(command: string, { eventName, data }: ITelemetryLog): TPromise<any> {
|
||||
this.appender.log(eventName, data);
|
||||
return TPromise.as(null);
|
||||
}
|
||||
}
|
||||
|
||||
export class TelemetryAppenderClient implements ITelemetryAppender {
|
||||
|
||||
constructor(private channel: ITelemetryAppenderChannel) { }
|
||||
|
||||
log(eventName: string, data?: any): any {
|
||||
this.channel.call('log', { eventName, data })
|
||||
.done(null, err => `Failed to log telemetry: ${console.warn(err)}`);
|
||||
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
dispose(): any {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { escapeRegExpCharacters } from 'vs/base/common/strings';
|
||||
import { ITelemetryService, ITelemetryInfo, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
@@ -12,14 +10,13 @@ import { ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils'
|
||||
import { optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { cloneAndChange, mixin } from 'vs/base/common/objects';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
|
||||
export interface ITelemetryServiceConfig {
|
||||
appender: ITelemetryAppender;
|
||||
commonProperties?: TPromise<{ [name: string]: any }>;
|
||||
commonProperties?: Thenable<{ [name: string]: any }>;
|
||||
piiPaths?: string[];
|
||||
}
|
||||
|
||||
@@ -31,7 +28,7 @@ export class TelemetryService implements ITelemetryService {
|
||||
_serviceBrand: any;
|
||||
|
||||
private _appender: ITelemetryAppender;
|
||||
private _commonProperties: TPromise<{ [name: string]: any; }>;
|
||||
private _commonProperties: Thenable<{ [name: string]: any; }>;
|
||||
private _piiPaths: string[];
|
||||
private _userOptIn: boolean;
|
||||
|
||||
@@ -43,7 +40,7 @@ export class TelemetryService implements ITelemetryService {
|
||||
@optional(IConfigurationService) private _configurationService: IConfigurationService
|
||||
) {
|
||||
this._appender = config.appender;
|
||||
this._commonProperties = config.commonProperties || TPromise.as({});
|
||||
this._commonProperties = config.commonProperties || Promise.resolve({});
|
||||
this._piiPaths = config.piiPaths || [];
|
||||
this._userOptIn = true;
|
||||
|
||||
@@ -75,7 +72,7 @@ export class TelemetryService implements ITelemetryService {
|
||||
return this._userOptIn;
|
||||
}
|
||||
|
||||
getTelemetryInfo(): TPromise<ITelemetryInfo> {
|
||||
getTelemetryInfo(): Thenable<ITelemetryInfo> {
|
||||
return this._commonProperties.then(values => {
|
||||
// well known properties
|
||||
let sessionId = values['sessionID'];
|
||||
@@ -90,10 +87,10 @@ export class TelemetryService implements ITelemetryService {
|
||||
this._disposables = dispose(this._disposables);
|
||||
}
|
||||
|
||||
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): TPromise<any> {
|
||||
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Thenable<any> {
|
||||
// don't send events when the user is optout
|
||||
if (!this._userOptIn) {
|
||||
return TPromise.as(undefined);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
return this._commonProperties.then(values => {
|
||||
@@ -134,6 +131,8 @@ export class TelemetryService implements ITelemetryService {
|
||||
|
||||
const nodeModulesRegex = /^[\\\/]?(node_modules|node_modules\.asar)[\\\/]/;
|
||||
const fileRegex = /(file:\/\/)?([a-zA-Z]:(\\\\|\\|\/)|(\\\\|\\|\/))?([\w-\._]+(\\\\|\\|\/))+[\w-\._]*/g;
|
||||
let lastIndex = 0;
|
||||
updatedStack = '';
|
||||
|
||||
while (true) {
|
||||
const result = fileRegex.exec(stack);
|
||||
@@ -142,9 +141,13 @@ export class TelemetryService implements ITelemetryService {
|
||||
}
|
||||
// Anoynimize user file paths that do not need to be retained or cleaned up.
|
||||
if (!nodeModulesRegex.test(result[0]) && cleanUpIndexes.every(([x, y]) => result.index < x || result.index >= y)) {
|
||||
updatedStack = updatedStack.slice(0, result.index) + result[0].replace(/./g, 'a') + updatedStack.slice(fileRegex.lastIndex);
|
||||
updatedStack += stack.substring(lastIndex, result.index) + '<REDACTED: user-file-path>';
|
||||
lastIndex = fileRegex.lastIndex;
|
||||
}
|
||||
}
|
||||
if (lastIndex < stack.length) {
|
||||
updatedStack += stack.substr(lastIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// sanitize with configured cleanup patterns
|
||||
@@ -171,4 +174,4 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat
|
||||
'tags': ['usesOnlineServices']
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { guessMimeTypes } from 'vs/base/common/mime';
|
||||
import * as paths from 'vs/base/common/paths';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IConfigurationService, ConfigurationTarget, ConfigurationTargetToString } from 'vs/platform/configuration/common/configuration';
|
||||
import { IKeybindingService, KeybindingSource } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { ITelemetryService, ITelemetryInfo, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
@@ -17,11 +15,11 @@ import { ILogService } from 'vs/platform/log/common/log';
|
||||
export const NullTelemetryService = new class implements ITelemetryService {
|
||||
_serviceBrand: undefined;
|
||||
publicLog(eventName: string, data?: ITelemetryData) {
|
||||
return TPromise.wrap<void>(null);
|
||||
return Promise.resolve(void 0);
|
||||
}
|
||||
isOptedIn: true;
|
||||
getTelemetryInfo(): TPromise<ITelemetryInfo> {
|
||||
return TPromise.wrap({
|
||||
getTelemetryInfo(): Promise<ITelemetryInfo> {
|
||||
return Promise.resolve({
|
||||
instanceId: 'someValue.instanceId',
|
||||
sessionId: 'someValue.sessionId',
|
||||
machineId: 'someValue.machineId'
|
||||
@@ -31,17 +29,17 @@ export const NullTelemetryService = new class implements ITelemetryService {
|
||||
|
||||
export interface ITelemetryAppender {
|
||||
log(eventName: string, data: any): void;
|
||||
dispose(): TPromise<any>;
|
||||
dispose(): Thenable<any>;
|
||||
}
|
||||
|
||||
export function combinedAppender(...appenders: ITelemetryAppender[]): ITelemetryAppender {
|
||||
return {
|
||||
log: (e, d) => appenders.forEach(a => a.log(e, d)),
|
||||
dispose: () => TPromise.join(appenders.map(a => a.dispose()))
|
||||
dispose: () => Promise.all(appenders.map(a => a.dispose()))
|
||||
};
|
||||
}
|
||||
|
||||
export const NullAppender: ITelemetryAppender = { log: () => null, dispose: () => TPromise.as(null) };
|
||||
export const NullAppender: ITelemetryAppender = { log: () => null, dispose: () => Promise.resolve(null) };
|
||||
|
||||
|
||||
export class LogAppender implements ITelemetryAppender {
|
||||
@@ -49,8 +47,8 @@ export class LogAppender implements ITelemetryAppender {
|
||||
private commonPropertiesRegex = /^sessionID$|^version$|^timestamp$|^commitHash$|^common\./;
|
||||
constructor(@ILogService private readonly _logService: ILogService) { }
|
||||
|
||||
dispose(): TPromise<any> {
|
||||
return TPromise.as(undefined);
|
||||
dispose(): Promise<any> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
log(eventName: string, data: any): void {
|
||||
@@ -67,26 +65,27 @@ export class LogAppender implements ITelemetryAppender {
|
||||
/* __GDPR__FRAGMENT__
|
||||
"URIDescriptor" : {
|
||||
"mimeType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"scheme": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"ext": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"path": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
export interface URIDescriptor {
|
||||
mimeType?: string;
|
||||
scheme?: string;
|
||||
ext?: string;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
export function telemetryURIDescriptor(uri: URI, hashPath: (path: string) => string): URIDescriptor {
|
||||
const fsPath = uri && uri.fsPath;
|
||||
return fsPath ? { mimeType: guessMimeTypes(fsPath).join(', '), ext: paths.extname(fsPath), path: hashPath(fsPath) } : {};
|
||||
return fsPath ? { mimeType: guessMimeTypes(fsPath).join(', '), scheme: uri.scheme, ext: paths.extname(fsPath), path: hashPath(fsPath) } : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Only add settings that cannot contain any personal/private information of users (PII).
|
||||
*/
|
||||
const configurationValueWhitelist = [
|
||||
'editor.tabCompletion',
|
||||
'editor.fontFamily',
|
||||
'editor.fontWeight',
|
||||
'editor.fontSize',
|
||||
@@ -113,8 +112,11 @@ const configurationValueWhitelist = [
|
||||
'editor.multiCursorModifier',
|
||||
'editor.quickSuggestions',
|
||||
'editor.quickSuggestionsDelay',
|
||||
'editor.parameterHints',
|
||||
'editor.parameterHints.enabled',
|
||||
'editor.parameterHints.cycle',
|
||||
'editor.autoClosingBrackets',
|
||||
'editor.autoClosingQuotes',
|
||||
'editor.autoSurround',
|
||||
'editor.autoIndent',
|
||||
'editor.formatOnType',
|
||||
'editor.formatOnPaste',
|
||||
@@ -127,11 +129,13 @@ const configurationValueWhitelist = [
|
||||
'editor.suggestSelection',
|
||||
'editor.suggestFontSize',
|
||||
'editor.suggestLineHeight',
|
||||
'editor.tabCompletion',
|
||||
'editor.selectionHighlight',
|
||||
'editor.occurrencesHighlight',
|
||||
'editor.overviewRulerLanes',
|
||||
'editor.overviewRulerBorder',
|
||||
'editor.cursorBlinking',
|
||||
'editor.cursorSmoothCaretAnimation',
|
||||
'editor.cursorStyle',
|
||||
'editor.mouseWheelZoom',
|
||||
'editor.fontLigatures',
|
||||
@@ -155,6 +159,7 @@ const configurationValueWhitelist = [
|
||||
'breadcrumbs.enabled',
|
||||
'breadcrumbs.filePath',
|
||||
'breadcrumbs.symbolPath',
|
||||
'breadcrumbs.symbolSortOrder',
|
||||
'breadcrumbs.useQuickPick',
|
||||
'explorer.openEditors.visible',
|
||||
'extensions.autoUpdate',
|
||||
@@ -180,6 +185,7 @@ const configurationValueWhitelist = [
|
||||
'workbench.editor.enablePreview',
|
||||
'workbench.editor.enablePreviewFromQuickOpen',
|
||||
'workbench.editor.showTabs',
|
||||
'workbench.editor.highlightModifiedTabs',
|
||||
'workbench.editor.swipeToNavigate',
|
||||
'workbench.sideBar.location',
|
||||
'workbench.startupEditor',
|
||||
@@ -197,7 +203,7 @@ export function configurationTelemetry(telemetryService: ITelemetryService, conf
|
||||
}
|
||||
*/
|
||||
telemetryService.publicLog('updateConfiguration', {
|
||||
configurationSource: ConfigurationTarget[event.source],
|
||||
configurationSource: ConfigurationTargetToString(event.source),
|
||||
configurationKeys: flattenKeys(event.sourceConfig)
|
||||
});
|
||||
/* __GDPR__
|
||||
@@ -207,7 +213,7 @@ export function configurationTelemetry(telemetryService: ITelemetryService, conf
|
||||
}
|
||||
*/
|
||||
telemetryService.publicLog('updateConfigurationValues', {
|
||||
configurationSource: ConfigurationTarget[event.source],
|
||||
configurationSource: ConfigurationTargetToString(event.source),
|
||||
configurationValues: flattenValues(event.sourceConfig, configurationValueWhitelist)
|
||||
});
|
||||
}
|
||||
@@ -264,5 +270,5 @@ function flattenValues(value: Object, keys: string[]): { [key: string]: any }[]
|
||||
array.push({ [key]: v });
|
||||
}
|
||||
return array;
|
||||
}, []);
|
||||
}, <{ [key: string]: any }[]>[]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user