diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatOpenAgentDebugPanelAction.ts b/src/vs/workbench/contrib/chat/browser/actions/chatOpenAgentDebugPanelAction.ts index e8e96696e52..2f989dacea2 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatOpenAgentDebugPanelAction.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatOpenAgentDebugPanelAction.ts @@ -11,9 +11,10 @@ import { localize, localize2 } from '../../../../../nls.js'; import { Action2, MenuId, registerAction2 } from '../../../../../platform/actions/common/actions.js'; import { Categories } from '../../../../../platform/action/common/actionCommonCategories.js'; import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js'; -import { IFileDialogService } from '../../../../../platform/dialogs/common/dialogs.js'; +import { IDialogService, IFileDialogService } from '../../../../../platform/dialogs/common/dialogs.js'; import { IFileService } from '../../../../../platform/files/common/files.js'; import { INotificationService, Severity } from '../../../../../platform/notification/common/notification.js'; +import { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js'; import { ActiveEditorContext } from '../../../../common/contextkeys.js'; import { IEditorService } from '../../../../services/editor/common/editorService.js'; import { isChatViewTitleActionContext } from '../../common/actions/chatActions.js'; @@ -126,6 +127,7 @@ export function registerChatOpenAgentDebugPanelAction() { const fileDialogService = accessor.get(IFileDialogService); const fileService = accessor.get(IFileService); const notificationService = accessor.get(INotificationService); + const telemetryService = accessor.get(ITelemetryService); const sessionResource = chatDebugService.activeSessionResource; if (!sessionResource) { @@ -146,6 +148,10 @@ export function registerChatOpenAgentDebugPanelAction() { } await fileService.writeFile(outputPath, VSBuffer.wrap(data)); + + telemetryService.publicLog2('chatDebugLogExported', { + fileSizeBytes: data.byteLength, + }); } }); @@ -169,10 +175,12 @@ export function registerChatOpenAgentDebugPanelAction() { async run(accessor: ServicesAccessor): Promise { const chatDebugService = accessor.get(IChatDebugService); + const dialogService = accessor.get(IDialogService); const editorService = accessor.get(IEditorService); const fileDialogService = accessor.get(IFileDialogService); const fileService = accessor.get(IFileService); const notificationService = accessor.get(INotificationService); + const telemetryService = accessor.get(ITelemetryService); const defaultUri = joinPath(await fileDialogService.defaultFilePath(), defaultDebugLogFileName); const result = await fileDialogService.showOpenDialog({ @@ -187,19 +195,59 @@ export function registerChatOpenAgentDebugPanelAction() { const maxImportSize = 50 * 1024 * 1024; // 50 MB const stat = await fileService.stat(result[0]); if (stat.size !== undefined && stat.size > maxImportSize) { - notificationService.notify({ severity: Severity.Warning, message: localize('chatDebugLog.fileTooLarge', "The selected file exceeds the 50 MB size limit for log imports.") }); + telemetryService.publicLog2('chatDebugLogImported', { + fileSizeBytes: stat.size, + result: 'fileTooLarge', + }); + await dialogService.warn( + localize('chatDebugLog.fileTooLargeTitle', "File Too Large"), + localize('chatDebugLog.fileTooLargeDetail', "The selected file ({0} MB) exceeds the 50 MB size limit for debug log imports.", (stat.size / (1024 * 1024)).toFixed(1)) + ); return; } const content = await fileService.readFile(result[0]); const sessionUri = await chatDebugService.importLog(content.value.buffer); if (!sessionUri) { + telemetryService.publicLog2('chatDebugLogImported', { + fileSizeBytes: content.value.byteLength, + result: 'providerFailed', + }); notificationService.notify({ severity: Severity.Warning, message: localize('chatDebugLog.importFailed', "Import is not supported by the current provider.") }); return; } + telemetryService.publicLog2('chatDebugLogImported', { + fileSizeBytes: content.value.byteLength, + result: 'success', + }); + const options: IChatDebugEditorOptions = { pinned: true, sessionResource: sessionUri, viewHint: 'overview' }; await editorService.openEditor(ChatDebugEditorInput.instance, options); } }); } + +// Telemetry types + +type ChatDebugExportEvent = { + fileSizeBytes: number; +}; + +type ChatDebugExportClassification = { + fileSizeBytes: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Size of the exported chat debug log file in bytes.' }; + owner: 'vijayu'; + comment: 'Tracks usage of the debug panel export feature.'; +}; + +type ChatDebugImportEvent = { + fileSizeBytes: number; + result: 'success' | 'fileTooLarge' | 'providerFailed'; +}; + +type ChatDebugImportClassification = { + fileSizeBytes: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Size of the imported chat debug log file in bytes.' }; + result: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Outcome of the chat debug file import: success, fileTooLarge, or providerFailed.' }; + owner: 'vijayu'; + comment: 'Tracks usage of the debug panel import feature and failure modes.'; +};