Skip to content

Commit

Permalink
vscode: add TelemetryLogger support (#12453)
Browse files Browse the repository at this point in the history
Closes: #12232

The commit adds support for the `TelemetryLogger` VS Code API in addition to other related functionality.

Contributed on behalf of STMicroelectronics

Signed-off-by: Remi Schnekenburger <[email protected]>
  • Loading branch information
rschnekenbu authored May 9, 2023
1 parent f906362 commit 934931f
Show file tree
Hide file tree
Showing 9 changed files with 606 additions and 17 deletions.
1 change: 1 addition & 0 deletions packages/core/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ export * from './strings';
export * from './types';
export { default as URI } from './uri';
export * from './view-column';
export * from './telemetry';

49 changes: 48 additions & 1 deletion packages/core/src/common/objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// *****************************************************************************

import { isObject } from './types';
import { isObject, isUndefined } from './types';

export function deepClone<T>(obj: T): T {
if (!isObject(obj)) {
Expand Down Expand Up @@ -70,3 +70,50 @@ export function notEmpty<T>(arg: T | undefined | null): arg is T {
export function isEmpty(arg: Object): boolean {
return Object.keys(arg).length === 0 && arg.constructor === Object;
}

// copied and modified from https://github.com/microsoft/vscode/blob/1.76.0/src/vs/base/common/objects.ts#L45-L83
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function cloneAndChange(obj: any, changer: (orig: any) => any, seen: Set<any>): any {
// impossible to clone an undefined or null object
// eslint-disable-next-line no-null/no-null
if (isUndefined(obj) || obj === null) {
return obj;
}

const changed = changer(obj);
if (!isUndefined(changed)) {
return changed;
}

if (Array.isArray(obj)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const r1: any[] = [];
for (const e of obj) {
r1.push(cloneAndChange(e, changer, seen));
}
return r1;
}

if (isObject(obj)) {
if (seen.has(obj)) {
throw new Error('Cannot clone recursive data-structure');
}
seen.add(obj);
const r2 = {};
for (const i2 in obj) {
if (_hasOwnProperty.call(obj, i2)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(r2 as any)[i2] = cloneAndChange(obj[i2], changer, seen);
}
}
seen.delete(obj);
return r2;
}

return obj;
}
45 changes: 45 additions & 0 deletions packages/core/src/common/telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// *****************************************************************************
// Copyright (C) 2023 STMicroelectronics and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// *****************************************************************************

export class TelemetryTrustedValue<T> {
readonly value: T;

constructor(value: T) {
this.value = value;
}
}

export interface TelemetryLogger {
readonly sender: TelemetrySender;
readonly options: TelemetryLoggerOptions | undefined;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
logUsage(eventName: string, data?: Record<string, any | TelemetryTrustedValue<any>>): void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
logError(eventNameOrException: string | Error, data?: Record<string, any | TelemetryTrustedValue<any>>): void;

dispose(): void;
}

interface TelemetrySender {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendEventData(eventName: string, data?: Record<string, any>): void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendErrorData(error: Error, data?: Record<string, any>): void;
flush?(): void | Thenable<void>;
}

interface TelemetryLoggerOptions {
}
10 changes: 9 additions & 1 deletion packages/plugin-ext/src/common/plugin-api-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2079,6 +2079,12 @@ export interface TabsMain {
$closeGroup(groupIds: number[], preserveFocus?: boolean): Promise<boolean>;
}

export interface TelemetryMain {
}

export interface TelemetryExt {
}

// endregion

export const PLUGIN_RPC_CONTEXT = {
Expand Down Expand Up @@ -2116,6 +2122,7 @@ export const PLUGIN_RPC_CONTEXT = {
THEMING_MAIN: <ProxyIdentifier<ThemingMain>>createProxyIdentifier<ThemingMain>('ThemingMain'),
COMMENTS_MAIN: <ProxyIdentifier<CommentsMain>>createProxyIdentifier<CommentsMain>('CommentsMain'),
TABS_MAIN: <ProxyIdentifier<TabsMain>>createProxyIdentifier<TabsMain>('TabsMain'),
TELEMETRY_MAIN: <ProxyIdentifier<TelemetryMain>>createProxyIdentifier<TelemetryMain>('TelemetryMain'),
LOCALIZATION_MAIN: <ProxyIdentifier<LocalizationMain>>createProxyIdentifier<LocalizationMain>('LocalizationMain'),
};

Expand Down Expand Up @@ -2151,7 +2158,8 @@ export const MAIN_RPC_CONTEXT = {
TIMELINE_EXT: createProxyIdentifier<TimelineExt>('TimeLineExt'),
THEMING_EXT: createProxyIdentifier<ThemingExt>('ThemingExt'),
COMMENTS_EXT: createProxyIdentifier<CommentsExt>('CommentsExt'),
TABS_EXT: createProxyIdentifier<TabsExt>('TabsExt')
TABS_EXT: createProxyIdentifier<TabsExt>('TabsExt'),
TELEMETRY_EXT: createProxyIdentifier<TelemetryExt>('TelemetryExt)')
};

export interface TasksExt {
Expand Down
13 changes: 0 additions & 13 deletions packages/plugin-ext/src/plugin/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// *****************************************************************************

import { Emitter, Event } from '@theia/core/lib/common/event';
import * as theia from '@theia/plugin';
import { RPCProtocol } from '../common/rpc-protocol';
import { EnvMain, PLUGIN_RPC_CONTEXT } from '../common/plugin-api-rpc';
Expand All @@ -31,16 +30,12 @@ export abstract class EnvExtImpl {
private envMachineId: string;
private envSessionId: string;
private host: string;
private _isTelemetryEnabled: boolean;
private _remoteName: string | undefined;
private onDidChangeTelemetryEnabledEmitter = new Emitter<boolean>();

constructor(rpc: RPCProtocol) {
this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.ENV_MAIN);
this.envSessionId = v4();
this.envMachineId = v4();
// we don't support telemetry at the moment
this._isTelemetryEnabled = false;
this._remoteName = undefined;
}

Expand Down Expand Up @@ -101,14 +96,6 @@ export abstract class EnvExtImpl {
return this.host;
}

get isTelemetryEnabled(): boolean {
return this._isTelemetryEnabled;
}

get onDidChangeTelemetryEnabled(): Event<boolean> {
return this.onDidChangeTelemetryEnabledEmitter.event;
}

get remoteName(): string | undefined {
return this._remoteName;
}
Expand Down
11 changes: 9 additions & 2 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ import {
InlayHint,
InlayHintKind,
InlayHintLabelPart,
TelemetryTrustedValue,
NotebookCell,
NotebookCellKind,
NotebookCellStatusBarAlignment,
Expand Down Expand Up @@ -236,6 +237,7 @@ import { Endpoint } from '@theia/core/lib/browser/endpoint';
import { FilePermission } from '@theia/filesystem/lib/common/files';
import { TabsExtImpl } from './tabs';
import { LocalizationExtImpl } from './localization-ext';
import { TelemetryExtImpl } from './telemetry-ext';

export function createAPIFactory(
rpc: RPCProtocol,
Expand Down Expand Up @@ -277,6 +279,7 @@ export function createAPIFactory(
const tabsExt = rpc.set(MAIN_RPC_CONTEXT.TABS_EXT, new TabsExtImpl(rpc));
const customEditorExt = rpc.set(MAIN_RPC_CONTEXT.CUSTOM_EDITORS_EXT, new CustomEditorsExtImpl(rpc, documents, webviewExt, workspaceExt));
const webviewViewsExt = rpc.set(MAIN_RPC_CONTEXT.WEBVIEW_VIEWS_EXT, new WebviewViewsExtImpl(rpc, webviewExt));
const telemetryExt = rpc.set(MAIN_RPC_CONTEXT.TELEMETRY_EXT, new TelemetryExtImpl());
rpc.set(MAIN_RPC_CONTEXT.DEBUG_EXT, debugExt);

return function (plugin: InternalPlugin): typeof theia {
Expand Down Expand Up @@ -724,9 +727,12 @@ export function createAPIFactory(
get appHost(): string { return envExt.appHost; },
get language(): string { return envExt.language; },
get isNewAppInstall(): boolean { return envExt.isNewAppInstall; },
get isTelemetryEnabled(): boolean { return envExt.isTelemetryEnabled; },
get isTelemetryEnabled(): boolean { return telemetryExt.isTelemetryEnabled; },
get onDidChangeTelemetryEnabled(): theia.Event<boolean> {
return envExt.onDidChangeTelemetryEnabled;
return telemetryExt.onDidChangeTelemetryEnabled;
},
createTelemetryLogger(sender: theia.TelemetrySender, options?: theia.TelemetryLoggerOptions): theia.TelemetryLogger {
return telemetryExt.createTelemetryLogger(sender, options);
},
get remoteName(): string | undefined { return envExt.remoteName; },
get machineId(): string { return envExt.machineId; },
Expand Down Expand Up @@ -1307,6 +1313,7 @@ export function createAPIFactory(
InlayHint,
InlayHintKind,
InlayHintLabelPart,
TelemetryTrustedValue,
NotebookCellData,
NotebookCellKind,
NotebookCellOutput,
Expand Down
Loading

0 comments on commit 934931f

Please sign in to comment.