Path: blob/main/extensions/copilot/src/extension/chat/vscode-node/chatHookTelemetry.ts
13399 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import type * as vscode from 'vscode';6import { IPostToolUseHookResult, IPreToolUseHookResult } from '../../../platform/chat/common/chatHookService';7import { ITelemetryService } from '../../../platform/telemetry/common/telemetry';89export class ChatHookTelemetry {10constructor(11private readonly _telemetryService: ITelemetryService,12) { }1314logConfiguredHooks(hooks: vscode.ChatRequestHooks): void {15const hookTypeCounts: Record<string, number> = {};16let totalHookCount = 0;17for (const hookType of Object.keys(hooks)) {18const commands = hooks[hookType];19if (commands && commands.length > 0) {20hookTypeCounts[hookType] = commands.length;21totalHookCount += commands.length;22}23}2425if (totalHookCount === 0) {26return;27}2829/* __GDPR__30"hooks.configured" : {31"owner": "roblourens",32"comment": "Reports which hook types are configured for a chat request",33"hookTypes": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "JSON map of hook type names to their command counts" },34"totalHookCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Total number of hook commands configured across all types" }35}36*/37this._telemetryService.sendMSFTTelemetryEvent('hooks.configured', {38hookTypes: JSON.stringify(hookTypeCounts),39}, {40totalHookCount,41});42}4344logHookExecuted(hookType: string, hookCount: number, durationMs: number, hasError: boolean, hasCaughtException: boolean): void {45/* __GDPR__46"hooks.executed" : {47"owner": "roblourens",48"comment": "Reports the execution of hooks including duration and outcome",49"hookType": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The type of hook that was executed (e.g., PreToolUse, PostToolUse, Stop)" },50"hookCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Number of hook commands executed for this hook type" },51"hasError": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Whether any hook command returned an error exit code" },52"hasCaughtException": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Whether an unexpected exception was caught during hook execution" },53"durationMs": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "comment": "Total duration of all hook executions in milliseconds" }54}55*/56this._telemetryService.sendMSFTTelemetryEvent('hooks.executed', {57hookType,58hasError: String(hasError),59hasCaughtException: String(hasCaughtException),60}, {61hookCount,62durationMs,63});64}6566logPreToolUseResult(result: IPreToolUseHookResult): void {67/* __GDPR__68"hooks.preToolUse.result" : {69"owner": "roblourens",70"comment": "Reports the collapsed result of PreToolUse hooks including whether the tool was blocked",71"permissionDecision": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The most restrictive permission decision: allow, deny, or ask" },72"hasUpdatedInput": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Whether a hook modified the tool input" },73"hasAdditionalContext": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Whether hooks provided additional context" }74}75*/76this._telemetryService.sendMSFTTelemetryEvent('hooks.preToolUse.result', {77permissionDecision: result.permissionDecision,78hasUpdatedInput: result.updatedInput ? 'true' : undefined,79hasAdditionalContext: result.additionalContext ? 'true' : undefined,80});81}8283logPostToolUseResult(result: IPostToolUseHookResult): void {84/* __GDPR__85"hooks.postToolUse.result" : {86"owner": "roblourens",87"comment": "Reports the collapsed result of PostToolUse hooks including whether the tool result was blocked",88"didBlock": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Whether any hook blocked the tool result" },89"hasAdditionalContext": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Whether hooks provided additional context" }90}91*/92this._telemetryService.sendMSFTTelemetryEvent('hooks.postToolUse.result', {93didBlock: result.decision === 'block' ? 'true' : undefined,94hasAdditionalContext: result.additionalContext ? 'true' : undefined,95});96}97}9899100