Skip to content
This repository has been archived by the owner on Mar 11, 2024. It is now read-only.

Commit

Permalink
Fix Telemetry setup (#296)
Browse files Browse the repository at this point in the history
* fix: use new telemetry package

* fix: update to latest non-preview version

* refactor: rename Telemetry module into `Telemetry`

* refactor: split functions/tests according to usage

* feat: add custom `enableTelemetry` setting

* refactor: fix `import` lints

* docs: adds *Requires reload* to description

* docs: clarify `truffle`s analytics link

* docs: improve wording in description

* refactor: make `obfuscate` top level function
  • Loading branch information
acuarica authored Jan 16, 2023
1 parent 279506e commit 5fd3e54
Show file tree
Hide file tree
Showing 46 changed files with 343 additions and 312 deletions.
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@
"enum": [
"Truffle"
]
},
"truffle-vscode.enableTelemetry": {
"type": "boolean",
"default": true,
"markdownDescription": "Indicates whether to collect anonymous product usage data. Regardless of this setting, the extension honors the [`telemetry.telemetryLevel`](https://code.visualstudio.com/docs/getstarted/telemetry#_disable-telemetry-reporting) user setting, _i.e._, if `telemetry.telemetryLevel` is `off` the extension does not send any data regardless of this setting. See <https://trufflesuite.com/analytics/> for the analytics policy used in `truffle`. *Requires reload to take effect.*"
}
}
},
Expand Down Expand Up @@ -835,6 +840,7 @@
"@truffle/fetch-and-compile": "^0.5.19",
"@truffle/resolver": "^9.0.4",
"@truffle/workflow-compile": "^4.0.36",
"@vscode/extension-telemetry": "^0.6.2",
"abi-decoder": "^2.4.0",
"acorn": "^8.7.1",
"acorn-walk": "^8.2.0",
Expand All @@ -852,7 +858,6 @@
"semver": "^6.0.0",
"solidity-parser-antlr": "^0.4.11",
"uuid": "^3.3.2",
"vscode-extension-telemetry": "^0.4.5",
"web3": "1.7.4"
},
"extensionDependencies": [
Expand Down
4 changes: 2 additions & 2 deletions src/Models/ItemCreators/ItemCreator.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.

import {Telemetry} from '../../TelemetryClient';
import {IExtensionItem} from '../TreeItems/IExtensionItem';
import {Telemetry} from '@/Telemetry';
import type {IExtensionItem} from '../TreeItems/IExtensionItem';

export abstract class ItemCreator {
public create(obj: {[key: string]: any}): IExtensionItem {
Expand Down
2 changes: 1 addition & 1 deletion src/Models/ItemFactory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.

import {Telemetry} from '../TelemetryClient';
import {Telemetry} from '@/Telemetry';
import type {ItemCreator} from './ItemCreators/ItemCreator';
import {CommandItemCreator} from './ItemCreators/CommandItemCreator';
import {GenericNetworkNodeItemCreator} from './ItemCreators/GenericNetworkNodeItemCreator';
Expand Down
14 changes: 6 additions & 8 deletions src/Models/TreeItems/ExtensionItem.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.

import {commands, TreeItem, TreeItemCollapsibleState, Uri} from 'vscode';
import {Constants} from '../../Constants';
import {Telemetry} from '../../TelemetryClient';
import {ItemType} from '../ItemType';
import {IExtensionItem} from './IExtensionItem';
import {commands, TreeItem, TreeItemCollapsibleState, type Uri} from 'vscode';
import {Constants} from '@/Constants';
import {obfuscate, Telemetry} from '@/Telemetry';
import type {ItemType} from '../ItemType';
import type {IExtensionItem} from './IExtensionItem';
import Timeout = NodeJS.Timeout;

export interface ExtensionItemData {
Expand Down Expand Up @@ -51,9 +51,7 @@ export abstract class ExtensionItem extends TreeItem implements IExtensionItem {
if (this.children.some((_child) => _child.label === child.label)) {
Telemetry.sendException(
new Error(
Constants.errorMessageStrings.GetMessageChildAlreadyConnected(
Telemetry.obfuscate(child.label?.toString() || '')
)
Constants.errorMessageStrings.GetMessageChildAlreadyConnected(obfuscate(child.label?.toString() || ''))
)
);
throw new Error(Constants.errorMessageStrings.GetMessageChildAlreadyConnected(child.label?.toString() || ''));
Expand Down
4 changes: 2 additions & 2 deletions src/Models/TreeItems/MnemonicNetworkNode.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.

import {INetwork} from '@/helpers/ConfigurationReader';
import type {INetwork} from '@/helpers/ConfigurationReader';
import {generateMnemonic, getTruffleConfigUri, TruffleConfig} from '@/helpers/TruffleConfiguration';
import {window} from 'vscode';
import {Constants, RequiredApps} from '@/Constants';
import {showInputBox, showQuickPick, saveTextInFile} from '@/helpers/userInteraction';
import {MnemonicRepository} from '@/services/MnemonicRepository'; // Should be full path since cycle dependencies
import {Telemetry} from '@/TelemetryClient';
import {Telemetry} from '@/Telemetry';
import {NetworkNode} from './NetworkNode';

export abstract class MnemonicNetworkNode extends NetworkNode {
Expand Down
77 changes: 77 additions & 0 deletions src/Telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.

import crypto from 'crypto';
import os from 'os';
import TelemetryReporter, {
type TelemetryEventMeasurements,
type TelemetryEventProperties,
} from '@vscode/extension-telemetry';
import {Constants} from './Constants';
import {Output, OutputLabel} from './Output';
import {workspace} from 'vscode';

export const Telemetry = new (class {
private readonly reporter?: TelemetryReporter;

private readonly defaultProperties: {[key: string]: any} = {};

constructor() {
const enableTelemetry = workspace.getConfiguration('truffle-vscode').get('enableTelemetry');

if (enableTelemetry) {
const extensionKey = process.env.AIKEY || Constants.extensionKey;
try {
this.reporter = new TelemetryReporter(Constants.extensionName, Constants.extensionVersion, extensionKey);
// set default values for machine/session ids
this.defaultProperties['common.vscodemachineid'] = generateMachineId();
this.defaultProperties['common.vscodesessionid'] = generateSessionId();
} catch (err) {
Output.outputLine(OutputLabel.telemetryClient, `Initialize done with error: ${(err as Error).message}`);
}
}
}

public sendEvent(
eventName: string,
properties?: TelemetryEventProperties,
measurements?: TelemetryEventMeasurements
): void {
const props = {...this.defaultProperties, ...properties};
if (this.reporter) {
this.reporter.sendTelemetryEvent(eventName, props, measurements);
}
}

public sendException(
exception: Error,
properties?: {[key: string]: string},
measurements?: {[key: string]: number}
): void {
const props = {...this.defaultProperties, ...properties};
const error = new Error(exception.message);
error.stack = '';

if (this.reporter) {
this.reporter.sendTelemetryException(error, props, measurements);
}
}

public async dispose(): Promise<void> {
if (this.reporter) {
await this.reporter.dispose();
}
}
})();

export function obfuscate(data: string): string {
return crypto.createHash('sha256').update(data).digest('base64');
}

function generateMachineId(): string {
return crypto.createHash('sha256').update(os.hostname()).digest('base64');
}

function generateSessionId(): string {
return crypto.randomBytes(16).toString('hex');
}
95 changes: 0 additions & 95 deletions src/TelemetryClient.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/commands/DashboardCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {Constants} from '@/Constants';
import {required} from '@/helpers/required';
import {showIgnorableNotification} from '@/helpers/userInteraction';
import {DashboardService} from '@/services/dashboard/DashboardService';
import {Telemetry} from '@/TelemetryClient';
import {Telemetry} from '@/Telemetry';
export namespace DashboardCommands {
// Command to bind to UI commands
export async function startDashboardCmd(): Promise<void> {
Expand Down
8 changes: 4 additions & 4 deletions src/commands/DebuggerCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
// Licensed under the MIT license.

import path from 'path';
import {debug, DebugConfiguration, QuickPickItem, Uri, QuickPickItemKind, workspace} from 'vscode';
import {debug, type DebugConfiguration, type QuickPickItem, Uri, QuickPickItemKind, workspace} from 'vscode';

import {DEBUG_TYPE} from '@/debugAdapter/constants/debugAdapter';
import {DebugNetwork} from '@/debugAdapter/debugNetwork';
import {TransactionProvider} from '@/debugAdapter/transaction/transactionProvider';
import {Web3Wrapper} from '@/debugAdapter/web3Wrapper';
import {getTruffleWorkspace, getPathByPlatform} from '@/helpers/workspace';
import {showInputBox, showQuickPick} from '@/helpers/userInteraction';
import {Telemetry} from '@/TelemetryClient';
import {DebuggerTypes} from '@/debugAdapter/models/debuggerTypes';
import {Telemetry} from '@/Telemetry';
import type {DebuggerTypes} from '@/debugAdapter/models/debuggerTypes';

const TX_REGEX = /^(?:0x)?[0-9a-fA-F]{64}$/;

export namespace DebuggerCommands {
export async function startSolidityDebugger() {
export async function startSolidityDebugger(): Promise<void> {
Telemetry.sendEvent('DebuggerCommands.startSolidityDebugger.commandStarted');

const workspaceUri = (await getTruffleWorkspace()).workspace;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/GanacheCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {ItemType} from '@/Models/ItemType';
import {LocalProject, type TLocalProjectOptions} from '@/Models/TreeItems/LocalProject';
import {GanacheService} from '@/services/ganache/GanacheService';
import {TreeManager} from '@/services/tree/TreeManager';
import {Telemetry} from '../TelemetryClient';
import {Telemetry} from '@/Telemetry';
import type {ProjectView} from '@/views/NetworksView';

export namespace GanacheCommands {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/GenericCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {required} from '../helpers/required';
import type {GenericProject} from '../Models/TreeItems/GenericProject';
import {GenericService} from '@/services/generic/GenericService';
import {TreeManager} from '@/services/tree/TreeManager';
import {Telemetry} from '../TelemetryClient';
import {Telemetry} from '@/Telemetry';
import type {ProjectView} from '@/views/NetworksView';

export namespace GenericCommands {
Expand Down
8 changes: 4 additions & 4 deletions src/commands/ProjectCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import {required} from '@/helpers/required';
import {checkTruffleConfigNaming} from '@/helpers/TruffleConfiguration';
import {showIgnorableNotification, showOpenFolderDialog, showQuickPick} from '@/helpers/userInteraction';
import {CancellationEvent} from '@/Models/CancellationEvent';
import {Telemetry} from '@/TelemetryClient';
import {Telemetry} from '@/Telemetry';
import fs from 'fs-extra';
import requestPromise from 'request-promise';
import {QuickPickItem, Uri, window, workspace} from 'vscode';
import {type QuickPickItem, Uri, window, workspace} from 'vscode';
import * as outputCommandHelper from '@/helpers/command';

/**
Expand Down Expand Up @@ -74,10 +74,10 @@ export namespace ProjectCommands {
];

// Displays the QuickPick with the possibilities to choose between project types
const command = (await showQuickPick(typeOfSolidityProjectDestination, {
const command = await showQuickPick(typeOfSolidityProjectDestination, {
placeHolder: Constants.placeholders.selectTypeOfSolidityProject,
ignoreFocusOut: true,
})) as IProjectDestination;
});

// Creates the project
await command.cmd(command.projectType);
Expand Down
20 changes: 15 additions & 5 deletions src/commands/ServiceCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT license.

import {Constants} from '@/Constants';
import {mapItemType} from '@/helpers/telemetry';
import {showInputBox, showQuickPick} from '@/helpers/userInteraction';
import {ItemType} from '@/Models/ItemType';
import {LocalProject, type TLocalProjectOptions} from '@/Models/TreeItems/LocalProject';
Expand All @@ -18,7 +17,7 @@ import {InfuraResourceExplorer} from '@/resourceExplorers/InfuraResourceExplorer
import {LocalResourceExplorer} from '@/resourceExplorers/LocalResourceExplorer';
import {GanacheService} from '@/services/ganache/GanacheService';
import {TreeManager} from '@/services/tree/TreeManager';
import {Telemetry} from '@/TelemetryClient';
import {obfuscate, Telemetry} from '@/Telemetry';
import type {ProjectView} from '@/views/NetworksView';
import type {QuickPickItem} from 'vscode';

Expand Down Expand Up @@ -296,8 +295,19 @@ async function addChild(service: Service, child: Project): Promise<void> {
service.addChild(child);

Telemetry.sendEvent('ServiceCommands.execute.newServiceItem', {
ruri: Telemetry.obfuscate((child.resourceUri || '').toString()),
type: Telemetry.obfuscate(child.itemType.toString()),
url: Telemetry.obfuscate(JSON.stringify(await child.getRPCAddress())),
ruri: obfuscate((child.resourceUri || '').toString()),
type: obfuscate(child.itemType.toString()),
url: obfuscate(JSON.stringify(await child.getRPCAddress())),
});
}

export function mapItemType(itemType: ItemType): string {
switch (itemType) {
case ItemType.LOCAL_PROJECT:
return Constants.treeItemData.service.local.prefix;
case ItemType.INFURA_PROJECT:
return Constants.treeItemData.service.infura.prefix;
default:
return 'other';
}
}
Loading

0 comments on commit 5fd3e54

Please sign in to comment.