Skip to content

Commit 9a96e56

Browse files
JuliaABurchNick Ardecky
andauthored
Fix: normalize code transformation by gumby metrics (#4131)
* Fix: normalize code transformation by gumby metrics * Ran newchange * Merge vscode telemetry * Fix: unit test * Fix: unit test * Chore - add project pre-validation errors * Revert "Ran newchange" This reverts commit 5f0dd7f. * Fix: remove unnecessary transform * Fix: comments * Fix: re-adding throw * Change CodeTransformConstants to enum * Refactor models and constants file to models folder * Refactor - refactor variables to ENUM as preferred coding style for this repository * Refactor generated types to enums * Refactor change uploadZipSize to codeTransformTotalByteSize and refactor with TODO statements for each byte count * Refactor change uploadZipSize to codeTransformTotalByteSize and refactor with TODO statements for each byte count * Fix: removing unneeded import * Chore - remove codeTransformConfigurationFilePath * Chore - remove local telemetry definitions * Chore - version bump for analytics * Chore - keep amazonQ invoke method for now * Chore: clean up unused telemetry * Fix: updated package-lock.json * Removing unneeded metric definition * Fix: Upgraded commons package introduces new jsonc type, which needs to be declared with its extension * chore: run prettier --------- Co-authored-by: Nick Ardecky <[email protected]>
1 parent 16ccd1b commit 9a96e56

File tree

17 files changed

+681
-475
lines changed

17 files changed

+681
-475
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4262,7 +4262,7 @@
42624262
},
42634263
"devDependencies": {
42644264
"@aws-sdk/types": "^3.13.1",
4265-
"@aws-toolkits/telemetry": "^1.0.167",
4265+
"@aws-toolkits/telemetry": "^1.0.169",
42664266
"@aws/fully-qualified-names": "^2.1.1",
42674267
"@cspotcode/source-map-support": "^0.8.1",
42684268
"@sinonjs/fake-timers": "^10.0.2",

src/amazonq/explorer/amazonQChildrenNodes.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@ import * as vscode from 'vscode'
77
import * as nls from 'vscode-nls'
88
import { Commands, placeholder } from '../../shared/vscode/commands2'
99
import { getIcon } from '../../shared/icons'
10-
import {
11-
focusAmazonQPanel,
12-
reconnect,
13-
showTransformByQ,
14-
transformTreeNode,
15-
} from '../../codewhisperer/commands/basicCommands'
10+
import { focusAmazonQPanel, reconnect, showTransformByQ } from '../../codewhisperer/commands/basicCommands'
1611
import { transformByQState } from '../../codewhisperer/models/model'
1712
import * as CodeWhispererConstants from '../../codewhisperer/models/constants'
1813
import { amazonQHelpUrl } from '../../shared/constants'
@@ -66,7 +61,7 @@ export const createTransformByQ = () => {
6661
if (transformByQState.isRunning()) {
6762
vscode.commands.executeCommand('setContext', 'gumby.isTransformAvailable', false)
6863
if (status === '') {
69-
// job is running but polling has not started yet, so display generic messsage
64+
// job is running but polling has not started yet, so display generic message
7065
status = CodeWhispererConstants.transformByQStateRunningMessage
7166
}
7267
} else if (transformByQState.isCancelled()) {
@@ -80,7 +75,7 @@ export const createTransformByQ = () => {
8075
} else if (transformByQState.isNotStarted()) {
8176
status = ''
8277
}
83-
return showTransformByQ.build(transformTreeNode).asTreeNode({
78+
return showTransformByQ.build(CodeWhispererConstants.transformTreeNode).asTreeNode({
8479
label: status !== '' ? `${prefix} Transform [Job status: ` + status + `]` : `Transform`,
8580
iconPath: transformByQState.getIconForButton(),
8681
tooltip: `${prefix} Transform`,

src/amazonqGumby/activation.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import { startTransformByQWithProgress, confirmStopTransformByQ } from '../codew
1212
import { transformByQState } from '../codewhisperer/models/model'
1313
import * as CodeWhispererConstants from '../codewhisperer/models/constants'
1414
import { ProposedTransformationExplorer } from '../codewhisperer/service/transformationResultsViewProvider'
15+
import { codeTransformTelemetryState } from './telemetry/codeTransformTelemetryState'
16+
import { telemetry } from '../shared/telemetry/telemetry'
17+
import { CancelActionPositions, logCodeTransformInitiatedMetric } from './telemetry/codeTransformTelemetry'
18+
import { CodeTransformConstants } from './models/constants'
1519

1620
export async function activate(context: ExtContext) {
1721
const transformationHubViewProvider = new TransformationHubViewProvider()
@@ -25,12 +29,13 @@ export async function activate(context: ExtContext) {
2529
vscode.window.registerWebviewViewProvider('aws.amazonq.transformationHub', transformationHubViewProvider),
2630

2731
Commands.register('aws.amazonq.startTransformationInHub', async () => {
32+
logCodeTransformInitiatedMetric(CodeTransformConstants.HubStartButton)
2833
await startTransformByQWithProgress()
2934
}),
3035

31-
Commands.register('aws.amazonq.stopTransformationInHub', async () => {
36+
Commands.register('aws.amazonq.stopTransformationInHub', async (cancelSrc: CancelActionPositions) => {
3237
if (transformByQState.isRunning()) {
33-
confirmStopTransformByQ(transformByQState.getJobId())
38+
confirmStopTransformByQ(transformByQState.getJobId(), cancelSrc)
3439
} else {
3540
vscode.window.showInformationMessage(CodeWhispererConstants.noOngoingJobMessage)
3641
}
@@ -48,4 +53,27 @@ export async function activate(context: ExtContext) {
4853
vscode.commands.executeCommand('markdown.showPreview', vscode.Uri.file(transformByQState.getPlanFilePath()))
4954
})
5055
)
56+
57+
// Register an activation event listener to determine when the IDE opens, closes or users
58+
// select to open a new workspace
59+
vscode.workspace.onDidChangeWorkspaceFolders(event => {
60+
// Register when the IDE is closed
61+
if (event.added.length === 0 && event.removed.length === 0) {
62+
// Only fire closed during running/active job status
63+
if (transformByQState.isRunning()) {
64+
telemetry.codeTransform_jobIsClosedDuringIdeRun.emit({
65+
codeTransformJobId: transformByQState.getJobId(),
66+
codeTransformSessionId: codeTransformTelemetryState.getSessionId(),
67+
codeTransformStatus: transformByQState.getStatus(),
68+
})
69+
}
70+
} else {
71+
// Register when the workspace is changed to a new project, or IDE is opened
72+
telemetry.codeTransform_jobIsResumedAfterIdeClose.emit({
73+
codeTransformJobId: transformByQState.getJobId(),
74+
codeTransformSessionId: codeTransformTelemetryState.getSessionId(),
75+
codeTransformStatus: transformByQState.getStatus(),
76+
})
77+
}
78+
})
5179
}

src/amazonqGumby/entrypoint.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { transformByQState } from '../codewhisperer/models/model'
99
import { AuthUtil } from '../codewhisperer/util/authUtil'
1010
import vscode from 'vscode'
1111
import { sleep } from '../shared/utilities/timeoutUtils'
12+
import { telemetry } from '../shared/telemetry/telemetry'
1213

1314
export async function processTransformByQ() {
1415
if (!AuthUtil.instance.isEnterpriseSsoInUse()) {
@@ -17,6 +18,7 @@ export async function processTransformByQ() {
1718
}
1819
if (transformByQState.isNotStarted()) {
1920
await sleep(1000) // sleep so that chat can respond first, then show input prompt
21+
telemetry.codeTransform_jobIsStartedFromChatPrompt.emit()
2022
startTransformByQWithProgress()
2123
} else {
2224
vscode.window.showInformationMessage(jobInProgressMessage, { modal: true })

src/amazonqGumby/models/constants.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
export enum CodeTransformConstants {
7+
HubStartButton = 'HubStartButton',
8+
}

src/amazonqGumby/models/model.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { ToolkitError } from '../../shared/errors'
7+
8+
export class TransformByQUploadArchiveFailed extends ToolkitError {
9+
constructor() {
10+
// do not chain the error due to security issues (may contain the uploadUrl)
11+
super('Failed to zip code and upload it to S3')
12+
}
13+
}
14+
15+
export class TransformByQJavaProjectNotFound extends ToolkitError {
16+
constructor() {
17+
super('No Java projects found', { code: 'NoJavaProjectsAvailable' })
18+
}
19+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* This class contains helper methods dedicated to logging metrics specific to
6+
* CodeTransform
7+
*/
8+
9+
import { telemetry } from '../../shared/telemetry/telemetry'
10+
import { JDKVersion } from '../../codewhisperer/models/model'
11+
import * as CodeWhispererConstants from '../../codewhisperer/models/constants'
12+
import { codeTransformTelemetryState } from './codeTransformTelemetryState'
13+
14+
export enum CancelActionPositions {
15+
ApiError = 'apiError',
16+
LoadingPanel = 'loadingPanelStopButton',
17+
DevToolsSidePanel = 'devToolsStopButton',
18+
BottomHubPanel = 'bottomPanelSideNavButton',
19+
}
20+
21+
export enum StartActionPositions {
22+
DevToolsSidePanel = 'devToolsStartButton',
23+
BottomHubPanel = 'bottomPanelSideNavButton',
24+
}
25+
26+
export const logCodeTransformInitiatedMetric = (source: string): void => {
27+
const commonMetrics = {
28+
codeTransformSessionId: codeTransformTelemetryState.getSessionId(),
29+
}
30+
31+
if (source === CodeWhispererConstants.transformTreeNode) {
32+
telemetry.codeTransform_isDoubleClickedToTriggerUserModal.emit({
33+
codeTransformStartSrcComponents: StartActionPositions.DevToolsSidePanel,
34+
...commonMetrics,
35+
})
36+
} else if (source === StartActionPositions.BottomHubPanel) {
37+
telemetry.codeTransform_isDoubleClickedToTriggerUserModal.emit({
38+
codeTransformStartSrcComponents: StartActionPositions.BottomHubPanel,
39+
...commonMetrics,
40+
})
41+
}
42+
}
43+
44+
//TODO: it would be better to expand JDKVersion from an enum to a class
45+
export const toJDKMetricValue = (source: JDKVersion): string => {
46+
switch (source) {
47+
case JDKVersion.JDK8:
48+
return 'jdk8'
49+
case JDKVersion.JDK11:
50+
return 'jdk11'
51+
case JDKVersion.JDK17:
52+
return 'jdk17'
53+
default:
54+
return ''
55+
}
56+
}
57+
58+
export const calculateTotalLatency = (startTime: number, endTime: number = Date.now()): number => endTime - startTime

src/codewhisperer/commands/basicCommands.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ import { FileSystemCommon } from '../../srcShared/fs'
3232
import { Mutable } from '../../shared/utilities/tsUtils'
3333
import { CodeWhispererSource } from './types'
3434
import { showManageConnections } from '../../auth/ui/vue/show'
35+
import {
36+
CancelActionPositions,
37+
logCodeTransformInitiatedMetric,
38+
} from '../../amazonqGumby/telemetry/codeTransformTelemetry'
3539
import { FeatureConfigProvider } from '../service/featureConfigProvider'
3640

3741
export const toggleCodeSuggestions = Commands.declare(
@@ -98,7 +102,6 @@ export const showSecurityScan = Commands.declare(
98102
}
99103
)
100104

101-
export const transformTreeNode = 'qTreeNode'
102105
export const showTransformByQ = Commands.declare(
103106
{ id: 'aws.awsq.transform', compositeKey: { 0: 'source' } },
104107
(context: ExtContext) => async (source: string) => {
@@ -107,14 +110,15 @@ export const showTransformByQ = Commands.declare(
107110
}
108111

109112
if (transformByQState.isNotStarted()) {
113+
logCodeTransformInitiatedMetric(source)
110114
startTransformByQWithProgress()
111115
} else if (transformByQState.isCancelled()) {
112116
vscode.window.showInformationMessage(CodeWhispererConstants.cancellationInProgressMessage)
113117
} else if (transformByQState.isRunning()) {
114-
await confirmStopTransformByQ(transformByQState.getJobId())
118+
await confirmStopTransformByQ(transformByQState.getJobId(), CancelActionPositions.DevToolsSidePanel)
115119
}
116120
// emit telemetry if clicked from tree node
117-
if (source === transformTreeNode) {
121+
if (source === CodeWhispererConstants.transformTreeNode) {
118122
telemetry.ui_click.emit({
119123
elementId: 'amazonq_transform',
120124
passive: false,

0 commit comments

Comments
 (0)