Skip to content

telemetry(amazonq): Added metrics on loading webviews #5471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.amazonq

import com.intellij.openapi.Disposable
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.util.Alarm
import software.aws.toolkits.telemetry.MetricResult
import software.aws.toolkits.telemetry.Telemetry

@Service(Service.Level.PROJECT)
class LoadModuleCompletion(project: Project?) : Disposable{

private val alarm = Alarm(Alarm.ThreadToUse.POOLED_THREAD, this)
private var initializeLoad = true

fun start(moduleName: String) {
alarm.addRequest(
{
if(!initializeLoad) {
emitMetric(moduleName)

}
initializeLoad = false


},
10000
)
}

private fun emitMetric(moduleName: String) {
Telemetry.toolkit.didLoadModule.use {
it.module(moduleName)
it.result(MetricResult.Failed)
}
initializeLoad = true
}

fun resetTimer() {
alarm.cancelAllRequests()

}

companion object {
fun getInstance(project: Project?) = project?.service<LoadModuleCompletion>()
}

override fun dispose() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import software.aws.toolkits.jetbrains.utils.isQConnected
import software.aws.toolkits.jetbrains.utils.isQExpired
import software.aws.toolkits.jetbrains.utils.isQWebviewsAvailable
import software.aws.toolkits.telemetry.FeatureId
import software.aws.toolkits.telemetry.MetricResult
import software.aws.toolkits.telemetry.Telemetry
import software.aws.toolkits.telemetry.UiTelemetry
import software.aws.toolkits.telemetry.WebviewTelemetry
import java.awt.event.ActionListener
Expand Down Expand Up @@ -150,6 +152,11 @@ class QWebviewBrowser(val project: Project, private val parentDisposable: Dispos
project,
reAuth = isQExpired(project)
)
Telemetry.toolkit.didLoadModule.use {
it.module("Login")
it.result(MetricResult.Succeeded)
}
LoadModuleCompletion.getInstance(project)?.resetTimer()
}

is BrowserMessage.SelectConnection -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.BearerTokenPr
import software.aws.toolkits.jetbrains.core.notifications.NotificationPanel
import software.aws.toolkits.jetbrains.core.notifications.ProcessNotificationsBase
import software.aws.toolkits.jetbrains.core.webview.BrowserState
import software.aws.toolkits.jetbrains.services.amazonq.LoadModuleCompletion
import software.aws.toolkits.jetbrains.services.amazonq.QWebviewPanel
import software.aws.toolkits.jetbrains.services.amazonq.RefreshQChatPanelButtonPressedListener
import software.aws.toolkits.jetbrains.services.amazonq.gettingstarted.openMeetQPage
Expand All @@ -33,6 +34,7 @@ import software.aws.toolkits.jetbrains.utils.isQExpired
import software.aws.toolkits.jetbrains.utils.isQWebviewsAvailable
import software.aws.toolkits.resources.message
import software.aws.toolkits.telemetry.FeatureId
import software.aws.toolkits.telemetry.Telemetry
import java.awt.event.ComponentAdapter
import java.awt.event.ComponentEvent

Expand Down Expand Up @@ -107,9 +109,12 @@ class AmazonQToolWindowFactory : ToolWindowFactory, DumbAware {
project: Project,
qPanel: Wrapper,
) {
Telemetry.toolkit.didLoadModule.startSpan()
val component = if (isQConnected(project) && !isQExpired(project)) {
LoadModuleCompletion.getInstance(project)?.start("Chat")
AmazonQToolWindow.getInstance(project).component
} else {
LoadModuleCompletion.getInstance(project)?.start("Login")
QWebviewPanel.getInstance(project).browser?.prepareBrowser(BrowserState(FeatureId.AmazonQ))
QWebviewPanel.getInstance(project).component
}
Expand Down Expand Up @@ -149,10 +154,12 @@ class AmazonQToolWindowFactory : ToolWindowFactory, DumbAware {
openMeetQPage(project)
}

LoadModuleCompletion.getInstance(project)?.start("Login")
QWebviewPanel.getInstance(project).browser?.prepareBrowser(BrowserState(FeatureId.AmazonQ))

// isQConnected alone is not robust and there is race condition (read/update connection states)
val component = if (isNewConnectionForQ || (isQConnected(project) && !isQExpired(project))) {
LoadModuleCompletion.getInstance(project)?.start("Chat")
LOG.debug { "returning Q-chat window; isQConnection=$isNewConnectionForQ; hasPinnedConnection=$isNewConnectionForQ" }
AmazonQToolWindow.getInstance(project).component
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.cef.browser.CefBrowser
import software.aws.toolkits.jetbrains.services.amazonq.LoadModuleCompletion
import software.aws.toolkits.jetbrains.services.amazonq.apps.AppConnection
import software.aws.toolkits.jetbrains.services.amazonq.commands.MessageSerializer
import software.aws.toolkits.jetbrains.services.amazonq.util.command
import software.aws.toolkits.jetbrains.services.amazonq.util.tabType
import software.aws.toolkits.jetbrains.services.amazonq.webview.theme.AmazonQTheme
import software.aws.toolkits.jetbrains.services.amazonq.webview.theme.ThemeBrowserAdapter
import software.aws.toolkits.jetbrains.settings.MeetQSettings
import software.aws.toolkits.telemetry.MetricResult
import software.aws.toolkits.telemetry.Telemetry
import java.util.function.Function

Expand All @@ -47,6 +49,14 @@ class BrowserConnector(
RunOnceUtil.runOnceForApp("AmazonQ-UI-Ready") {
MeetQSettings.getInstance().reinvent2024OnboardingCount += 1
}

Telemetry.toolkit.didLoadModule.use {
// the Duration is usually 0 because it takes a few nanoseconds to load the module
// so when it's translated to millis it is returned as 0
it.module("Chat")
it.result(MetricResult.Succeeded)
}
LoadModuleCompletion.getInstance(null)?.resetTimer()
}

"disclaimer-acknowledged" -> {
Expand All @@ -70,6 +80,7 @@ class BrowserConnector(
Telemetry.toolkit.willOpenModule.use {
it.module(module.asText())
it.source(trigger.asText())
it.result(MetricResult.Succeeded)
}
}
}
Expand Down
Loading