From 965969c3fad1d58346761f6fb96272854355b110 Mon Sep 17 00:00:00 2001 From: nkomonen-amazon Date: Fri, 14 Mar 2025 13:25:32 -0400 Subject: [PATCH 1/2] telemetry(webview): Emit toolkit_X module telemetry on auth webview Problem: With our telemetry, we do not know when the frontend webview UI has actually loaded Solution: Emit certain metrics during the webview loading process to get a better idea of if the webview UI successfully completed its initial load. - toolkit_willOpenModule, indicates intent to render a webview - toolkit_didLoadModule, indicates the final result of loading the webview - On Success it it just a success result. We know a success when the frontend send a successful message to the backend. It knows this by ensuring there were no errors and that a certain HTML element can be found, then once the page finishes its initial load it will send a success message to the backend. - On Failure, what happens is a timer times out after 10 seconds. Signed-off-by: nkomonen-amazon --- .../webview/messages/messageDispatcher.ts | 25 ++-- packages/core/src/amazonq/webview/ui/main.ts | 2 +- .../webview/vue/amazonq/backend_amazonq.ts | 1 + .../core/src/login/webview/vue/backend.ts | 23 ++-- packages/core/src/login/webview/vue/login.vue | 15 ++- .../src/login/webview/vue/reauthenticate.vue | 19 ++- packages/core/src/login/webview/vue/root.vue | 72 ++++++++++- .../src/shared/telemetry/vscodeTelemetry.json | 10 -- packages/core/src/webviews/main.ts | 113 ++++++++++++++++++ 9 files changed, 243 insertions(+), 37 deletions(-) diff --git a/packages/core/src/amazonq/webview/messages/messageDispatcher.ts b/packages/core/src/amazonq/webview/messages/messageDispatcher.ts index dc3bc4c77c8..f17de54e416 100644 --- a/packages/core/src/amazonq/webview/messages/messageDispatcher.ts +++ b/packages/core/src/amazonq/webview/messages/messageDispatcher.ts @@ -16,6 +16,8 @@ import globals from '../../../shared/extensionGlobals' import { openUrl } from '../../../shared/utilities/vsCodeUtils' import { DefaultAmazonQAppInitContext } from '../../apps/initContext' +const qChatModuleName = 'amazonqChat' + export function dispatchWebViewMessagesToApps( webview: Webview, webViewToAppsMessagePublishers: Map> @@ -29,8 +31,8 @@ export function dispatchWebViewMessagesToApps( * This would be equivalent of the duration between "user clicked open q" and "ui has become available" * NOTE: Amazon Q UI is only loaded ONCE. The state is saved between each hide/show of the webview. */ - telemetry.webview_load.emit({ - webviewName: 'amazonq', + telemetry.toolkit_didLoadModule.emit({ + module: qChatModuleName, duration: performance.measure(amazonqMark.uiReady, amazonqMark.open).duration, result: 'Succeeded', }) @@ -86,12 +88,19 @@ export function dispatchWebViewMessagesToApps( } if (msg.type === 'error') { - const event = msg.event === 'webview_load' ? telemetry.webview_load : telemetry.webview_error - event.emit({ - webviewName: 'amazonqChat', - result: 'Failed', - reasonDesc: msg.errorMessage, - }) + if (msg.event === 'toolkit_didLoadModule') { + telemetry.toolkit_didLoadModule.emit({ + module: qChatModuleName, + result: 'Failed', + reasonDesc: msg.errorMessage, + }) + } else { + telemetry.webview_error.emit({ + webviewName: qChatModuleName, + result: 'Failed', + reasonDesc: msg.errorMessage, + }) + } return } diff --git a/packages/core/src/amazonq/webview/ui/main.ts b/packages/core/src/amazonq/webview/ui/main.ts index d7285d81ba5..5ae03840f8f 100644 --- a/packages/core/src/amazonq/webview/ui/main.ts +++ b/packages/core/src/amazonq/webview/ui/main.ts @@ -63,7 +63,7 @@ export const createMynahUI = ( const { error, message } = e ideApi.postMessage({ type: 'error', - event: connector.isUIReady ? 'webview_error' : 'webview_load', + event: connector.isUIReady ? 'webview_error' : 'toolkit_didLoadModule', errorMessage: error ? error.toString() : message, }) }) diff --git a/packages/core/src/login/webview/vue/amazonq/backend_amazonq.ts b/packages/core/src/login/webview/vue/amazonq/backend_amazonq.ts index 83c511ad9f6..7132e91afec 100644 --- a/packages/core/src/login/webview/vue/amazonq/backend_amazonq.ts +++ b/packages/core/src/login/webview/vue/amazonq/backend_amazonq.ts @@ -27,6 +27,7 @@ const className = 'AmazonQLoginWebview' export class AmazonQLoginWebview extends CommonAuthWebview { public override id: string = 'aws.amazonq.AmazonCommonAuth' public static sourcePath: string = 'vue/src/login/webview/vue/amazonq/index.js' + public override supportsLoadTelemetry: boolean = true override onActiveConnectionModified = new vscode.EventEmitter() diff --git a/packages/core/src/login/webview/vue/backend.ts b/packages/core/src/login/webview/vue/backend.ts index 9bc6c5ae339..43d86feedf9 100644 --- a/packages/core/src/login/webview/vue/backend.ts +++ b/packages/core/src/login/webview/vue/backend.ts @@ -62,18 +62,25 @@ export abstract class CommonAuthWebview extends VueWebview { } private didCall: { login: boolean; reauth: boolean } = { login: false, reauth: false } - public setUiReady(state: 'login' | 'reauth') { - // Prevent telemetry spam, since showing/hiding chat triggers this each time. - // So only emit once. + /** + * Called when the UI load process is completed, regardless of success or failure + * + * @param errorMessage IF an error is caught on the frontend, this is the message. It will result in a failure metric. + * Otherwise we assume success. + */ + public setUiReady(state: 'login' | 'reauth', errorMessage?: string) { + // Only emit once to prevent telemetry spam, since showing/hiding chat triggers this each time. + // TODO: Research how to not trigger this on every show/hide if (this.didCall[state]) { return } - telemetry.webview_load.emit({ - passive: true, - webviewName: state, - result: 'Succeeded', - }) + if (errorMessage) { + this.setLoadFailure(state, errorMessage) + } else { + this.setDidLoad(state) + } + this.didCall[state] = true } diff --git a/packages/core/src/login/webview/vue/login.vue b/packages/core/src/login/webview/vue/login.vue index d21bf911802..831a1dfcb22 100644 --- a/packages/core/src/login/webview/vue/login.vue +++ b/packages/core/src/login/webview/vue/login.vue @@ -145,6 +145,7 @@ >