Skip to content

Commit 9391662

Browse files
committed
feat: add telemetry commands (#7236)
* add telemetry commands * changeset * fix and test dates * update changeset * add global/project status * default true * remove changeset * update wrangler telemetry status
1 parent a30c805 commit 9391662

File tree

4 files changed

+308
-79
lines changed

4 files changed

+308
-79
lines changed

packages/wrangler/src/__tests__/metrics.test.ts

Lines changed: 205 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,18 @@ import { CI } from "../is-ci";
77
import { logger } from "../logger";
88
import { getMetricsConfig, getMetricsDispatcher } from "../metrics";
99
import {
10-
CURRENT_METRICS_DATE,
1110
readMetricsConfig,
1211
USER_ID_CACHE_PATH,
1312
writeMetricsConfig,
1413
} from "../metrics/metrics-config";
1514
import { writeAuthConfigFile } from "../user";
1615
import { mockConsoleMethods } from "./helpers/mock-console";
17-
import { clearDialogs, mockConfirm } from "./helpers/mock-dialogs";
16+
import { clearDialogs } from "./helpers/mock-dialogs";
1817
import { useMockIsTTY } from "./helpers/mock-istty";
1918
import { msw, mswSuccessOauthHandlers } from "./helpers/msw";
2019
import { runInTempDir } from "./helpers/run-in-tmp";
20+
import { runWrangler } from "./helpers/run-wrangler";
21+
import { writeWranglerToml } from "./helpers/write-wrangler-toml";
2122
import type { MockInstance } from "vitest";
2223

2324
declare const global: { SPARROW_SOURCE_KEY: string | undefined };
@@ -270,7 +271,7 @@ describe("metrics", () => {
270271
});
271272

272273
it("should return enabled true if the user on this device previously agreed to send metrics", async () => {
273-
await writeMetricsConfig({
274+
writeMetricsConfig({
274275
permission: {
275276
enabled: true,
276277
date: new Date(2022, 6, 4),
@@ -287,7 +288,7 @@ describe("metrics", () => {
287288
});
288289

289290
it("should return enabled false if the user on this device previously refused to send metrics", async () => {
290-
await writeMetricsConfig({
291+
writeMetricsConfig({
291292
permission: {
292293
enabled: false,
293294
date: new Date(2022, 6, 4),
@@ -303,49 +304,11 @@ describe("metrics", () => {
303304
});
304305
});
305306

306-
it("should accept and store permission granting to send metrics if the user agrees", async () => {
307-
mockConfirm({
308-
text: "Would you like to help improve Wrangler by sending usage metrics to Cloudflare?",
309-
result: true,
310-
});
311-
expect(
312-
await getMetricsConfig({
313-
sendMetrics: undefined,
314-
offline: false,
315-
})
316-
).toMatchObject({
317-
enabled: true,
318-
});
319-
expect((await readMetricsConfig()).permission).toMatchObject({
320-
enabled: true,
321-
});
322-
});
323-
324-
it("should accept and store permission declining to send metrics if the user declines", async () => {
325-
mockConfirm({
326-
text: "Would you like to help improve Wrangler by sending usage metrics to Cloudflare?",
327-
result: false,
328-
});
329-
expect(
330-
await getMetricsConfig({
331-
sendMetrics: undefined,
332-
offline: false,
333-
})
334-
).toMatchObject({
335-
enabled: false,
336-
});
337-
expect((await readMetricsConfig()).permission).toMatchObject({
338-
enabled: false,
339-
});
340-
});
341-
342-
it("should ignore the config if the permission date is older than the current metrics date", async () => {
343-
mockConfirm({
344-
text: "Would you like to help improve Wrangler by sending usage metrics to Cloudflare?",
345-
result: false,
346-
});
307+
it("should print a message if the permission date is older than the current metrics date", async () => {
308+
vi.useFakeTimers();
309+
vi.setSystemTime(new Date(2024, 11, 12));
347310
const OLD_DATE = new Date(2000);
348-
await writeMetricsConfig({
311+
writeMetricsConfig({
349312
permission: { enabled: true, date: OLD_DATE },
350313
});
351314
expect(
@@ -354,53 +317,48 @@ describe("metrics", () => {
354317
offline: false,
355318
})
356319
).toMatchObject({
357-
enabled: false,
320+
enabled: true,
358321
});
359-
const { permission } = await readMetricsConfig();
360-
expect(permission?.enabled).toBe(false);
322+
const { permission } = readMetricsConfig();
323+
expect(permission?.enabled).toBe(true);
361324
// The date should be updated to today's date
362-
expect(permission?.date).toEqual(CURRENT_METRICS_DATE);
325+
expect(permission?.date).toEqual(new Date(2024, 11, 12));
363326

364327
expect(std.out).toMatchInlineSnapshot(`
365-
"Usage metrics tracking has changed since you last granted permission.
366-
Your choice has been saved in the following file: test-xdg-config/metrics.json.
367-
368-
You can override the user level setting for a project in \`wrangler.toml\`:
369-
370-
- to disable sending metrics for a project: \`send_metrics = false\`
371-
- to enable sending metrics for a project: \`send_metrics = true\`"
328+
"Usage metrics tracking has changed since you last granted permission."
372329
`);
330+
vi.useRealTimers();
373331
});
374332
});
375333

376334
describe("deviceId", () => {
377335
it("should return a deviceId found in the config file", async () => {
378-
await writeMetricsConfig({ deviceId: "XXXX-YYYY-ZZZZ" });
336+
writeMetricsConfig({ deviceId: "XXXX-YYYY-ZZZZ" });
379337
const { deviceId } = await getMetricsConfig({
380338
sendMetrics: true,
381339
offline: false,
382340
});
383341
expect(deviceId).toEqual("XXXX-YYYY-ZZZZ");
384-
expect((await readMetricsConfig()).deviceId).toEqual(deviceId);
342+
expect(readMetricsConfig().deviceId).toEqual(deviceId);
385343
});
386344

387345
it("should create and store a new deviceId if none is found in the config file", async () => {
388-
await writeMetricsConfig({});
346+
writeMetricsConfig({});
389347
const { deviceId } = await getMetricsConfig({
390348
sendMetrics: true,
391349
offline: false,
392350
});
393351
expect(deviceId).toMatch(
394352
/[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}/
395353
);
396-
expect((await readMetricsConfig()).deviceId).toEqual(deviceId);
354+
expect(readMetricsConfig().deviceId).toEqual(deviceId);
397355
});
398356
});
399357

400358
describe("userId", () => {
401359
const userRequests = mockUserRequest();
402360
it("should return a userId found in a cache file", async () => {
403-
await saveToConfigCache(USER_ID_CACHE_PATH, {
361+
saveToConfigCache(USER_ID_CACHE_PATH, {
404362
userId: "CACHED_USER_ID",
405363
});
406364
const { userId } = await getMetricsConfig({
@@ -434,6 +392,191 @@ describe("metrics", () => {
434392
});
435393
});
436394
});
395+
396+
describe("telemetry commands", () => {
397+
beforeEach(() => {
398+
vi.useFakeTimers();
399+
vi.setSystemTime(new Date(2024, 11, 12));
400+
});
401+
afterEach(() => {
402+
vi.useRealTimers();
403+
});
404+
describe("wrangler telemetry status", () => {
405+
it("prints the current telemetry status based on the cached metrics config", async () => {
406+
writeMetricsConfig({
407+
permission: {
408+
enabled: true,
409+
date: new Date(2022, 6, 4),
410+
},
411+
});
412+
await runWrangler("telemetry status");
413+
expect(std.out).toMatchInlineSnapshot(`
414+
"Status: Enabled
415+
416+
To configure telemetry globally on this machine, you can run \`wrangler telemetry disable / enable\`.
417+
You can override this for individual projects with the environment variable \`WRANGLER_SEND_METRICS=true/false\`.
418+
"
419+
`);
420+
writeMetricsConfig({
421+
permission: {
422+
enabled: false,
423+
date: new Date(2022, 6, 4),
424+
},
425+
});
426+
await runWrangler("telemetry status");
427+
expect(std.out).toMatchInlineSnapshot(`
428+
"Status: Enabled
429+
430+
To configure telemetry globally on this machine, you can run \`wrangler telemetry disable / enable\`.
431+
You can override this for individual projects with the environment variable \`WRANGLER_SEND_METRICS=true/false\`.
432+
433+
Status: Disabled
434+
435+
To configure telemetry globally on this machine, you can run \`wrangler telemetry disable / enable\`.
436+
You can override this for individual projects with the environment variable \`WRANGLER_SEND_METRICS=true/false\`.
437+
"
438+
`);
439+
});
440+
441+
it("shows wrangler.toml as the source with send_metrics is present", async () => {
442+
writeMetricsConfig({
443+
permission: {
444+
enabled: true,
445+
date: new Date(2022, 6, 4),
446+
},
447+
});
448+
writeWranglerToml({ send_metrics: false });
449+
await runWrangler("telemetry status");
450+
expect(std.out).toMatchInlineSnapshot(`
451+
"Status: Disabled (set by wrangler.toml)
452+
453+
To configure telemetry globally on this machine, you can run \`wrangler telemetry disable / enable\`.
454+
You can override this for individual projects with the environment variable \`WRANGLER_SEND_METRICS=true/false\`.
455+
"
456+
`);
457+
});
458+
459+
it("shows environment variable as the source if used", async () => {
460+
writeMetricsConfig({
461+
permission: {
462+
enabled: true,
463+
date: new Date(2022, 6, 4),
464+
},
465+
});
466+
vi.stubEnv("WRANGLER_SEND_METRICS", "false");
467+
await runWrangler("telemetry status");
468+
expect(std.out).toMatchInlineSnapshot(`
469+
"Status: Disabled (set by environment variable)
470+
471+
To configure telemetry globally on this machine, you can run \`wrangler telemetry disable / enable\`.
472+
You can override this for individual projects with the environment variable \`WRANGLER_SEND_METRICS=true/false\`.
473+
"
474+
`);
475+
});
476+
477+
it("defaults to enabled if metrics config is not set", async () => {
478+
writeMetricsConfig({});
479+
await runWrangler("telemetry status");
480+
expect(std.out).toMatchInlineSnapshot(`
481+
"Status: Enabled
482+
483+
To configure telemetry globally on this machine, you can run \`wrangler telemetry disable / enable\`.
484+
You can override this for individual projects with the environment variable \`WRANGLER_SEND_METRICS=true/false\`.
485+
"
486+
`);
487+
});
488+
489+
it("prioritises environment variable over send_metrics", async () => {
490+
writeMetricsConfig({
491+
permission: {
492+
enabled: true,
493+
date: new Date(2022, 6, 4),
494+
},
495+
});
496+
writeWranglerToml({ send_metrics: true });
497+
vi.stubEnv("WRANGLER_SEND_METRICS", "false");
498+
await runWrangler("telemetry status");
499+
expect(std.out).toMatchInlineSnapshot(`
500+
"Status: Disabled (set by environment variable)
501+
502+
To configure telemetry globally on this machine, you can run \`wrangler telemetry disable / enable\`.
503+
You can override this for individual projects with the environment variable \`WRANGLER_SEND_METRICS=true/false\`.
504+
"
505+
`);
506+
});
507+
});
508+
509+
it("disables telemetry when `wrangler telemetry disable` is run", async () => {
510+
writeMetricsConfig({
511+
permission: {
512+
enabled: true,
513+
date: new Date(2022, 6, 4),
514+
},
515+
});
516+
await runWrangler("telemetry disable");
517+
expect(std.out).toMatchInlineSnapshot(`
518+
"Status: Disabled
519+
520+
Wrangler is no longer collecting telemetry about your usage.
521+
"
522+
`);
523+
expect(readMetricsConfig()).toMatchObject({
524+
permission: {
525+
enabled: false,
526+
date: new Date(2024, 11, 12),
527+
},
528+
});
529+
});
530+
531+
it("enables telemetry when `wrangler telemetry enable` is run", async () => {
532+
writeMetricsConfig({
533+
permission: {
534+
enabled: false,
535+
date: new Date(2022, 6, 4),
536+
},
537+
});
538+
await runWrangler("telemetry enable");
539+
expect(std.out).toMatchInlineSnapshot(`
540+
"Status: Enabled
541+
542+
Wrangler is now collecting telemetry about your usage. Thank you for helping make Wrangler better 🧡
543+
"
544+
`);
545+
expect(readMetricsConfig()).toMatchObject({
546+
permission: {
547+
enabled: true,
548+
date: new Date(2024, 11, 12),
549+
},
550+
});
551+
});
552+
553+
it("doesn't overwrite c3 telemetry config", async () => {
554+
writeMetricsConfig({
555+
c3permission: {
556+
enabled: false,
557+
date: new Date(2022, 6, 4),
558+
},
559+
});
560+
await runWrangler("telemetry enable");
561+
expect(std.out).toMatchInlineSnapshot(`
562+
"Status: Enabled
563+
564+
Wrangler is now collecting telemetry about your usage. Thank you for helping make Wrangler better 🧡
565+
"
566+
`);
567+
const config = readMetricsConfig();
568+
expect(config).toMatchObject({
569+
c3permission: {
570+
enabled: false,
571+
date: new Date(2022, 6, 4),
572+
},
573+
permission: {
574+
enabled: true,
575+
date: new Date(2024, 11, 12),
576+
},
577+
});
578+
});
579+
});
437580
});
438581

439582
function mockUserRequest() {

packages/wrangler/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import "./dev";
4949
import "./kv";
5050
import "./workflows";
5151
import "./user/commands";
52+
import "./metrics/commands";
5253
import { demandSingleValue } from "./core";
5354
import { logBuildFailure, logger, LOGGER_LEVELS } from "./logger";
5455
import { mTlsCertificateCommands } from "./mtls-certificate/cli";
@@ -584,6 +585,7 @@ export function createCLIParser(argv: string[]) {
584585
register.registerNamespace("login");
585586
register.registerNamespace("logout");
586587
register.registerNamespace("whoami");
588+
register.registerNamespace("telemetry");
587589

588590
/******************************************************/
589591
/* DEPRECATED COMMANDS */

0 commit comments

Comments
 (0)