Skip to content

Commit afbf326

Browse files
committed
Adding toolkit telemetry for build and execute in UTG
1 parent ddb1965 commit afbf326

File tree

4 files changed

+265
-36
lines changed

4 files changed

+265
-36
lines changed

packages/core/src/amazonqTest/chat/controller/controller.ts

Lines changed: 120 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -285,19 +285,35 @@ export class TestController {
285285
if (session.stopIteration) {
286286
telemetryErrorMessage = getTelemetryReasonDesc(data.error.uiMessage.replaceAll('```', ''))
287287
}
288-
TelemetryHelper.instance.sendTestGenerationToolkitEvent(
289-
session,
290-
true,
291-
true,
292-
isCancel ? 'Cancelled' : 'Failed',
293-
session.startTestGenerationRequestId,
294-
performance.now() - session.testGenerationStartTime,
295-
telemetryErrorMessage,
296-
session.isCodeBlockSelected,
297-
session.artifactsUploadDuration,
298-
session.srcPayloadSize,
299-
session.srcZipFileSize
300-
)
288+
if (session.listOfTestGenerationJobId.length > 1) {
289+
TelemetryHelper.instance.sendUnitTestGenerationEvent(
290+
session,
291+
isCancel ? 'Cancelled' : 'Failed',
292+
session.artifactsUploadDuration,
293+
session.srcZipFileSize,
294+
session.charsOfCodeAccepted,
295+
session.numberOfTestsGenerated,
296+
session.linesOfCodeGenerated,
297+
session.charsOfCodeGenerated,
298+
session.numberOfTestsGenerated,
299+
session.linesOfCodeGenerated,
300+
undefined
301+
)
302+
} else {
303+
TelemetryHelper.instance.sendTestGenerationToolkitEvent(
304+
session,
305+
session.isSupportedLanguage,
306+
true,
307+
isCancel ? 'Cancelled' : 'Failed',
308+
session.startTestGenerationRequestId,
309+
performance.now() - session.testGenerationStartTime,
310+
telemetryErrorMessage,
311+
session.isCodeBlockSelected,
312+
session.artifactsUploadDuration,
313+
session.srcPayloadSize,
314+
session.srcZipFileSize
315+
)
316+
}
301317
if (session.stopIteration) {
302318
// Error from Science
303319
this.messenger.sendMessage(data.error.uiMessage.replaceAll('```', ''), data.tabID, 'answer')
@@ -503,6 +519,7 @@ export class TestController {
503519
unsupportedMessage = `<span style="color: #EE9D28;">&#9888;<b>I'm sorry, but /test only supports Python and Java</b><br></span> I will still generate a suggestion below.`
504520
}
505521
this.messenger.sendMessage(unsupportedMessage, tabID, 'answer')
522+
session.isSupportedLanguage = false
506523
await this.onCodeGeneration(
507524
session,
508525
userPrompt,
@@ -530,6 +547,7 @@ export class TestController {
530547
)
531548
}
532549
session.isCodeBlockSelected = selectionRange !== undefined
550+
session.isSupportedLanguage = true
533551

534552
/**
535553
* Zip the project
@@ -613,7 +631,7 @@ export class TestController {
613631
// return early if references are disabled and there are references
614632
if (!CodeWhispererSettings.instance.isSuggestionsWithCodeReferencesEnabled() && session.references.length > 0) {
615633
void vscode.window.showInformationMessage('Your settings do not allow code generation with references.')
616-
await this.endSession(data, FollowUpTypes.SkipBuildAndFinish)
634+
await this.endSession(data)
617635
await this.sessionCleanUp()
618636
return
619637
}
@@ -690,7 +708,12 @@ export class TestController {
690708
const rightUri = vscode.Uri.file(path.join(this.tempResultDirPath, 'resultArtifacts', filePath))
691709
const fileName = path.basename(absolutePath)
692710
await vscode.commands.executeCommand('vscode.diff', leftUri, rightUri, `${fileName} ${amazonQTabSuffix}`)
693-
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_viewDiff' })
711+
const elementId =
712+
session.listOfTestGenerationJobId.length > 1
713+
? 'unitTestGeneration_viewDiff_Iteration'
714+
: 'unitTestGeneration_viewDiff'
715+
716+
telemetry.ui_click.emit({ elementId })
694717
session.latencyOfTestGeneration = performance.now() - session.testGenerationStartTime
695718
this.messenger.sendUpdatePlaceholder(message.tabID, `Please select an action to proceed (Accept or Reject)`)
696719
}
@@ -774,9 +797,12 @@ export class TestController {
774797
}
775798
const document = await vscode.workspace.openTextDocument(absolutePath)
776799
await vscode.window.showTextDocument(document)
777-
// TODO: send the message once again once build is enabled
778-
// this.messenger.sendMessage('Accepted', message.tabID, 'prompt')
779-
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_acceptDiff' })
800+
const elementId =
801+
session.listOfTestGenerationJobId.length > 1
802+
? 'unitTestGeneration_acceptDiff_Iteration'
803+
: 'unitTestGeneration_acceptDiff'
804+
805+
telemetry.ui_click.emit({ elementId })
780806

781807
getLogger().info(
782808
`Generated unit tests are accepted for ${session.fileLanguage ?? 'plaintext'} language with jobId: ${session.listOfTestGenerationJobId[0]}, jobGroupName: ${session.testGenerationJobGroupName}, result: Succeeded`
@@ -802,7 +828,7 @@ export class TestController {
802828
)
803829

804830
if (!Auth.instance.isInternalAmazonUser()) {
805-
await this.endSession(message, FollowUpTypes.SkipBuildAndFinish)
831+
await this.endSession(message)
806832
return
807833
}
808834

@@ -844,6 +870,19 @@ export class TestController {
844870
})
845871
this.messenger.sendChatInputEnabled(message.tabID, false)
846872
} else {
873+
TelemetryHelper.instance.sendUnitTestGenerationEvent(
874+
session,
875+
undefined,
876+
session.artifactsUploadDuration,
877+
session.srcZipFileSize,
878+
session.charsOfCodeAccepted,
879+
session.numberOfTestsGenerated,
880+
session.linesOfCodeGenerated,
881+
session.charsOfCodeGenerated,
882+
session.numberOfTestsGenerated,
883+
session.linesOfCodeGenerated,
884+
undefined
885+
)
847886
this.sessionStorage.getSession().listOfTestGenerationJobId = []
848887
this.messenger.sendMessage(
849888
'You have gone through both iterations and this unit test generation workflow is complete.',
@@ -904,31 +943,65 @@ export class TestController {
904943
}
905944

906945
// TODO: Check if there are more cases to endSession if yes create a enum or type for step
907-
private async endSession(data: any, step: FollowUpTypes) {
946+
private async endSession(data: any, step?: FollowUpTypes) {
908947
this.messenger.sendMessage('Unit test generation completed.', data.tabID, 'answer')
909948

910949
const session = this.sessionStorage.getSession()
911950
if (step === FollowUpTypes.RejectCode) {
912-
TelemetryHelper.instance.sendTestGenerationToolkitEvent(
951+
if (session.listOfTestGenerationJobId.length > 1) {
952+
// TODO
953+
// telemetry.amazonq_unitTestGeneration.emit()
954+
TelemetryHelper.instance.sendUnitTestGenerationEvent(
955+
session,
956+
undefined,
957+
session.artifactsUploadDuration,
958+
session.srcZipFileSize,
959+
0,
960+
0,
961+
0,
962+
session.charsOfCodeGenerated,
963+
session.numberOfTestsGenerated,
964+
session.linesOfCodeGenerated,
965+
undefined
966+
)
967+
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_rejectDiff_Iteration' })
968+
} else {
969+
TelemetryHelper.instance.sendTestGenerationToolkitEvent(
970+
session,
971+
true,
972+
true,
973+
'Succeeded',
974+
session.startTestGenerationRequestId,
975+
session.latencyOfTestGeneration,
976+
undefined,
977+
session.isCodeBlockSelected,
978+
session.artifactsUploadDuration,
979+
session.srcPayloadSize,
980+
session.srcZipFileSize,
981+
0,
982+
0,
983+
0,
984+
session.charsOfCodeGenerated,
985+
session.numberOfTestsGenerated,
986+
session.linesOfCodeGenerated
987+
)
988+
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_rejectDiff' })
989+
}
990+
} else if (step === FollowUpTypes.SkipBuildAndFinish) {
991+
TelemetryHelper.instance.sendUnitTestGenerationEvent(
913992
session,
914-
true,
915-
true,
916-
'Succeeded',
917-
session.startTestGenerationRequestId,
918-
session.latencyOfTestGeneration,
919993
undefined,
920-
session.isCodeBlockSelected,
921994
session.artifactsUploadDuration,
922-
session.srcPayloadSize,
923995
session.srcZipFileSize,
924-
0,
925-
0,
926-
0,
927996
session.charsOfCodeGenerated,
928997
session.numberOfTestsGenerated,
929-
session.linesOfCodeGenerated
998+
session.linesOfCodeGenerated,
999+
session.charsOfCodeGenerated,
1000+
session.numberOfTestsGenerated,
1001+
session.linesOfCodeGenerated,
1002+
undefined
9301003
)
931-
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_rejectDiff' })
1004+
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_SkipAndFinish' })
9321005
}
9331006

9341007
await this.sessionCleanUp()
@@ -944,7 +1017,7 @@ export class TestController {
9441017

9451018
private startInitialBuild(data: any) {
9461019
// TODO: Remove the fallback build command after stable version of backend build command.
947-
const userMessage = `Would you like me to help build and execute the test? I’ll run following commands.\n\`\`\`sh\n${this.sessionStorage.getSession().shortAnswer?.buildCommand}\n`
1020+
const userMessage = `Would you like me to help build and execute the test? I’ll run following commands.\n\`\`\`sh\n${this.getBuildCommands()}\n`
9481021
const followUps: FollowUps = {
9491022
text: '',
9501023
options: [
@@ -1264,6 +1337,19 @@ export class TestController {
12641337

12651338
if (codeDiffLength === 0 || session.buildStatus === BuildStatus.SUCCESS) {
12661339
this.messenger.sendMessage('Unit test generation workflow is complete.', data.tabID, 'answer')
1340+
TelemetryHelper.instance.sendUnitTestGenerationEvent(
1341+
session,
1342+
undefined,
1343+
session.artifactsUploadDuration,
1344+
session.srcZipFileSize,
1345+
session.charsOfCodeGenerated,
1346+
session.numberOfTestsGenerated,
1347+
session.linesOfCodeGenerated,
1348+
session.charsOfCodeGenerated,
1349+
session.numberOfTestsGenerated,
1350+
session.linesOfCodeGenerated,
1351+
undefined
1352+
)
12671353
await this.sessionCleanUp()
12681354
}
12691355
}

packages/core/src/amazonqTest/chat/session/session.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export class Session {
3535
public testGenerationJob: TestGenerationJob | undefined
3636

3737
// Start Test generation
38+
public isSupportedLanguage: boolean = false
3839
public conversationState: ConversationState = ConversationState.IDLE
3940
public shortAnswer: ShortAnswer | undefined
4041
public sourceFilePath: string = ''

packages/core/src/codewhisperer/util/telemetryHelper.ts

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
CodewhispererPreviousSuggestionState,
1414
CodewhispererUserDecision,
1515
CodewhispererUserTriggerDecision,
16+
Result,
1617
telemetry,
1718
} from '../../shared/telemetry/telemetry'
1819
import { CodewhispererCompletionType, CodewhispererSuggestionState } from '../../shared/telemetry/telemetry'
@@ -27,7 +28,7 @@ import { CodeWhispererSupplementalContext } from '../models/model'
2728
import { FeatureConfigProvider } from '../../shared/featureConfig'
2829
import { CodeScanRemediationsEventType } from '../client/codewhispereruserclient'
2930
import { CodeAnalysisScope as CodeAnalysisScopeClientSide } from '../models/constants'
30-
import { Session } from '../../amazonqTest/chat/session/session'
31+
import { BuildStatus, Session } from '../../amazonqTest/chat/session/session'
3132

3233
export class TelemetryHelper {
3334
// Some variables for client component latency
@@ -90,7 +91,7 @@ export class TelemetryHelper {
9091
telemetry.amazonq_utgGenerateTests.emit({
9192
cwsprChatProgrammingLanguage: session.fileLanguage ?? 'plaintext',
9293
hasUserPromptSupplied: session.hasUserPromptSupplied,
93-
isSupportedLanguage: isSupportedLanguage,
94+
isSupportedLanguage: session.isSupportedLanguage,
9495
isFileInWorkspace: isFileInWorkspace,
9596
result: result,
9697
artifactsUploadDuration: artifactsUploadDuration,
@@ -113,6 +114,61 @@ export class TelemetryHelper {
113114
})
114115
}
115116

117+
/**
118+
* amazonq_unitTestGeneration event is emitted in 6 cases for Unit Test Generation
119+
* 1) If user close chat window
120+
* 2) If build succeeds in build and execute
121+
* 3) If user reject generated code
122+
* 4) If user click on skip and finish button
123+
* 5) If user completes 3 iterations in build and execute
124+
* 6) If there is any error/exception
125+
*/
126+
public sendUnitTestGenerationEvent(
127+
session: Session,
128+
reasonDesc?: string,
129+
artifactsUploadDuration?: number,
130+
buildZipFileBytes?: number,
131+
acceptedCharactersCount?: number,
132+
acceptedCount?: number,
133+
acceptedLinesCount?: number,
134+
generatedCharactersCount?: number,
135+
generatedCount?: number,
136+
generatedLinesCount?: number,
137+
reason?: string
138+
) {
139+
telemetry.amazonq_unitTestGeneration.emit({
140+
cwsprChatProgrammingLanguage: session.fileLanguage ?? 'plaintext',
141+
hasUserPromptSupplied: session.hasUserPromptSupplied,
142+
isSupportedLanguage: session.isSupportedLanguage,
143+
isFileInWorkspace: true, // Always true TODO: Confirm
144+
result:
145+
session.buildStatus === BuildStatus.SUCCESS
146+
? 'Succeeded'
147+
: session.buildStatus === BuildStatus.FAILURE
148+
? 'Failed'
149+
: ('Cancelled' as Result),
150+
151+
artifactsUploadDuration: artifactsUploadDuration,
152+
buildZipFileBytes: buildZipFileBytes,
153+
credentialStartUrl: AuthUtil.instance.startUrl,
154+
acceptedCharactersCount: acceptedCharactersCount,
155+
acceptedCount: acceptedCount,
156+
acceptedLinesCount: acceptedLinesCount,
157+
generatedCharactersCount: generatedCharactersCount,
158+
generatedCount: generatedCount,
159+
generatedLinesCount: generatedLinesCount,
160+
isCodeBlockSelected: session.isCodeBlockSelected,
161+
jobGroup: session.testGenerationJobGroupName,
162+
jobId: session.listOfTestGenerationJobId.at(-1) ?? undefined,
163+
perfClientLatency: 0, // TODO for V2 version: Calculate the client side latency between iterations
164+
requestId: session.startTestGenerationRequestId,
165+
reasonDesc: reasonDesc,
166+
reason: reason,
167+
update: (session.updatedBuildCommands?.length ?? 0) > 0, // If user modifies command return true else false
168+
count: session.listOfTestGenerationJobId.length - 1, // Number of build and execute iterations if count = -1 then user did not even start the build and cycle loop and failed/terminated at the vanilla UTG.
169+
})
170+
}
171+
116172
public recordServiceInvocationTelemetry(
117173
requestId: string,
118174
sessionId: string,

0 commit comments

Comments
 (0)