From f3b048fbbe1e340c4185ad8d9ceeebb48a737b9a Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Wed, 21 Jun 2023 16:10:54 -0400 Subject: [PATCH 1/4] Fixes part of #2685 - end-to-end performance tracking for code completion requests Signed-off-by: Rob Stryker --- src/standardLanguageClient.ts | 23 ++++++++++++++++++++++- src/telemetry.ts | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/standardLanguageClient.ts b/src/standardLanguageClient.ts index ab70fdf51..6f612b76c 100644 --- a/src/standardLanguageClient.ts +++ b/src/standardLanguageClient.ts @@ -11,7 +11,7 @@ import { apiManager } from "./apiManager"; import * as buildPath from './buildpath'; import { javaRefactorKinds, RefactorDocumentProvider } from "./codeActionProvider"; import { Commands } from "./commands"; -import { ClientStatus } from "./extension.api"; +import { ClientStatus, TraceEvent } from "./extension.api"; import * as fileEventHandler from './fileEventHandler'; import { gradleCodeActionMetadata, GradleCodeActionProvider } from "./gradle/gradleCodeActionProvider"; import { awaitServerConnection, prepareExecutable, DEBUG } from "./javaServerStarter"; @@ -148,6 +148,7 @@ export class StandardLanguageClient { // Disable the client-side snippet provider since LS is ready. snippetCompletionProvider.dispose(); registerDocumentValidationListener(context, this.languageClient); + registerCodeCompletionTelemetryListener(context, this.languageClient); break; case 'Started': this.status = ClientStatus.started; @@ -735,3 +736,23 @@ export async function applyWorkspaceEdit(workspaceEdit: WorkspaceEdit, languageC return Promise.resolve(true); } } + +export function registerCodeCompletionTelemetryListener(context: ExtensionContext, languageClient: LanguageClient) { + const javaExt = extensions.getExtension("redhat.java"); + javaExt.exports?.onDidRequestEnd((traceEvent: any) => { + if (traceEvent.type === "textDocument/completion") { + // See https://github.com/redhat-developer/vscode-java/pull/3010 + // to exclude the invalid completion requests. + if (!traceEvent.resultLength && traceEvent.type === "textDocument/completion") { + return; + } + const event: TraceEvent = traceEvent as TraceEvent; + const props = { + ms: Math.round(event.duration * 100) / 100, + resultLength: event.resultLength || 0, + error: event.error === undefined? false : true, + }; + return Telemetry.sendTelemetry(Telemetry.COMPLETION_EVENT, props); + } + }); +} diff --git a/src/telemetry.ts b/src/telemetry.ts index d930123df..64a019075 100644 --- a/src/telemetry.ts +++ b/src/telemetry.ts @@ -7,6 +7,7 @@ import { ExtensionContext, workspace, WorkspaceConfiguration } from "vscode"; export namespace Telemetry { export const STARTUP_EVT = "startup"; + export const COMPLETION_EVENT = "textCompletion"; export const SERVER_INITIALIZED_EVT = "java.workspace.initialized"; let telemetryManager: TelemetryService = null; let serverInitializedReceived = false; From e01affcc1ba6f69de0a28d40f05169f6fb8a86ff Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Fri, 23 Jun 2023 11:44:42 -0400 Subject: [PATCH 2/4] Cleanup for issue 2685 Signed-off-by: Rob Stryker --- src/standardLanguageClient.ts | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/standardLanguageClient.ts b/src/standardLanguageClient.ts index 6f612b76c..b5fcff7c0 100644 --- a/src/standardLanguageClient.ts +++ b/src/standardLanguageClient.ts @@ -5,7 +5,7 @@ import { findRuntimes } from "jdk-utils"; import * as net from 'net'; import * as path from 'path'; import { CancellationToken, CodeActionKind, commands, ConfigurationTarget, DocumentSelector, EventEmitter, ExtensionContext, extensions, languages, Location, ProgressLocation, TextEditor, Uri, ViewColumn, window, workspace } from "vscode"; -import { ConfigurationParams, ConfigurationRequest, LanguageClientOptions, Location as LSLocation, MessageType, Position as LSPosition, TextDocumentPositionParams, WorkspaceEdit } from "vscode-languageclient"; +import { ConfigurationParams, ConfigurationRequest, LanguageClientOptions, Location as LSLocation, MessageType, Position as LSPosition, TextDocumentPositionParams, WorkspaceEdit, CompletionRequest } from "vscode-languageclient"; import { LanguageClient, StreamInfo } from "vscode-languageclient/node"; import { apiManager } from "./apiManager"; import * as buildPath from './buildpath'; @@ -148,7 +148,7 @@ export class StandardLanguageClient { // Disable the client-side snippet provider since LS is ready. snippetCompletionProvider.dispose(); registerDocumentValidationListener(context, this.languageClient); - registerCodeCompletionTelemetryListener(context, this.languageClient); + registerCodeCompletionTelemetryListener(); break; case 'Started': this.status = ClientStatus.started; @@ -737,22 +737,20 @@ export async function applyWorkspaceEdit(workspaceEdit: WorkspaceEdit, languageC } } -export function registerCodeCompletionTelemetryListener(context: ExtensionContext, languageClient: LanguageClient) { - const javaExt = extensions.getExtension("redhat.java"); - javaExt.exports?.onDidRequestEnd((traceEvent: any) => { - if (traceEvent.type === "textDocument/completion") { - // See https://github.com/redhat-developer/vscode-java/pull/3010 - // to exclude the invalid completion requests. - if (!traceEvent.resultLength && traceEvent.type === "textDocument/completion") { +export function registerCodeCompletionTelemetryListener() { + apiManager.getApiInstance().onDidRequestEnd((traceEvent: any) => { + if (traceEvent.type === CompletionRequest.method) { + // Exclude the invalid completion requests. + if (!traceEvent.resultLength) { return; } const event: TraceEvent = traceEvent as TraceEvent; const props = { - ms: Math.round(event.duration * 100) / 100, + duration: Math.round(event.duration * 100) / 100, resultLength: event.resultLength || 0, - error: event.error === undefined? false : true, + error: !!event.error, }; return Telemetry.sendTelemetry(Telemetry.COMPLETION_EVENT, props); } - }); -} + }); +} \ No newline at end of file From fd7b7b78b4f364312e3f8d1c5c729d6e2e2dd93c Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Thu, 27 Jul 2023 13:26:45 -0400 Subject: [PATCH 3/4] Update USAGE_DATA.md for code completion telemetry Signed-off-by: Rob Stryker --- USAGE_DATA.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/USAGE_DATA.md b/USAGE_DATA.md index e97a20529..ed5e1d221 100644 --- a/USAGE_DATA.md +++ b/USAGE_DATA.md @@ -18,7 +18,8 @@ vscode-java has opt-in telemetry collection, provided by [vscode-redhat-telemetr * `java.settings.url`, `java.format.settings.url`, `java.quickfix.showAt`, `java.symbols.includeSourceMethodDeclarations`, `java.completion.guessMethodArguments`, `java.completion.postfix.enabled`, `java.cleanup.actionsOnSave`, `java.sharedIndexes.enabled`, `java.inlayHints.parameterNames.enabled`, `java.server.launchMode`, `java.autobuild.enabled` * The extension name and the choice made when a recommendation to install a 3rd party extension is proposed * The name of Java commands being manually executed, and any resulting errors - + * The number of results (eg. 20), whether an error occured (eg. false), and duration (in milliseconds) when code assist is activated + ## What's included in the general telemetry data Please see the From d5a49b606dd58bc517dc6f44fa57e538a884f2d0 Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Thu, 27 Jul 2023 16:42:55 -0400 Subject: [PATCH 4/4] Cleanup - Unnecessary cast --- src/standardLanguageClient.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/standardLanguageClient.ts b/src/standardLanguageClient.ts index b5fcff7c0..092821187 100644 --- a/src/standardLanguageClient.ts +++ b/src/standardLanguageClient.ts @@ -738,17 +738,16 @@ export async function applyWorkspaceEdit(workspaceEdit: WorkspaceEdit, languageC } export function registerCodeCompletionTelemetryListener() { - apiManager.getApiInstance().onDidRequestEnd((traceEvent: any) => { + apiManager.getApiInstance().onDidRequestEnd((traceEvent: TraceEvent) => { if (traceEvent.type === CompletionRequest.method) { // Exclude the invalid completion requests. if (!traceEvent.resultLength) { return; } - const event: TraceEvent = traceEvent as TraceEvent; const props = { - duration: Math.round(event.duration * 100) / 100, - resultLength: event.resultLength || 0, - error: !!event.error, + duration: Math.round(traceEvent.duration * 100) / 100, + resultLength: traceEvent.resultLength || 0, + error: !!traceEvent.error, }; return Telemetry.sendTelemetry(Telemetry.COMPLETION_EVENT, props); }