1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.TelemetryManager = exports.MetricName = void 0;
|
4 | const tslib_1 = require("tslib");
|
5 | const fslib_1 = require("@yarnpkg/fslib");
|
6 | const httpUtils = tslib_1.__importStar(require("./httpUtils"));
|
7 | const miscUtils = tslib_1.__importStar(require("./miscUtils"));
|
8 | var MetricName;
|
9 | (function (MetricName) {
|
10 | MetricName["VERSION"] = "version";
|
11 | MetricName["COMMAND_NAME"] = "commandName";
|
12 | MetricName["PLUGIN_NAME"] = "pluginName";
|
13 | MetricName["INSTALL_COUNT"] = "installCount";
|
14 | MetricName["PROJECT_COUNT"] = "projectCount";
|
15 | MetricName["WORKSPACE_COUNT"] = "workspaceCount";
|
16 | MetricName["DEPENDENCY_COUNT"] = "dependencyCount";
|
17 | MetricName["EXTENSION"] = "packageExtension";
|
18 | })(MetricName = exports.MetricName || (exports.MetricName = {}));
|
19 | class TelemetryManager {
|
20 | constructor(configuration, accountId) {
|
21 | this.values = new Map();
|
22 | this.hits = new Map();
|
23 | this.enumerators = new Map();
|
24 | this.configuration = configuration;
|
25 | const registryFile = this.getRegistryPath();
|
26 | this.isNew = !fslib_1.xfs.existsSync(registryFile);
|
27 | this.sendReport(accountId);
|
28 | this.startBuffer();
|
29 | }
|
30 | reportVersion(value) {
|
31 | this.reportValue(MetricName.VERSION, value);
|
32 | }
|
33 | reportCommandName(value) {
|
34 | this.reportValue(MetricName.COMMAND_NAME, value || `<none>`);
|
35 | }
|
36 | reportPluginName(value) {
|
37 | this.reportValue(MetricName.PLUGIN_NAME, value);
|
38 | }
|
39 | reportProject(cwd) {
|
40 | this.reportEnumerator(MetricName.PROJECT_COUNT, cwd);
|
41 | }
|
42 | reportInstall(nodeLinker) {
|
43 | this.reportHit(MetricName.INSTALL_COUNT, nodeLinker);
|
44 | }
|
45 | reportPackageExtension(value) {
|
46 | this.reportValue(MetricName.EXTENSION, value);
|
47 | }
|
48 | reportWorkspaceCount(count) {
|
49 | this.reportValue(MetricName.WORKSPACE_COUNT, String(count));
|
50 | }
|
51 | reportDependencyCount(count) {
|
52 | this.reportValue(MetricName.DEPENDENCY_COUNT, String(count));
|
53 | }
|
54 | reportValue(metric, value) {
|
55 | miscUtils.getSetWithDefault(this.values, metric).add(value);
|
56 | }
|
57 | reportEnumerator(metric, value) {
|
58 | miscUtils.getSetWithDefault(this.enumerators, metric).add(value);
|
59 | }
|
60 | reportHit(metric, extra = `*`) {
|
61 | const ns = miscUtils.getMapWithDefault(this.hits, metric);
|
62 | const current = miscUtils.getFactoryWithDefault(ns, extra, () => 0);
|
63 | ns.set(extra, current + 1);
|
64 | }
|
65 | getRegistryPath() {
|
66 | const registryFile = this.configuration.get(`globalFolder`);
|
67 | return fslib_1.ppath.join(registryFile, `telemetry.json`);
|
68 | }
|
69 | sendReport(accountId) {
|
70 | var _a, _b, _c;
|
71 | const registryFile = this.getRegistryPath();
|
72 | let content;
|
73 | try {
|
74 | content = fslib_1.xfs.readJsonSync(registryFile);
|
75 | }
|
76 | catch (_d) {
|
77 | content = {};
|
78 | }
|
79 | const now = Date.now();
|
80 | const interval = this.configuration.get(`telemetryInterval`) * 24 * 60 * 60 * 1000;
|
81 | const lastUpdate = (_a = content.lastUpdate) !== null && _a !== void 0 ? _a : now + interval + Math.floor(interval * Math.random());
|
82 | const nextUpdate = lastUpdate + interval;
|
83 | if (nextUpdate > now && content.lastUpdate != null)
|
84 | return;
|
85 | try {
|
86 | fslib_1.xfs.mkdirSync(fslib_1.ppath.dirname(registryFile), { recursive: true });
|
87 | fslib_1.xfs.writeJsonSync(registryFile, { lastUpdate: now });
|
88 | }
|
89 | catch (_e) {
|
90 |
|
91 | return;
|
92 | }
|
93 | if (nextUpdate > now)
|
94 | return;
|
95 | if (!content.blocks)
|
96 | return;
|
97 | for (const [userId, block] of Object.entries((_b = content.blocks) !== null && _b !== void 0 ? _b : {})) {
|
98 | if (Object.keys(block).length === 0)
|
99 | continue;
|
100 | const upload = block;
|
101 | upload.userId = userId;
|
102 | for (const key of Object.keys((_c = upload.enumerators) !== null && _c !== void 0 ? _c : {}))
|
103 | upload.enumerators[key] = upload.enumerators[key].length;
|
104 | const rawUrl = `https://browser-http-intake.logs.datadoghq.eu/v1/input/${accountId}?ddsource=yarn`;
|
105 | httpUtils.post(rawUrl, upload, {
|
106 | configuration: this.configuration,
|
107 | }).catch(() => {
|
108 |
|
109 | });
|
110 | }
|
111 | }
|
112 | applyChanges() {
|
113 | var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
114 | const registryFile = this.getRegistryPath();
|
115 | let content;
|
116 | try {
|
117 | content = fslib_1.xfs.readJsonSync(registryFile);
|
118 | }
|
119 | catch (_k) {
|
120 | content = {};
|
121 | }
|
122 | const userId = (_a = this.configuration.get(`telemetryUserId`)) !== null && _a !== void 0 ? _a : `*`;
|
123 | const blocks = content.blocks = (_b = content.blocks) !== null && _b !== void 0 ? _b : {};
|
124 | const block = blocks[userId] = (_c = blocks[userId]) !== null && _c !== void 0 ? _c : {};
|
125 | for (const key of this.hits.keys()) {
|
126 | const store = block.hits = (_d = block.hits) !== null && _d !== void 0 ? _d : {};
|
127 | const ns = store[key] = (_e = store[key]) !== null && _e !== void 0 ? _e : {};
|
128 | for (const [extra, value] of this.hits.get(key)) {
|
129 | ns[extra] = ((_f = ns[extra]) !== null && _f !== void 0 ? _f : 0) + value;
|
130 | }
|
131 | }
|
132 | for (const field of [`values`, `enumerators`]) {
|
133 | for (const key of this[field].keys()) {
|
134 | const store = block[field] = (_g = block[field]) !== null && _g !== void 0 ? _g : {};
|
135 | store[key] = [...new Set([
|
136 | ...(_h = store[key]) !== null && _h !== void 0 ? _h : [],
|
137 | ...(_j = this[field].get(key)) !== null && _j !== void 0 ? _j : [],
|
138 | ])];
|
139 | }
|
140 | }
|
141 | fslib_1.xfs.mkdirSync(fslib_1.ppath.dirname(registryFile), { recursive: true });
|
142 | fslib_1.xfs.writeJsonSync(registryFile, content);
|
143 | }
|
144 | startBuffer() {
|
145 | process.on(`exit`, () => {
|
146 | try {
|
147 | this.applyChanges();
|
148 | }
|
149 | catch (_a) {
|
150 |
|
151 | }
|
152 | });
|
153 | }
|
154 | }
|
155 | exports.TelemetryManager = TelemetryManager;
|