Skip to content
24 changes: 23 additions & 1 deletion packages/amazonq/src/lsp/chat/autoDebug/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import * as vscode from 'vscode'
import { Commands, getLogger, messages } from 'aws-core-vscode/shared'
import { AutoDebugController } from './controller'
import { autoDebugTelemetry } from './telemetry'

/**
* Auto Debug commands for Amazon Q
Expand Down Expand Up @@ -72,6 +73,16 @@ export class AutoDebugCommands implements vscode.Disposable {
return await action()
} catch (error) {
this.logger.error(`AutoDebugCommands: Error in ${logContext}: %s`, error)

// Record telemetry failure based on context
const commandType =
logContext === 'fixWithAmazonQ'
? 'fixWithQ'
: logContext === 'fixAllWithAmazonQ'
? 'fixAllWithQ'
: 'explainProblem'
autoDebugTelemetry.recordCommandFailure(commandType, String(error))

void messages.showMessage('error', 'Amazon Q was not able to fix or explain the problem. Try again shortly')
}
}
Expand All @@ -91,6 +102,9 @@ export class AutoDebugCommands implements vscode.Disposable {
* Fix with Amazon Q - fixes only the specific issues the user selected
*/
private async fixWithAmazonQ(range?: vscode.Range, diagnostics?: vscode.Diagnostic[]): Promise<void> {
const problemCount = diagnostics?.length
autoDebugTelemetry.recordCommandInvocation('fixWithQ', problemCount)

await this.executeWithErrorHandling(
async () => {
const editor = this.checkActiveEditor()
Expand All @@ -102,6 +116,7 @@ export class AutoDebugCommands implements vscode.Disposable {
throw new Error('Failed to save document')
}
await this.controller.fixSpecificProblems(range, diagnostics)
autoDebugTelemetry.recordCommandSuccess('fixWithQ', problemCount)
},
'Fix with Amazon Q',
'fixWithAmazonQ'
Expand All @@ -112,6 +127,8 @@ export class AutoDebugCommands implements vscode.Disposable {
* Fix All with Amazon Q - processes all errors in the current file
*/
private async fixAllWithAmazonQ(): Promise<void> {
autoDebugTelemetry.recordCommandInvocation('fixAllWithQ')

await this.executeWithErrorHandling(
async () => {
const editor = this.checkActiveEditor()
Expand All @@ -122,7 +139,8 @@ export class AutoDebugCommands implements vscode.Disposable {
if (!saved) {
throw new Error('Failed to save document')
}
await this.controller.fixAllProblemsInFile(10) // 10 errors per batch
const problemCount = await this.controller.fixAllProblemsInFile(10) // 10 errors per batch
autoDebugTelemetry.recordCommandSuccess('fixAllWithQ', problemCount)
},
'Fix All with Amazon Q',
'fixAllWithAmazonQ'
Expand All @@ -133,13 +151,17 @@ export class AutoDebugCommands implements vscode.Disposable {
* Explains the problem using Amazon Q
*/
private async explainProblem(range?: vscode.Range, diagnostics?: vscode.Diagnostic[]): Promise<void> {
const problemCount = diagnostics?.length
autoDebugTelemetry.recordCommandInvocation('explainProblem', problemCount)

await this.executeWithErrorHandling(
async () => {
const editor = this.checkActiveEditor()
if (!editor) {
return
}
await this.controller.explainProblems(range, diagnostics)
autoDebugTelemetry.recordCommandSuccess('explainProblem', problemCount)
},
'Explain Problem',
'explainProblem'
Expand Down
10 changes: 6 additions & 4 deletions packages/amazonq/src/lsp/chat/autoDebug/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,32 +110,34 @@ export class AutoDebugController implements vscode.Disposable {
/**
* Fix with Amazon Q - sends up to 15 error messages one time when user clicks the button
*/
public async fixAllProblemsInFile(maxProblems: number = 15): Promise<void> {
public async fixAllProblemsInFile(maxProblems: number = 15): Promise<number> {
try {
const editor = vscode.window.activeTextEditor
if (!editor) {
void messages.showMessage('warn', 'No active editor found')
return
return 0
}

// Get all diagnostics for the current file
const allDiagnostics = vscode.languages.getDiagnostics(editor.document.uri)
const errorDiagnostics = this.filterErrorDiagnostics(allDiagnostics)
if (errorDiagnostics.length === 0) {
return
return 0
}

// Take up to maxProblems errors (15 by default)
const diagnosticsToFix = errorDiagnostics.slice(0, maxProblems)
const result = await this.getProblemsFromDiagnostics(undefined, diagnosticsToFix)
if (!result) {
return
return 0
}

const fixMessage = this.createFixMessage(result.editor.document.uri.fsPath, result.problems)
await this.sendMessageToChat(fixMessage)
return result.problems.length
} catch (error) {
this.logger.error('AutoDebugController: Error in fix process: %s', error)
throw error
}
}

Expand Down
71 changes: 71 additions & 0 deletions packages/amazonq/src/lsp/chat/autoDebug/telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*!
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

import { telemetry } from 'aws-core-vscode/telemetry'

/**
* Auto Debug command types for telemetry tracking
*/
export type AutoDebugCommandType = 'fixWithQ' | 'fixAllWithQ' | 'explainProblem'

/**
* Telemetry interface for Auto Debug feature
* Tracks usage counts and success rates for the three main commands
*/
export interface AutoDebugTelemetry {
/**
* Record when an auto debug command is invoked
*/
recordCommandInvocation(commandType: AutoDebugCommandType, problemCount?: number): void

/**
* Record when an auto debug command succeeds
*/
recordCommandSuccess(commandType: AutoDebugCommandType, problemCount?: number): void

/**
* Record when an auto debug command fails
*/
recordCommandFailure(commandType: AutoDebugCommandType, error?: string, problemCount?: number): void
}

/**
* Implementation of Auto Debug telemetry tracking
*/
export class AutoDebugTelemetryImpl implements AutoDebugTelemetry {
recordCommandInvocation(commandType: AutoDebugCommandType, problemCount?: number): void {
telemetry.amazonq_autoDebugCommand.emit({
amazonqAutoDebugCommandType: commandType,
amazonqAutoDebugAction: 'invoked',
amazonqAutoDebugProblemCount: problemCount,
result: 'Succeeded',
})
}

recordCommandSuccess(commandType: AutoDebugCommandType, problemCount?: number): void {
telemetry.amazonq_autoDebugCommand.emit({
amazonqAutoDebugCommandType: commandType,
amazonqAutoDebugAction: 'completed',
amazonqAutoDebugProblemCount: problemCount,
result: 'Succeeded',
})
}

recordCommandFailure(commandType: AutoDebugCommandType, error?: string, problemCount?: number): void {
telemetry.amazonq_autoDebugCommand.emit({
amazonqAutoDebugCommandType: commandType,
amazonqAutoDebugAction: 'completed',
amazonqAutoDebugProblemCount: problemCount,
result: 'Failed',
reason: error ? 'Error' : 'Unknown',
reasonDesc: error?.substring(0, 200), // Truncate to 200 chars as recommended
})
}
}

/**
* Global instance of auto debug telemetry
*/
export const autoDebugTelemetry: AutoDebugTelemetry = new AutoDebugTelemetryImpl()
46 changes: 46 additions & 0 deletions packages/core/src/shared/telemetry/vscodeTelemetry.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,23 @@
"type": "int",
"description": "The number of executed operations"
},
{
"name": "amazonqAutoDebugCommandType",
"type": "string",
"allowedValues": ["fixWithQ", "fixAllWithQ", "explainProblem"],
"description": "The type of auto debug command executed"
},
{
"name": "amazonqAutoDebugAction",
"type": "string",
"allowedValues": ["invoked", "completed"],
"description": "The action performed (invoked or completed)"
},
{
"name": "amazonqAutoDebugProblemCount",
"type": "int",
"description": "Number of problems being processed"
},
{
"name": "smusDomainId",
"type": "string",
Expand Down Expand Up @@ -1306,6 +1323,35 @@
}
]
},
{
"name": "amazonq_autoDebugCommand",
"description": "Tracks usage of Amazon Q auto debug commands (fixWithQ, fixAllWithQ, explainProblem)",
"metadata": [
{
"type": "amazonqAutoDebugCommandType",
"required": true
},
{
"type": "amazonqAutoDebugAction",
"required": true
},
{
"type": "amazonqAutoDebugProblemCount",
"required": false
},
{
"type": "result"
},
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be available by default IIRC.

"type": "reason",
"required": false
},
{
"type": "reasonDesc",
"required": false
}
]
},
{
"name": "smus_login",
"description": "Emitted whenever a user signin to SMUS",
Expand Down