forked from golang/vscode-go
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
src/goTelemetry: ask gopls to prompt for telemetry opt-in
We want to avoid overwhelming users with the telemetry opt-in prompt when gopls starts. Instead of relying on the setting, the extension monitors the user's activities - open/close files, typing. And tell gopls when it thinks is a good time to show prompt, by calling the gopls's maybe_prompt_for_telemetry command. And for this initial rollout, we aim to reach out to 0.1% of users who didn't disable the vscode's general telemetry. Since go telemetry is pretty different wrt privacy preserving, we will eventually remove the vscode's general telemetry preference checking. We also ask all preview extension users - we think there are not many those users. Change-Id: Iced5bdcf61d7fd4276fd3b5cc61d6dc9686cf6d4 Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/533315 Reviewed-by: Robert Findley <[email protected]> Reviewed-by: Suzy Mueller <[email protected]> TryBot-Result: kokoro <[email protected]> Commit-Queue: Hyang-Ah Hana Kim <[email protected]>
- Loading branch information
Showing
6 changed files
with
318 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/*--------------------------------------------------------- | ||
* Copyright 2023 The Go Authors. All rights reserved. | ||
* Licensed under the MIT License. See LICENSE in the project root for license information. | ||
*--------------------------------------------------------*/ | ||
|
||
import * as vscode from 'vscode'; | ||
|
||
import { createHash } from 'crypto'; | ||
import { ExecuteCommandRequest } from 'vscode-languageserver-protocol'; | ||
import { daysBetween } from './goSurvey'; | ||
import { LanguageClient } from 'vscode-languageclient/node'; | ||
|
||
// Name of the prompt telemetry command. This is also used to determine if the gopls instance supports telemetry. | ||
// Exported for testing. | ||
export const GOPLS_MAYBE_PROMPT_FOR_TELEMETRY = 'gopls.maybe_prompt_for_telemetry'; | ||
|
||
// Key for the global state that holds the very first time the telemetry-enabled gopls was observed. | ||
// Exported for testing. | ||
export const TELEMETRY_START_TIME_KEY = 'telemetryStartTime'; | ||
|
||
// Go extension delegates most of the telemetry logic to gopls. | ||
// TelemetryService provides API to interact with gopls's telemetry. | ||
export class TelemetryService { | ||
private active = false; | ||
constructor( | ||
private languageClient: Pick<LanguageClient, 'sendRequest'> | undefined, | ||
private globalState: vscode.Memento, | ||
commands: string[] = [] | ||
) { | ||
if (!languageClient || !commands.includes(GOPLS_MAYBE_PROMPT_FOR_TELEMETRY)) { | ||
// we are not backed by the gopls version that supports telemetry. | ||
return; | ||
} | ||
|
||
this.active = true; | ||
// record the first time we see the gopls with telemetry support. | ||
// The timestamp will be used to avoid prompting too early. | ||
const telemetryStartTime = globalState.get<Date>(TELEMETRY_START_TIME_KEY); | ||
if (!telemetryStartTime) { | ||
globalState.update(TELEMETRY_START_TIME_KEY, new Date()); | ||
} | ||
} | ||
|
||
async promptForTelemetry( | ||
isPreviewExtension: boolean, | ||
isVSCodeTelemetryEnabled: boolean = vscode.env.isTelemetryEnabled, | ||
samplingInterval = 1 /* prompt N out of 1000. 1 = 0.1% */ | ||
) { | ||
if (!this.active) return; | ||
|
||
// Do not prompt yet if the user disabled vscode's telemetry. | ||
// TODO(hyangah): remove this condition after we roll out to 100%. It's possible | ||
// users who don't want vscode's telemetry are still willing to opt in. | ||
if (!isVSCodeTelemetryEnabled) return; | ||
|
||
// Allow at least 7days for gopls to collect some data. | ||
const now = new Date(); | ||
const telemetryStartTime = this.globalState.get<Date>(TELEMETRY_START_TIME_KEY, now); | ||
if (daysBetween(telemetryStartTime, now) < 7) { | ||
return; | ||
} | ||
|
||
// For official extension users, prompt only N out of 1000. | ||
if (!isPreviewExtension && this.hashMachineID() % 1000 >= samplingInterval) { | ||
return; | ||
} | ||
|
||
try { | ||
await this.languageClient?.sendRequest(ExecuteCommandRequest.type, { | ||
command: GOPLS_MAYBE_PROMPT_FOR_TELEMETRY | ||
}); | ||
} catch (e) { | ||
console.log(`failed to send telemetry request: ${e}`); | ||
} | ||
} | ||
|
||
// exported for testing. | ||
public hashMachineID(salt?: string): number { | ||
const hash = createHash('md5').update(`${vscode.env.machineId}${salt}`).digest('hex'); | ||
return parseInt(hash.substring(0, 8), 16); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.