Skip to content

Commit 52beaed

Browse files
committed
Remove extension telemetry setting and use VS Code setting instead
1 parent b1a15d8 commit 52beaed

File tree

8 files changed

+22
-566
lines changed

8 files changed

+22
-566
lines changed

extensions/ql-vscode/package.json

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -497,16 +497,6 @@
497497
"title": "Telemetry",
498498
"order": 11,
499499
"properties": {
500-
"codeQL.telemetry.enableTelemetry": {
501-
"type": "boolean",
502-
"default": false,
503-
"scope": "application",
504-
"markdownDescription": "Specifies whether to send CodeQL usage telemetry. This setting AND the one of the global telemetry settings (`#telemetry.enableTelemetry#` or `#telemetry.telemetryLevel#`) must be enabled for telemetry to be sent to GitHub. For more information, see the [telemetry documentation](https://codeql.github.com/docs/codeql-for-visual-studio-code/about-telemetry-in-codeql-for-visual-studio-code)",
505-
"tags": [
506-
"telemetry",
507-
"usesOnlineServices"
508-
]
509-
},
510500
"codeQL.telemetry.logTelemetry": {
511501
"type": "boolean",
512502
"default": false,

extensions/ql-vscode/src/common/vscode/dialog.ts

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { env, Uri, window } from "vscode";
1+
import { window } from "vscode";
22

33
/**
44
* Opens a modal dialog for the user to make a yes/no choice.
@@ -34,50 +34,6 @@ export async function showBinaryChoiceDialog(
3434
return chosenItem?.title === yesItem.title;
3535
}
3636

37-
/**
38-
* Opens a modal dialog for the user to make a yes/no choice.
39-
*
40-
* @param message The message to show.
41-
* @param modal If true (the default), show a modal dialog box, otherwise dialog is non-modal and can
42-
* be closed even if the user does not make a choice.
43-
*
44-
* @return
45-
* `true` if the user clicks 'Yes',
46-
* `false` if the user clicks 'No' or cancels the dialog,
47-
* `undefined` if the dialog is closed without the user making a choice.
48-
*/
49-
export async function showBinaryChoiceWithUrlDialog(
50-
message: string,
51-
url: string,
52-
): Promise<boolean | undefined> {
53-
const urlItem = { title: "More Information", isCloseAffordance: false };
54-
const yesItem = { title: "Yes", isCloseAffordance: false };
55-
const noItem = { title: "No", isCloseAffordance: true };
56-
let chosenItem;
57-
58-
// Keep the dialog open as long as the user is clicking the 'more information' option.
59-
// To prevent an infinite loop, if the user clicks 'more information' 5 times, close the dialog and return cancelled
60-
let count = 0;
61-
do {
62-
chosenItem = await window.showInformationMessage(
63-
message,
64-
{ modal: true },
65-
urlItem,
66-
yesItem,
67-
noItem,
68-
);
69-
if (chosenItem === urlItem) {
70-
await env.openExternal(Uri.parse(url, true));
71-
}
72-
count++;
73-
} while (chosenItem === urlItem && count < 5);
74-
75-
if (!chosenItem || chosenItem.title === urlItem.title) {
76-
return undefined;
77-
}
78-
return chosenItem.title === yesItem.title;
79-
}
80-
8137
/**
8238
* Show an information message with a customisable action.
8339
* @param message The message to show.
Lines changed: 16 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,14 @@
1-
import type {
2-
Extension,
3-
ExtensionContext,
4-
ConfigurationChangeEvent,
5-
} from "vscode";
6-
import { ConfigurationTarget, env } from "vscode";
1+
import type { Extension, ExtensionContext } from "vscode";
72
import TelemetryReporter from "vscode-extension-telemetry";
8-
import {
9-
ConfigListener,
10-
CANARY_FEATURES,
11-
ENABLE_TELEMETRY,
12-
LOG_TELEMETRY,
13-
isIntegrationTestMode,
14-
isCanary,
15-
} from "../../config";
3+
import { LOG_TELEMETRY, isCanary } from "../../config";
164
import type { TelemetryClient } from "applicationinsights";
175
import { extLogger } from "../logging/vscode";
186
import { UserCancellationException } from "./progress";
19-
import { showBinaryChoiceWithUrlDialog } from "./dialog";
207
import type { RedactableError } from "../errors";
218
import type { SemVer } from "semver";
229
import type { AppTelemetry } from "../telemetry";
2310
import type { EnvelopeTelemetry } from "applicationinsights/out/Declarations/Contracts";
11+
import type { Disposable } from "../disposable-object";
2412

2513
// Key is injected at build time through the APP_INSIGHTS_KEY environment variable.
2614
const key = "REPLACE-APP-INSIGHTS-KEY";
@@ -55,80 +43,25 @@ const baseDataPropertiesToRemove = [
5543

5644
const NOT_SET_CLI_VERSION = "not-set";
5745

58-
export class ExtensionTelemetryListener
59-
extends ConfigListener
60-
implements AppTelemetry
61-
{
62-
private reporter?: TelemetryReporter;
46+
export class ExtensionTelemetryListener implements AppTelemetry, Disposable {
47+
private readonly reporter: TelemetryReporter;
6348

6449
private cliVersionStr = NOT_SET_CLI_VERSION;
6550

66-
constructor(
67-
private readonly id: string,
68-
private readonly version: string,
69-
private readonly key: string,
70-
private readonly ctx: ExtensionContext,
71-
) {
72-
super();
73-
74-
env.onDidChangeTelemetryEnabled(async () => {
75-
await this.initialize();
76-
});
77-
}
78-
79-
/**
80-
* This function handles changes to relevant configuration elements. There are 2 configuration
81-
* ids that this function cares about:
82-
*
83-
* * `codeQL.telemetry.enableTelemetry`: If this one has changed, then we need to re-initialize
84-
* the reporter and the reporter may wind up being removed.
85-
* * `codeQL.canary`: A change here could possibly re-trigger a dialog popup.
86-
*
87-
* Note that the global telemetry setting also gate-keeps whether or not to send telemetry events
88-
* to Application Insights. However, this gatekeeping happens inside of the vscode-extension-telemetry
89-
* package. So, this does not need to be handled here.
90-
*
91-
* @param e the configuration change event
92-
*/
93-
async handleDidChangeConfiguration(
94-
e: ConfigurationChangeEvent,
95-
): Promise<void> {
96-
if (e.affectsConfiguration(ENABLE_TELEMETRY.qualifiedName)) {
97-
await this.initialize();
98-
}
99-
100-
// Re-request telemetry so that users can see the dialog again.
101-
// Re-request if codeQL.canary is being set to `true` and telemetry
102-
// is not currently enabled.
103-
if (
104-
e.affectsConfiguration(CANARY_FEATURES.qualifiedName) &&
105-
CANARY_FEATURES.getValue() &&
106-
!ENABLE_TELEMETRY.getValue()
107-
) {
108-
await this.setTelemetryRequested(false);
109-
await this.requestTelemetryPermission();
110-
}
111-
}
112-
113-
async initialize() {
114-
await this.requestTelemetryPermission();
115-
116-
this.disposeReporter();
117-
118-
if (ENABLE_TELEMETRY.getValue<boolean>()) {
119-
this.createReporter();
120-
}
121-
}
122-
123-
private createReporter() {
51+
constructor(id: string, version: string, key: string) {
52+
// We can always initialize this and send events using it because the vscode-extension-telemetry will check
53+
// whether the `telemetry.telemetryLevel` setting is enabled.
12454
this.reporter = new TelemetryReporter(
125-
this.id,
126-
this.version,
127-
this.key,
55+
id,
56+
version,
57+
key,
12858
/* anonymize stack traces */ true,
12959
);
130-
this.push(this.reporter);
13160

61+
this.addTelemetryProcessor();
62+
}
63+
64+
private addTelemetryProcessor() {
13265
// The appInsightsClient field is private but we want to access it anyway
13366
const client = this.reporter["appInsightsClient"] as TelemetryClient;
13467
if (client) {
@@ -151,14 +84,10 @@ export class ExtensionTelemetryListener
15184
}
15285

15386
dispose() {
154-
super.dispose();
155-
void this.reporter?.dispose();
87+
void this.reporter.dispose();
15688
}
15789

15890
sendCommandUsage(name: string, executionTime: number, error?: Error): void {
159-
if (!this.reporter) {
160-
return;
161-
}
16291
const status = !error
16392
? CommandCompletion.Success
16493
: error instanceof UserCancellationException
@@ -178,10 +107,6 @@ export class ExtensionTelemetryListener
178107
}
179108

180109
sendUIInteraction(name: string): void {
181-
if (!this.reporter) {
182-
return;
183-
}
184-
185110
this.reporter.sendTelemetryEvent(
186111
"ui-interaction",
187112
{
@@ -197,10 +122,6 @@ export class ExtensionTelemetryListener
197122
error: RedactableError,
198123
extraProperties?: { [key: string]: string },
199124
): void {
200-
if (!this.reporter) {
201-
return;
202-
}
203-
204125
const properties: { [key: string]: string } = {
205126
isCanary: isCanary().toString(),
206127
cliVersion: this.cliVersionStr,
@@ -215,10 +136,6 @@ export class ExtensionTelemetryListener
215136
}
216137

217138
sendConfigInformation(config: Record<string, string>): void {
218-
if (!this.reporter) {
219-
return;
220-
}
221-
222139
this.reporter.sendTelemetryEvent(
223140
"config",
224141
{
@@ -230,37 +147,6 @@ export class ExtensionTelemetryListener
230147
);
231148
}
232149

233-
/**
234-
* Displays a popup asking the user if they want to enable telemetry
235-
* for this extension.
236-
*/
237-
async requestTelemetryPermission() {
238-
if (!this.wasTelemetryRequested()) {
239-
// if global telemetry is disabled, avoid showing the dialog or making any changes
240-
let result = undefined;
241-
if (
242-
env.isTelemetryEnabled &&
243-
// Avoid showing the dialog if we are in integration test mode.
244-
!isIntegrationTestMode()
245-
) {
246-
// Extension won't start until this completes.
247-
result = await showBinaryChoiceWithUrlDialog(
248-
"Does the CodeQL Extension by GitHub have your permission to collect usage data and metrics to help us improve CodeQL for VSCode?",
249-
"https://codeql.github.com/docs/codeql-for-visual-studio-code/about-telemetry-in-codeql-for-visual-studio-code",
250-
);
251-
}
252-
if (result !== undefined) {
253-
await Promise.all([
254-
this.setTelemetryRequested(true),
255-
ENABLE_TELEMETRY.updateValue<boolean>(
256-
result,
257-
ConfigurationTarget.Global,
258-
),
259-
]);
260-
}
261-
}
262-
}
263-
264150
/**
265151
* Exposed for testing
266152
*/
@@ -271,21 +157,6 @@ export class ExtensionTelemetryListener
271157
set cliVersion(version: SemVer | undefined) {
272158
this.cliVersionStr = version ? version.toString() : NOT_SET_CLI_VERSION;
273159
}
274-
275-
private disposeReporter() {
276-
if (this.reporter) {
277-
void this.reporter.dispose();
278-
this.reporter = undefined;
279-
}
280-
}
281-
282-
private wasTelemetryRequested(): boolean {
283-
return !!this.ctx.globalState.get<boolean>("telemetry-request-viewed");
284-
}
285-
286-
private async setTelemetryRequested(newValue: boolean): Promise<void> {
287-
await this.ctx.globalState.update("telemetry-request-viewed", newValue);
288-
}
289160
}
290161

291162
/**
@@ -305,11 +176,7 @@ export async function initializeTelemetry(
305176
extension.id,
306177
extension.packageJSON.version,
307178
key,
308-
ctx,
309179
);
310-
// do not await initialization, since doing so will sometimes cause a modal popup.
311-
// this is a particular problem during integration tests, which will hang if a modal popup is displayed.
312-
void telemetryListener.initialize();
313180
ctx.subscriptions.push(telemetryListener);
314181
return telemetryListener;
315182
}

extensions/ql-vscode/src/config.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,6 @@ const ROOT_SETTING = new Setting("codeQL");
165165
const TELEMETRY_SETTING = new Setting("telemetry", ROOT_SETTING);
166166

167167
export const LOG_TELEMETRY = new Setting("logTelemetry", TELEMETRY_SETTING);
168-
export const ENABLE_TELEMETRY = new Setting(
169-
"enableTelemetry",
170-
TELEMETRY_SETTING,
171-
);
172168

173169
// Distribution configuration
174170
const DISTRIBUTION_SETTING = new Setting("cli", ROOT_SETTING);
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"workbench.startupEditor": "none",
33
"security.workspace.trust.enabled": false,
4-
"codeQL.cli.executablePath": "/opt/codeql/codeql",
5-
"codeQL.telemetry.enableTelemetry": false
4+
"codeQL.cli.executablePath": "/opt/codeql/codeql"
65
}

0 commit comments

Comments
 (0)