From d68d71b3899c83dcb29ff8d9df160d7c83c0c2ff Mon Sep 17 00:00:00 2001 From: Sarah Shader Date: Mon, 18 Nov 2024 10:43:49 -0500 Subject: [PATCH] Hook up sentry reporting for local deployments (#31478) While we're rolling out dev with local deployments and trying to identify bugs, it'll be helpful to be able to see any errors that the local backend hits (similar to being able to see errors hit by `npx convex dev` and similar from cloud deployments). This change makes it so that `npx convex dev --local` reports errors from the local backend to one of our Sentry projects -- alpha testing instructions will be updated to make this clear. We'll make this reporting opt in or at least configurable before releasing more broadly. This makes it so that local backend can generally be configured to report errors (I think we weren't calling `sentry::init` anywhere before), but only if there's a `SENTRY_DSN` env var provided. GitOrigin-RevId: f08666117de00545e3ef755fb682fdf15964f065 --- src/cli/index.ts | 26 +++----------------------- src/cli/lib/localDeployment/run.ts | 16 ++++++++++++++-- src/cli/lib/utils/sentry.ts | 25 +++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 25 deletions(-) create mode 100644 src/cli/lib/utils/sentry.ts diff --git a/src/cli/index.ts b/src/cli/index.ts index 0c6cad6..de8f47b 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -14,15 +14,13 @@ import { login } from "./login.js"; import { logout } from "./logout.js"; import chalk from "chalk"; import * as Sentry from "@sentry/node"; -import "@sentry/tracing"; -import stripAnsi from "strip-ansi"; -import { productionProvisionHost, provisionHost } from "./lib/config.js"; -import { convexImport } from "./convexImport.js"; +import { initSentry } from "./lib/utils/sentry.js"; import { dev } from "./dev.js"; import { deploy } from "./deploy.js"; import { logs } from "./logs.js"; import { networkTest } from "./network_test.js"; import { convexExport } from "./convexExport.js"; +import { convexImport } from "./convexImport.js"; import { env } from "./env.js"; import { data } from "./data.js"; import inquirer from "inquirer"; @@ -40,28 +38,10 @@ function logToStderr(...args: unknown[]) { } async function main() { - // If you want to use `@sentry/tracing` in your project directly, use a named import instead: - // import * as SentryTracing from "@sentry/tracing" - // Unused named imports are not guaranteed to patch the global hub. - // Use ipv4 first for 127.0.0.1 in tests dns.setDefaultResultOrder("ipv4first"); - if (!process.env.CI && provisionHost === productionProvisionHost) { - Sentry.init({ - dsn: "https://f9fa0306e3d540079cf40ce8c2ad9644@o1192621.ingest.sentry.io/6390839", - release: "cli@" + version, - tracesSampleRate: 0.2, - beforeBreadcrumb: (breadcrumb) => { - // Strip ANSI color codes from log lines that are sent as breadcrumbs. - if (breadcrumb.message) { - breadcrumb.message = stripAnsi(breadcrumb.message); - } - return breadcrumb; - }, - }); - } - + initSentry(); inquirer.registerPrompt("search-list", inquirerSearchList); const nodeVersion = process.versions.node; diff --git a/src/cli/lib/localDeployment/run.ts b/src/cli/lib/localDeployment/run.ts index c24e3e3..c61a1c4 100644 --- a/src/cli/lib/localDeployment/run.ts +++ b/src/cli/lib/localDeployment/run.ts @@ -13,7 +13,8 @@ import { promisify } from "util"; import { Readable } from "stream"; import { nodeFs } from "../../../bundler/fs.js"; import detect from "detect-port"; - +import { SENTRY_DSN } from "../utils/sentry.js"; +import { createHash } from "crypto"; const LOCAL_BACKEND_INSTANCE_SECRET = "4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974"; @@ -137,11 +138,16 @@ export async function runLocalBackend( const { ports } = args; const deploymentDir = deploymentStateDir(args.deploymentName); ctx.fs.mkdir(deploymentDir, { recursive: true }); + const deploymentNameSha = createHash("sha256") + .update(args.deploymentName) + .digest("hex"); const commandArgs = [ "--port", ports.cloud.toString(), "--site-proxy-port", ports.site.toString(), + "--sentry-identifier", + deploymentNameSha, "--instance-name", args.deploymentName, "--instance-secret", @@ -153,7 +159,13 @@ export async function runLocalBackend( const commandStr = `${args.binaryPath} ${commandArgs.join(" ")}`; logVerbose(ctx, `Starting local backend: \`${commandStr}\``); const p = child_process - .spawn(args.binaryPath, commandArgs, { stdio: "ignore" }) + .spawn(args.binaryPath, commandArgs, { + stdio: "ignore", + env: { + ...process.env, + SENTRY_DSN: SENTRY_DSN, + }, + }) .on("exit", (code) => { logVerbose( ctx, diff --git a/src/cli/lib/utils/sentry.ts b/src/cli/lib/utils/sentry.ts new file mode 100644 index 0000000..a931390 --- /dev/null +++ b/src/cli/lib/utils/sentry.ts @@ -0,0 +1,25 @@ +import "@sentry/tracing"; +import { productionProvisionHost, provisionHost } from "../config.js"; +import stripAnsi from "strip-ansi"; +import * as Sentry from "@sentry/node"; +import { version } from "../../../index.js"; + +export const SENTRY_DSN = + "https://f9fa0306e3d540079cf40ce8c2ad9644@o1192621.ingest.sentry.io/6390839"; + +export function initSentry() { + if (!process.env.CI && provisionHost === productionProvisionHost) { + Sentry.init({ + dsn: SENTRY_DSN, + release: "cli@" + version, + tracesSampleRate: 0.2, + beforeBreadcrumb: (breadcrumb) => { + // Strip ANSI color codes from log lines that are sent as breadcrumbs. + if (breadcrumb.message) { + breadcrumb.message = stripAnsi(breadcrumb.message); + } + return breadcrumb; + }, + }); + } +}