mirror of
https://github.com/Microsoft/vscode
synced 2024-09-19 18:48:00 +00:00
Initial first run of telemetry output API (#157807)
* Initial first run of telemetry output API * Add proposed api check
This commit is contained in:
parent
f6a746fc46
commit
dbbf24add8
|
@ -86,6 +86,7 @@ export interface IEnvironmentService {
|
|||
// --- telemetry
|
||||
disableTelemetry: boolean;
|
||||
telemetryLogResource: URI;
|
||||
extensionTelemetryLogResource: URI;
|
||||
serviceMachineIdResource: URI;
|
||||
|
||||
// --- Policy
|
||||
|
|
|
@ -226,6 +226,7 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron
|
|||
|
||||
@memoize
|
||||
get telemetryLogResource(): URI { return URI.file(join(this.logsPath, 'telemetry.log')); }
|
||||
get extensionTelemetryLogResource(): URI { return URI.file(join(this.logsPath, 'extensionTelemetry.log')); }
|
||||
get disableTelemetry(): boolean { return !!this.args['disable-telemetry']; }
|
||||
|
||||
@memoize
|
||||
|
|
|
@ -24,7 +24,7 @@ export class TelemetryLogAppender extends Disposable implements ITelemetryAppend
|
|||
this.logger = this._register(logger);
|
||||
} else {
|
||||
this.logger = this._register(loggerService.createLogger(environmentService.telemetryLogResource));
|
||||
this.logger.info('The below are logs for every telemetry event sent from VS Code once the log level is set to trace.');
|
||||
this.logger.info('Below are logs for every telemetry event sent from VS Code once the log level is set to trace.');
|
||||
this.logger.info('===========================================================');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ILogger, ILoggerService } from 'vs/platform/log/common/log';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings';
|
||||
import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
@ -18,14 +19,26 @@ export class MainThreadTelemetry extends Disposable implements MainThreadTelemet
|
|||
|
||||
private static readonly _name = 'pluginHostTelemetry';
|
||||
|
||||
private readonly _extensionTelemetryLog: ILogger;
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
||||
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
|
||||
@IProductService private readonly _productService: IProductService
|
||||
@IProductService private readonly _productService: IProductService,
|
||||
@ILoggerService loggerService: ILoggerService,
|
||||
) {
|
||||
super();
|
||||
|
||||
const logger = loggerService.getLogger(this._environmentService.extensionTelemetryLogResource);
|
||||
if (logger) {
|
||||
this._extensionTelemetryLog = this._register(logger);
|
||||
} else {
|
||||
this._extensionTelemetryLog = this._register(loggerService.createLogger(this._environmentService.extensionTelemetryLogResource));
|
||||
this._extensionTelemetryLog.info('Below are logs for extension telemetry events sent to the telemetry output channel API once the log level is set to trace.');
|
||||
this._extensionTelemetryLog.info('===========================================================');
|
||||
}
|
||||
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTelemetry);
|
||||
|
||||
if (supportsTelemetry(this._productService, this._environmentService)) {
|
||||
|
@ -54,6 +67,11 @@ export class MainThreadTelemetry extends Disposable implements MainThreadTelemet
|
|||
$publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>): void {
|
||||
this.$publicLog(eventName, data as any);
|
||||
}
|
||||
|
||||
$logTelemetryToOutputChannel(eventName: string, data: Record<string, any>) {
|
||||
this._extensionTelemetryLog.trace(eventName, data);
|
||||
this._extensionTelemetryLog.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ import { combinedDisposable } from 'vs/base/common/lifecycle';
|
|||
import { checkProposedApiEnabled, ExtensionIdentifierSet, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { DebugConfigurationProviderTriggerKind } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { equalsIgnoreCase } from 'vs/base/common/strings';
|
||||
import { IExtHostTelemetryLogService } from 'vs/workbench/api/common/extHostTelemetryLogService';
|
||||
|
||||
export interface IExtensionRegistries {
|
||||
mine: ExtensionDescriptionRegistry;
|
||||
|
@ -123,6 +124,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
const extHostLoggerService = accessor.get(ILoggerService);
|
||||
const extHostLogService = accessor.get(ILogService);
|
||||
const extHostTunnelService = accessor.get(IExtHostTunnelService);
|
||||
const extHostTelemetryLogService = accessor.get(IExtHostTelemetryLogService);
|
||||
const extHostApiDeprecation = accessor.get(IExtHostApiDeprecationService);
|
||||
const extHostWindow = accessor.get(IExtHostWindow);
|
||||
const extHostSecretState = accessor.get(IExtHostSecretState);
|
||||
|
@ -795,6 +797,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
get tabGroups(): vscode.TabGroups {
|
||||
return extHostEditorTabs.tabGroups;
|
||||
},
|
||||
logTelemetryToOutputChannel(eventName: string, data: Record<string, any>): void {
|
||||
checkProposedApiEnabled(extension, 'telemetryLog');
|
||||
extHostTelemetryLogService.logToTelemetryOutputChannel(extension, eventName, data);
|
||||
}
|
||||
};
|
||||
|
||||
// namespace: workspace
|
||||
|
|
|
@ -27,6 +27,7 @@ import { ExtHostLoggerService } from 'vs/workbench/api/common/extHostLoggerServi
|
|||
import { ILoggerService, ILogService } from 'vs/platform/log/common/log';
|
||||
import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService';
|
||||
import { ExtHostVariableResolverProviderService, IExtHostVariableResolverProvider } from 'vs/workbench/api/common/extHostVariableResolverService';
|
||||
import { ExtHostTelemetryLogService, IExtHostTelemetryLogService } from 'vs/workbench/api/common/extHostTelemetryLogService';
|
||||
|
||||
registerSingleton(ILoggerService, ExtHostLoggerService);
|
||||
registerSingleton(ILogService, ExtHostLogService);
|
||||
|
@ -48,5 +49,6 @@ registerSingleton(IExtHostWindow, ExtHostWindow);
|
|||
registerSingleton(IExtHostWorkspace, ExtHostWorkspace);
|
||||
registerSingleton(IExtHostSecretState, ExtHostSecretState);
|
||||
registerSingleton(IExtHostTelemetry, ExtHostTelemetry);
|
||||
registerSingleton(IExtHostTelemetryLogService, ExtHostTelemetryLogService);
|
||||
registerSingleton(IExtHostEditorTabs, ExtHostEditorTabs);
|
||||
registerSingleton(IExtHostVariableResolverProvider, ExtHostVariableResolverProviderService);
|
||||
|
|
|
@ -599,6 +599,7 @@ export interface MainThreadStorageShape extends IDisposable {
|
|||
export interface MainThreadTelemetryShape extends IDisposable {
|
||||
$publicLog(eventName: string, data?: any): void;
|
||||
$publicLog2<E extends ClassifiedEvent<OmitMetadata<T>> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck<T, E>): void;
|
||||
$logTelemetryToOutputChannel(eventName: string, data: Record<string, any>): void;
|
||||
}
|
||||
|
||||
export interface MainThreadEditorInsetsShape extends IDisposable {
|
||||
|
|
34
src/vs/workbench/api/common/extHostTelemetryLogService.ts
Normal file
34
src/vs/workbench/api/common/extHostTelemetryLogService.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
|
||||
export interface IExtHostTelemetryLogService {
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
logToTelemetryOutputChannel(extension: IExtensionDescription, eventName: string, data: Record<string, any>): void;
|
||||
}
|
||||
|
||||
export const IExtHostTelemetryLogService = createDecorator<IExtHostTelemetryLogService>('IExtHostTelemetryLogService');
|
||||
|
||||
export class ExtHostTelemetryLogService implements IExtHostTelemetryLogService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private readonly _telemetryShape: extHostProtocol.MainThreadTelemetryShape;
|
||||
|
||||
constructor(
|
||||
@IExtHostRpcService rpc: IExtHostRpcService,
|
||||
) {
|
||||
this._telemetryShape = rpc.getProxy(extHostProtocol.MainContext.MainThreadTelemetry);
|
||||
}
|
||||
|
||||
public logToTelemetryOutputChannel(extension: IExtensionDescription, eventName: string, data: Record<string, any>): void {
|
||||
this._telemetryShape.$logTelemetryToOutputChannel(`${extension.identifier.value}/${eventName}`, data);
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ export const sharedLogChannelId = 'sharedLog';
|
|||
export const rendererLogChannelId = 'rendererLog';
|
||||
export const extHostLogChannelId = 'extHostLog';
|
||||
export const telemetryLogChannelId = 'telemetryLog';
|
||||
export const extensionTelemetryLogChannelId = 'extensionTelemetryLog';
|
||||
export const userDataSyncLogChannelId = 'userDataSyncLog';
|
||||
export const editSessionsLogChannelId = 'editSessionsSyncLog';
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ class LogOutputChannels extends Disposable implements IWorkbenchContribution {
|
|||
const registerTelemetryChannel = () => {
|
||||
if (supportsTelemetry(this.productService, this.environmentService) && this.logService.getLevel() === LogLevel.Trace) {
|
||||
this.registerLogChannel(Constants.telemetryLogChannelId, nls.localize('telemetryLog', "Telemetry"), this.environmentService.telemetryLogResource);
|
||||
this.registerLogChannel(Constants.extensionTelemetryLogChannelId, nls.localize('extensionTelemetryLog', "Extension Telemetry"), this.environmentService.extensionTelemetryLogResource);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -189,6 +189,7 @@ export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvi
|
|||
|
||||
@memoize
|
||||
get telemetryLogResource(): URI { return joinPath(this.logsHome, 'telemetry.log'); }
|
||||
get extensionTelemetryLogResource(): URI { return joinPath(this.logsHome, 'extensionTelemetry.log'); }
|
||||
|
||||
@memoize
|
||||
get disableTelemetry(): boolean { return false; }
|
||||
|
|
|
@ -58,6 +58,7 @@ export const allApiProposals = Object.freeze({
|
|||
tabInputTextMerge: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.tabInputTextMerge.d.ts',
|
||||
taskPresentationGroup: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.taskPresentationGroup.d.ts',
|
||||
telemetry: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.telemetry.d.ts',
|
||||
telemetryLog: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.telemetryLog.d.ts',
|
||||
terminalDataWriteEvent: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalDataWriteEvent.d.ts',
|
||||
terminalDimensions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalDimensions.d.ts',
|
||||
testCoverage: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testCoverage.d.ts',
|
||||
|
|
|
@ -9,15 +9,15 @@ declare module 'vscode' {
|
|||
/**
|
||||
* Whether or not usage telemetry collection is allowed
|
||||
*/
|
||||
isUsageEnabled: boolean;
|
||||
readonly isUsageEnabled: boolean;
|
||||
/**
|
||||
* Whether or not crash error telemetry collection is allowed
|
||||
*/
|
||||
isErrorsEnabled: boolean;
|
||||
readonly isErrorsEnabled: boolean;
|
||||
/**
|
||||
* Whether or not crash report collection is allowed
|
||||
*/
|
||||
isCrashEnabled: boolean;
|
||||
readonly isCrashEnabled: boolean;
|
||||
}
|
||||
|
||||
export namespace env {
|
||||
|
|
19
src/vscode-dts/vscode.proposed.telemetryLog.d.ts
vendored
Normal file
19
src/vscode-dts/vscode.proposed.telemetryLog.d.ts
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'vscode' {
|
||||
|
||||
export namespace window {
|
||||
/**
|
||||
* Logs a telemetry event to a shared extension output channel when the log level is set to trace.
|
||||
* This is similar in function to cores' telemetry output channel that can be seen when log level is set to trace.
|
||||
* Extension authors should only log to the output channel when sending telemetry.
|
||||
*
|
||||
* @param eventName The name of the telemetry event
|
||||
* @param data The data associated with the telemetry event
|
||||
*/
|
||||
export function logTelemetryToOutputChannel(eventName: string, data: Record<string, any>): void;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue