Skip to content

Commit

Permalink
Initial sentry implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
penalosa committed Dec 8, 2023
1 parent 70f634c commit fdc2486
Show file tree
Hide file tree
Showing 13 changed files with 300 additions and 37 deletions.
1 change: 1 addition & 0 deletions .github/workflows/create-pullrequest-prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ jobs:
NODE_ENV: "production"
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
ALGOLIA_PUBLIC_KEY: ${{ secrets.ALGOLIA_PUBLIC_KEY }}
SENTRY_DSN: "https://9edbb8417b284aa2bbead9b4c318918b@sentry10.cfdata.org/583"
CI_OS: ${{ runner.os }}

- name: Pack miniflare
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/prereleases.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ jobs:
# this is the "test/staging" key for sparrow analytics
SPARROW_SOURCE_KEY: "5adf183f94b3436ba78d67f506965998"
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
SENTRY_DSN: "https://9edbb8417b284aa2bbead9b4c318918b@sentry10.cfdata.org/583"
ALGOLIA_PUBLIC_KEY: ${{ secrets.ALGOLIA_PUBLIC_KEY }}
working-directory: packages/wrangler

Expand Down Expand Up @@ -111,6 +112,7 @@ jobs:
NODE_ENV: "production"
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
ALGOLIA_PUBLIC_KEY: ${{ secrets.ALGOLIA_PUBLIC_KEY }}
SENTRY_DSN: "https://9edbb8417b284aa2bbead9b4c318918b@sentry10.cfdata.org/583"
CI_OS: ${{ runner.os }}

- name: Build & Publish Prerelease Registry
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ jobs:
NPM_PUBLISH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
ALGOLIA_PUBLIC_KEY: ${{ secrets.ALGOLIA_PUBLIC_KEY }}
SENTRY_DSN: "https://9edbb8417b284aa2bbead9b4c318918b@sentry10.cfdata.org/583"

NODE_ENV: "production"
# This is the "production" key for sparrow analytics.
# Include this here because this step will rebuild Wrangler and needs to have this available
Expand Down
5 changes: 4 additions & 1 deletion packages/wrangler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,12 @@
"@cloudflare/pages-shared": "workspace:^",
"@cloudflare/types": "^6.18.4",
"@cloudflare/workers-tsconfig": "workspace:*",
"https-proxy-agent": "7.0.2",
"@cloudflare/workers-types": "^4.20230914.0",
"@iarna/toml": "^3.0.0",
"@microsoft/api-extractor": "^7.28.3",
"@sentry/node": "^7.86.0",
"@sentry/types": "^7.86.0",
"@sentry/utils": "^7.86.0",
"@types/body-parser": "^1.19.2",
"@types/busboy": "^1.5.0",
"@types/command-exists": "^1.2.0",
Expand Down Expand Up @@ -164,6 +166,7 @@
"get-port": "^6.1.2",
"glob-to-regexp": "0.4.1",
"http-terminator": "^3.2.0",
"https-proxy-agent": "7.0.2",
"ignore": "^5.2.0",
"ink": "^3.2.0",
"ink-select-input": "^4.2.1",
Expand Down
3 changes: 3 additions & 0 deletions packages/wrangler/scripts/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ async function buildMain(flags: BuildFlags = {}) {
...(process.env.ALGOLIA_PUBLIC_KEY
? { ALGOLIA_PUBLIC_KEY: `"${process.env.ALGOLIA_PUBLIC_KEY}"` }
: {}),
...(process.env.SENTRY_DSN
? { SENTRY_DSN: `"${process.env.SENTRY_DSN}"` }
: {}),
},
plugins: [embedWorkersPlugin],
};
Expand Down
1 change: 1 addition & 0 deletions packages/wrangler/src/api/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ export async function unstable_dev(
logLevel: options?.logLevel ?? defaultLogLevel,
port: options?.port ?? 0,
updateCheck: options?.updateCheck ?? false,
metricsOptOut: undefined,
};

//due to Pages adoption of unstable_dev, we can't *just* disable rebuilds and watching. instead, we'll have two versions of startDev, which will converge.
Expand Down
1 change: 1 addition & 0 deletions packages/wrangler/src/generate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export async function generateHandler(args: GenerateArgs) {
_: args._,
$0: args.$0,
experimentalJsonConfig: false,
metricsOptOut: undefined,
});
}

Expand Down
61 changes: 61 additions & 0 deletions packages/wrangler/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import module from "node:module";
import os from "node:os";
import path from "node:path";
import TOML from "@iarna/toml";
import chalk from "chalk";
import { ProxyAgent, setGlobalDispatcher } from "undici";
import makeCLI from "yargs";
import { version as wranglerVersion } from "../package.json";
Expand Down Expand Up @@ -39,13 +41,24 @@ import { initHandler, initOptions } from "./init";
import { kvNamespace, kvKey, kvBulk } from "./kv";
import { logBuildFailure, logger } from "./logger";
import * as metrics from "./metrics";
import {
CURRENT_METRICS_DATE,
getMetricsConfigPath,
writeMetricsConfig,
} from "./metrics/metrics-config";
import { mTlsCertificateCommands } from "./mtls-certificate/cli";
import { pages } from "./pages";
import { formatMessage, ParseError } from "./parse";
import { pubSubCommands } from "./pubsub/pubsub-commands";
import { queues } from "./queues/cli/commands";
import { r2 } from "./r2";
import { secret, secretBulkHandler, secretBulkOptions } from "./secret";
import {
captureGlobalException,
captureWranglerCommand,
closeSentry,
setupSentry,
} from "./sentry";
import { tailOptions, tailHandler } from "./tail";
import { generateTypes } from "./type-generation";
import { printWranglerBanner } from "./update-check";
Expand All @@ -54,6 +67,7 @@ import { vectorize } from "./vectorize/index";
import { whoami } from "./whoami";

import type { Config } from "./config";
import type { OnlyCamelCase } from "./config/config";
import type { CommonYargsArgv, CommonYargsOptions } from "./yargs-types";
import type Yargs from "yargs";

Expand Down Expand Up @@ -201,6 +215,11 @@ export function createCLIParser(argv: string[]) {
describe: `Experimental: Support wrangler.json`,
type: "boolean",
})
.option("metrics-opt-out", {
describe: `Opt out of crash reports & usage metrics, and remember the choice`,
type: "boolean",
hidden: true,
})
.check((args) => {
// Grab locally specified env params from `.env` file
const loaded = loadDotEnv(".env", args.env);
Expand Down Expand Up @@ -242,6 +261,24 @@ export function createCLIParser(argv: string[]) {
} else {
logger.log(wranglerVersion);
}
} else if (args.metricsOptOut) {
await writeMetricsConfig({
permission: {
enabled: !args.metricsOptOut,
date: CURRENT_METRICS_DATE,
},
});
logger.log(
`${chalk.green(
"Successfully opted out of metrics collection"
)}.\nYour choice has been saved in the following file: ${path.relative(
process.cwd(),
getMetricsConfigPath()
)}.\n\n` +
" You can override the user level setting for a project in `wrangler.toml`:\n\n" +
" - to disable sending metrics for a project: `send_metrics = false`\n" +
" - to enable sending metrics for a project: `send_metrics = true`"
);
} else {
wrangler.showHelp("log");
}
Expand Down Expand Up @@ -700,11 +737,32 @@ export function createCLIParser(argv: string[]) {
return wrangler;
}

export function createConfigArgParser(argv: string[]) {
return makeCLI(argv)
.scriptName("wrangler")

.option("config", {
alias: "c",
describe: "Path to .toml configuration file",
type: "string",
requiresArg: true,
});
}
export async function main(argv: string[]): Promise<void> {
setupSentry();
captureWranglerCommand(argv);

const wrangler = createCLIParser(argv);
try {
await wrangler.parse();
} catch (e) {
const configParser = createConfigArgParser(argv);
const parsed = await configParser.argv;
const config = readConfig(
parsed.config,
{} as OnlyCamelCase<CommonYargsOptions>
);

logger.log(""); // Just adds a bit of space
if (e instanceof CommandLineArgsError) {
logger.error(e.message);
Expand All @@ -720,6 +778,7 @@ export async function main(argv: string[]): Promise<void> {
text: "\nIf you think this is a bug, please open an issue at: https://github.com/cloudflare/workers-sdk/issues/new/choose",
});
logger.log(formatMessage(e));
await captureGlobalException(e, config.send_metrics);
} else if (
e instanceof Error &&
e.message.includes("Raw mode is not supported on")
Expand Down Expand Up @@ -755,9 +814,11 @@ export async function main(argv: string[]): Promise<void> {
`${fgGreenColor}%s${resetColor}`,
"If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose"
);
await captureGlobalException(e, config.send_metrics);
}
throw e;
} finally {
await closeSentry();
// In the bootstrapper script `bin/wrangler.js`, we open an IPC channel, so
// IPC messages from this process are propagated through the bootstrapper.
// Make sure this channel is closed once it's no longer needed, so we can
Expand Down
49 changes: 29 additions & 20 deletions packages/wrangler/src/metrics/metrics-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { getAPIToken } from "../user";
* This allows us to prompt the user to re-opt-in when we make substantive changes to our metrics
* gathering.
*/
export const CURRENT_METRICS_DATE = new Date(2022, 6, 4);
export const CURRENT_METRICS_DATE = new Date(2023, 12, 8);
export const USER_ID_CACHE_PATH = "user-id.json";

export const getWranglerSendMetricsFromEnv = getEnvironmentVariableFactory({
Expand Down Expand Up @@ -100,7 +100,7 @@ export async function getMetricsConfig({
return { enabled: permission.enabled, deviceId, userId };
} else if (permission.enabled) {
logger.log(
"Usage metrics tracking has changed since you last granted permission."
"Usage metrics & crash reporting has changed since you last granted permission."
);
}
}
Expand All @@ -113,24 +113,33 @@ export async function getMetricsConfig({

// Otherwise, let's ask the user and store the result in the metrics config.
const enabled = await confirm(
"Would you like to help improve Wrangler by sending usage metrics to Cloudflare?"
"Would you like to help improve Wrangler by automatically sending crash reports & usage metrics to Cloudflare?"
);
logger.log(
`Your choice has been saved in the following file: ${path.relative(
process.cwd(),
getMetricsConfigPath()
)}.\n\n` +
" You can override the user level setting for a project in `wrangler.toml`:\n\n" +
" - to disable sending metrics for a project: `send_metrics = false`\n" +
" - to enable sending metrics for a project: `send_metrics = true`"
);
writeMetricsConfig({
permission: {
enabled,
date: CURRENT_METRICS_DATE,
},
deviceId,
});
if (enabled) {
logger.log(
`Your choice has been saved in the following file: ${path.relative(
process.cwd(),
getMetricsConfigPath()
)}.\n\n` +
" You can override the user level setting for a project in `wrangler.toml`:\n\n" +
" - to disable sending metrics for a project: `send_metrics = false`\n" +
" - to enable sending metrics for a project: `send_metrics = true`"
);
writeMetricsConfig({
permission: {
enabled,
date: CURRENT_METRICS_DATE,
},
deviceId,
});
} else {
logger.log(
"Not sending crash reports or usage metrics to Cloudflare. For Wrangler to remember this choice, run `wrangler --metrics-opt-out`.\n\n" +
" You can override the user level setting for a project in `wrangler.toml`:\n\n" +
" - to disable sending metrics for a project: `send_metrics = false`\n" +
" - to enable sending metrics for a project: `send_metrics = true`"
);
}
return { enabled, deviceId, userId };
}

Expand Down Expand Up @@ -166,7 +175,7 @@ export function readMetricsConfig(): MetricsConfigFile {
/**
* Get the path to the metrics config file.
*/
function getMetricsConfigPath(): string {
export function getMetricsConfigPath(): string {
return path.resolve(getGlobalWranglerConfigPath(), "metrics.json");
}

Expand Down
Loading

0 comments on commit fdc2486

Please sign in to comment.