-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathcopilotCompletionContextTelemetry.ts
More file actions
121 lines (100 loc) · 5.18 KB
/
copilotCompletionContextTelemetry.ts
File metadata and controls
121 lines (100 loc) · 5.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import { randomUUID } from 'crypto';
import * as telemetry from '../telemetry';
import { CopilotCompletionContextFeatures, CopilotCompletionKind } from './copilotCompletionContextProvider';
export class CopilotCompletionContextTelemetry {
private static readonly correlationIdKey = 'correlationId';
private static readonly copilotEventName = 'copilotContextProvider';
private readonly metrics: Record<string, number> = {};
private readonly properties: Record<string, string> = {};
private readonly id: string;
constructor(correlationId?: string) {
this.id = correlationId ?? randomUUID().toString();
}
private addMetric(key: string, value: number): void {
this.metrics[key] = value;
}
private addProperty(key: string, value: string): void {
this.properties[key] = value;
}
public addInternalCanceled(duration?: number): void {
this.addProperty('internalCanceled', 'true');
this.addMetric('canceledElapsedMs', duration ?? -1);
}
public addCopilotCanceled(duration?: number): void {
this.addProperty('copilotCanceled', 'true');
this.addMetric('canceledElapsedMs', duration ?? -1);
}
public addError(): void {
this.addProperty('error', 'true');
}
public addWellKnownError(message: string): void {
this.addProperty('wellKnownError', message);
}
public addCompletionContextKind(completionKind: CopilotCompletionKind): void {
this.addProperty('completionContextKind', completionKind.toString());
}
public addCacheHitEntryGuid(cacheEntryGuid: string): void {
this.addProperty('usedCacheEntryId', cacheEntryGuid);
}
public addResolvedElapsed(duration: number): void {
this.addMetric('overallResolveElapsedMs', duration);
}
public addCacheSize(size: number): void {
this.addMetric('cacheSize', size);
}
public addCacheComputedData(duration: number, id: string): void {
this.addMetric('cacheComputedElapsedMs', duration);
this.addProperty('createdCacheEntryId', id);
}
public addRequestId(id: number): void {
this.addProperty('response.requestId', id.toString());
}
public addComputeContextElapsed(duration: number): void {
this.addMetric('computeContextElapsedMs', duration);
}
public addGetClientForElapsed(duration: number): void {
this.addMetric('getClientForElapsedMs', duration);
}
public addResponseMetadata(areSnippetsMissing: boolean, codeSnippetsCount?: number, traitsCount?: number, caretOffset?: number,
featureFlag?: CopilotCompletionContextFeatures): void {
this.addProperty('response.areCodeSnippetsMissing', areSnippetsMissing.toString());
// Args can be undefined, in which case the value is set to a
// special value (e.g. -1) to indicate data is not set.
this.addMetric('response.caretOffset', caretOffset ?? -1);
this.addProperty('response.featureFlag', featureFlag?.toString() ?? '<not-set>');
this.addMetric('response.codeSnippetsCount', codeSnippetsCount ?? -1);
this.addMetric('response.traitsCount', traitsCount ?? -1);
}
public addRequestMetadata(uri: string, caretOffset: number, completionId: string,
languageId: string, { featureFlag, timeBudgetFactor, maxCaretDistance }: {
featureFlag?: CopilotCompletionContextFeatures;
timeBudgetFactor?: number; maxCaretDistance?: number;
} = {}): void {
this.addProperty('request.completionId', completionId);
this.addProperty('request.languageId', languageId);
this.addMetric('request.caretOffset', caretOffset);
this.addProperty('request.featureFlag', featureFlag?.toString() ?? '<not-set>');
if (timeBudgetFactor !== undefined) { this.addMetric('request.timeBudgetFactor', timeBudgetFactor); }
if (maxCaretDistance !== undefined) { this.addMetric('request.maxCaretDistance', maxCaretDistance); }
}
public addCppStandardVersionMetadata(standardVersion: string, elapsedMs: number): void {
this.addProperty('response.cppStandardVersion', standardVersion);
this.addMetric('response.cppStandardVersionElapsedMs', elapsedMs);
}
public send(postfix?: string): void {
try {
const eventName = CopilotCompletionContextTelemetry.copilotEventName + (postfix ? `/${postfix}` : '');
this.properties[CopilotCompletionContextTelemetry.correlationIdKey] = this.id;
telemetry.logCopilotEvent(eventName, this.properties, this.metrics);
} catch (error) {
console.error('Error logging copilot telemetry event', error);
}
}
public fork(): CopilotCompletionContextTelemetry {
return new CopilotCompletionContextTelemetry(this.id);
}
}