@vscode/telemetry-extractor 1.9.5 → 1.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/node.js.yml +31 -0
- package/README.md +1 -1
- package/out/cli-options.js +6 -1
- package/out/cli-options.js.map +1 -1
- package/out/extractor.js +7 -3
- package/out/extractor.js.map +1 -1
- package/out/lib/events.js +15 -1
- package/out/lib/events.js.map +1 -1
- package/out/lib/file-writer.js +5 -1
- package/out/lib/file-writer.js.map +1 -1
- package/out/lib/fragments.js.map +1 -1
- package/out/lib/object-converter.js +15 -2
- package/out/lib/object-converter.js.map +1 -1
- package/out/lib/operations.js +9 -1
- package/out/lib/operations.js.map +1 -1
- package/out/lib/parser.js +12 -4
- package/out/lib/parser.js.map +1 -1
- package/out/lib/save-declarations.js +14 -1
- package/out/lib/save-declarations.js.map +1 -1
- package/out/lib/source-spec.js +5 -1
- package/out/lib/source-spec.js.map +1 -1
- package/out/lib/ts-parser.js +31 -15
- package/out/lib/ts-parser.js.map +1 -1
- package/package.json +9 -9
- package/src/cli-options.ts +1 -0
- package/src/extractor.ts +2 -2
- package/src/lib/events.ts +17 -2
- package/src/lib/fragments.ts +2 -2
- package/src/lib/object-converter.ts +10 -3
- package/src/lib/operations.ts +4 -1
- package/src/lib/parser.ts +7 -3
- package/src/lib/save-declarations.ts +9 -0
- package/src/lib/telemetry-interfaces.ts +6 -1
- package/src/lib/ts-parser.ts +28 -25
- package/documentation/comment-code-annotations.md +0 -197
- package/documentation/typescript-code-annotations.md +0 -187
- package/documentation/using-the-tool.md +0 -106
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
# Using Typescript to annotate your Typescript Code
|
|
2
|
-
|
|
3
|
-
As shown in [GDPR formatted comments](comment-code-annotations.md) telemetry events can be documented in the form of hand written JSON comments.
|
|
4
|
-
This form of documentation has its pros and cons, one of the major cons which is human error. Comments do not offer any computer assisted protection agianst things like simple typos while typings do.
|
|
5
|
-
|
|
6
|
-
## Declaring your telemetry handler
|
|
7
|
-
We recommend declaring your telemetry handler the same way VS Code does as the parser explicity looks for a function called publicLog2 which is templated
|
|
8
|
-
and takes two types, the event and the classification.
|
|
9
|
-
|
|
10
|
-
```typescript
|
|
11
|
-
interface IPropertyData {
|
|
12
|
-
classification: 'SystemMetaData' | 'CallstackOrException';
|
|
13
|
-
purpose: 'PerformanceAndHealth' | 'FeatureInsight';
|
|
14
|
-
owner: string;
|
|
15
|
-
comment: string;
|
|
16
|
-
expiration?: string;
|
|
17
|
-
endpoint?: string;
|
|
18
|
-
isMeasurement?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface IGDPRProperty {
|
|
22
|
-
readonly [name: string] : IPropertyData | undefined | IGDPRProperty;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
type ClassifiedEvent<T extends IGDPRProperty> = {
|
|
26
|
-
[k in keyof T]: any
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
type StrictPropertyCheck<TEvent, TClassifiedEvent, TError> = keyof TEvent extends keyof TClassifiedEvent ? keyof TClassifiedEvent extends keyof TEvent ? TEvent : TError : TError;
|
|
30
|
-
|
|
31
|
-
function publicLog2<E extends ClassifiedEvent<T> = never, T extends {[_ in keyof T]: IPropertyData | IGDPRProperty | undefined} = never>(name: string, props: StrictPropertyCheck<E, ClassifiedEvent<T>, 'Type of classified event does not match event properties'>) { }
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Simple Events
|
|
35
|
-
Previously the annotation for the event monacoworkbench/packagemetrics looked like this:
|
|
36
|
-
```ts
|
|
37
|
-
/* __GDPR__
|
|
38
|
-
"monacoworkbench/packagemetrics" : {
|
|
39
|
-
"commit" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
|
|
40
|
-
"size" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
|
|
41
|
-
"count" : {"classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
|
|
42
|
-
}
|
|
43
|
-
*/
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
With typescript annotations the event would be annotated like this:
|
|
47
|
-
```ts
|
|
48
|
-
type PackageMetricsClassification = {
|
|
49
|
-
commit: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' };
|
|
50
|
-
size: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' };
|
|
51
|
-
count: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' };
|
|
52
|
-
};
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
You would then need to declare a type for the event you're sending and send the event
|
|
56
|
-
|
|
57
|
-
```ts
|
|
58
|
-
interface PackageMetrics {
|
|
59
|
-
commit: string;
|
|
60
|
-
size: number;
|
|
61
|
-
count: number;
|
|
62
|
-
};
|
|
63
|
-
publicLog2<PackageMetrics, PackageMetricsClassification>('monacoworkbench/packagemetrics', packageMetric);
|
|
64
|
-
// Inline works too
|
|
65
|
-
publicLog2<PackageMetrics, PackageMetricsClassification>('monacoworkbench/packagemetrics', {commit: 'abcdef', size: 10, count: 1});
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
This form of annotation requires that the type of event sent and its classification match in terms of properties and that the classification is a valid classification.
|
|
69
|
-
|
|
70
|
-
## Includes
|
|
71
|
-
Includes were previously annotated like this:
|
|
72
|
-
```ts
|
|
73
|
-
/* __GDPR__FRAGMENT__
|
|
74
|
-
"TypeScriptCommonProperties" : {
|
|
75
|
-
"version" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
|
76
|
-
}
|
|
77
|
-
*/
|
|
78
|
-
|
|
79
|
-
/* __GDPR__
|
|
80
|
-
"tsserver.exitWithCode" : {
|
|
81
|
-
"code" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
|
|
82
|
-
"${include}": [
|
|
83
|
-
"${TypeScriptCommonProperties}"
|
|
84
|
-
]
|
|
85
|
-
}
|
|
86
|
-
*/
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
With using typings as annotations an include is effectively the extends keyword or an intersect type. The typing annotation is as follows
|
|
90
|
-
|
|
91
|
-
```ts
|
|
92
|
-
type TypeScriptCommonPropertiesClassification = {
|
|
93
|
-
version: {classification: 'SystemMetaData', purpose: 'FeatureInsight'};
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
// The intersect type signifies the include
|
|
97
|
-
type TSServeExitWithCodeClassification = {
|
|
98
|
-
code: {classification: 'CallstackOrException', purpose: 'PerformanceAndHealth'};
|
|
99
|
-
} & TypeScriptCommonPropertiesClassification;
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
The event is then given a type and sent just like the event above
|
|
103
|
-
```ts
|
|
104
|
-
interface TSServerExitCode {
|
|
105
|
-
code: number;
|
|
106
|
-
version: number;
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const tsServerEvent: TSServerExitCode = {
|
|
110
|
-
code: 0,
|
|
111
|
-
version: 3.5
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
publicLog2<TSServerExitCode, TSServeExitWithCodeClassification>('tsserver.exitWithCode', tsServerEvent);
|
|
115
|
-
publicLog2<TSServerExitCode, TSServeExitWithCodeClassification>('tsserver.exitWithCode', {code: 0, version: 3.5});
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Inlines
|
|
119
|
-
Inlines were previously annotated like so:
|
|
120
|
-
```ts
|
|
121
|
-
/* __GDPR__FRAGMENT__
|
|
122
|
-
"ExtensionIdentifier" : {
|
|
123
|
-
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
|
124
|
-
"uuid": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
|
125
|
-
}
|
|
126
|
-
*/
|
|
127
|
-
|
|
128
|
-
/* __GDPR__
|
|
129
|
-
"disableOtherKeymaps" : {
|
|
130
|
-
"newKeymap": { "${inline}": [ "${ExtensionIdentifier}" ] },
|
|
131
|
-
"oldKeymaps": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
|
132
|
-
"confirmed" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
|
133
|
-
}
|
|
134
|
-
*/
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
Inlines can be thought of as composition and therefore can be defined as a type containing another type
|
|
138
|
-
|
|
139
|
-
```ts
|
|
140
|
-
type ExtensionIdentifierClassifcation = {
|
|
141
|
-
id: {classification: 'SystemMetaData', purpose: 'FeatureInsight'};
|
|
142
|
-
uuid: {classification: 'SystemMetaData', purpose: 'FeatureInsight'};
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
type DisableOtherKeymapsClassification = {
|
|
146
|
-
newKeyMap: ExtensionIdentifierClassifcation;
|
|
147
|
-
oldKeyMaps: {classification: 'SystemMetaData', purpose: 'FeatureInsight'};
|
|
148
|
-
confirmed: {classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true};
|
|
149
|
-
};
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
The process of defining and sending the event are the same as the previous two
|
|
153
|
-
|
|
154
|
-
```ts
|
|
155
|
-
interface ExtensionIdentifier {
|
|
156
|
-
id: number;
|
|
157
|
-
uuid: number;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
interface DisableOtherKeymaps {
|
|
161
|
-
newKeyMap: ExtensionIdentifier;
|
|
162
|
-
oldKeyMaps: string;
|
|
163
|
-
confirmed: boolean;
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const extensionIdentifierFragment: ExtensionIdentifier = {
|
|
167
|
-
id: 1,
|
|
168
|
-
uuid: 1234
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
const disableKeymapsEvent: DisableOtherKeymaps = {
|
|
172
|
-
newKeyMap: extensionIdentifierFragment,
|
|
173
|
-
oldKeyMaps: 'abcd',
|
|
174
|
-
confirmed: true
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
publicLog2<DisableOtherKeymaps, DisableOtherKeymapsClassification>('disableOtherKeymaps', disableKeymapsEvent);
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## Currently Not Supported
|
|
181
|
-
|
|
182
|
-
* Wildcards
|
|
183
|
-
* Common Properties
|
|
184
|
-
* Anything else not defined above
|
|
185
|
-
|
|
186
|
-
To get around the not supported features we recommend annotating those with comments as the extractor will fall back on those provided no type annotations are provided.
|
|
187
|
-
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
# Generate Telemetry JSON Files
|
|
2
|
-
|
|
3
|
-
The inventories will be generated as `json` files. They have the following basic structure:
|
|
4
|
-
```json
|
|
5
|
-
{
|
|
6
|
-
"events": {
|
|
7
|
-
"<eventName>": {
|
|
8
|
-
"<propertyName>": {
|
|
9
|
-
"classification": "SystemMetaData",
|
|
10
|
-
"purpose": "FeatureInsight",
|
|
11
|
-
"endPoint": "none"
|
|
12
|
-
},
|
|
13
|
-
"<propertyName>": {
|
|
14
|
-
"classification": "SystemMetaData",
|
|
15
|
-
"purpose": "PerformanceAndHealth",
|
|
16
|
-
"isMeasurement": true,
|
|
17
|
-
"endPoint": "none"
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
...
|
|
21
|
-
},
|
|
22
|
-
"commonProperties": {
|
|
23
|
-
"<commonPropertyName>": {
|
|
24
|
-
"classification": "SystemMetaData",
|
|
25
|
-
"purpose": "FeatureInsight",
|
|
26
|
-
"endPoint": "none"
|
|
27
|
-
},
|
|
28
|
-
...
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Note: If the code annotations have syntax errors, the inventory generation will fail.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
## Viewing what the command has to offer
|
|
37
|
-
```bash
|
|
38
|
-
vscode-telemetry-extractor --help
|
|
39
|
-
Allows the extraction of telemetry annotation from code. For more details please read: https://github.com/microsoft/vscode-telemetry-extractor/blob/master/README.md
|
|
40
|
-
|
|
41
|
-
-s --sourceDir The folder which you want to extract telemetry from
|
|
42
|
-
-x --excludedDir A subdirectory which you would like to exclude from the extraction
|
|
43
|
-
-c --config A JSON Configuration file containing extraction details
|
|
44
|
-
-o --outputDir The directory which you would like the outputted JSON file to be placed in
|
|
45
|
-
-p --eventPrefix The string you wish to prepend to every telemetry event.
|
|
46
|
-
-h --help Displays the help dialog which provides more information on how to use the tool
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Extracting telemetry events
|
|
50
|
-
To extract telemetry events from your code you must provide a source directory and output directory.
|
|
51
|
-
The source directory is the folder containing the code which you wish to extract the events. The output directory is the location which the resulting JSON report will be placed.
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
vscode-telemetry-extractor -s PATH_TO_YOUR_CODE -o PATH_TO_PLACE_JSON
|
|
55
|
-
```
|
|
56
|
-
This will generate output similar to:
|
|
57
|
-
```bash
|
|
58
|
-
....running.
|
|
59
|
-
...extracting
|
|
60
|
-
...writing <OUTPUTDIR>/declarations-resolved.json
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Using a config file
|
|
64
|
-
The extractor also supports config files which can be passed in via a command line arguments to customize the way the tool parses.
|
|
65
|
-
An example config file can be found below. Note: `sourceDirs` and `excludedDirs` must be made relative to the `workingDir`
|
|
66
|
-
```json
|
|
67
|
-
[
|
|
68
|
-
{
|
|
69
|
-
"eventPrefix": "typescript-language-features/",
|
|
70
|
-
"workingDir": "/Users/lramos/vscode-telemetry-extractor/src/telemetry-sources",
|
|
71
|
-
"sourceDirs": [
|
|
72
|
-
"vscode/extensions/typescript-language-features",
|
|
73
|
-
"Typescript"
|
|
74
|
-
],
|
|
75
|
-
"excludedDirs": [],
|
|
76
|
-
"applyEndpoints": true
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"eventPrefix": "msjsdiag.chrome/",
|
|
80
|
-
"workingDir": "/Users/lramos/vscode-telemetry-extractor/src/telemetry-sources",
|
|
81
|
-
"sourceDirs": [
|
|
82
|
-
"vscode-chrome-debug-core",
|
|
83
|
-
"vscode-chrome-debug"
|
|
84
|
-
],
|
|
85
|
-
"excludedDirs": [],
|
|
86
|
-
"applyEndpoints": true,
|
|
87
|
-
"lowerCaseEvents": true
|
|
88
|
-
}
|
|
89
|
-
]
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Some defaults:
|
|
93
|
-
1. If no working directory is provided it will use your current working directory
|
|
94
|
-
2. `excludedDirs` defaults to an empty array
|
|
95
|
-
3. If the working directory provided is relative it must be relative to the current working directory
|
|
96
|
-
|
|
97
|
-
# Other Functionalities
|
|
98
|
-
|
|
99
|
-
## Running Tests
|
|
100
|
-
|
|
101
|
-
If you wish to make contributions to this tool, a few tests are provided to ensure there are no regressions. We also urge that you
|
|
102
|
-
add tests to ensure that any code you add doesn't break as well.
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
npm run test
|
|
106
|
-
```
|