Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
1 line
8.0 KiB
Plaintext
1 line
8.0 KiB
Plaintext
{"version":3,"file":"vercelCronsMonitoring.js","sources":["../../../src/server/vercelCronsMonitoring.ts"],"sourcesContent":["import type { Span } from '@sentry/core';\nimport { _INTERNAL_safeDateNow, captureCheckIn, debug, getIsolationScope, spanToJSON } from '@sentry/core';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport type { VercelCronsConfig } from '../common/types';\n\n// Attribute keys for storing cron check-in data on spans\nconst ATTR_SENTRY_CRON_CHECK_IN_ID = 'sentry.cron.checkInId';\nconst ATTR_SENTRY_CRON_MONITOR_SLUG = 'sentry.cron.monitorSlug';\nconst ATTR_SENTRY_CRON_START_TIME = 'sentry.cron.startTime';\nconst ATTR_SENTRY_CRON_SCHEDULE = 'sentry.cron.schedule';\n\n/**\n * Gets the Vercel crons configuration that was injected at build time.\n */\nfunction getVercelCronsConfig(): VercelCronsConfig {\n const globalWithCronsConfig = globalThis as typeof globalThis & {\n _sentryVercelCronsConfig?: string;\n };\n\n if (!globalWithCronsConfig._sentryVercelCronsConfig) {\n return undefined;\n }\n\n try {\n return JSON.parse(globalWithCronsConfig._sentryVercelCronsConfig) as VercelCronsConfig;\n } catch {\n DEBUG_BUILD && debug.log('[@sentry/nextjs] Failed to parse Vercel crons config');\n return undefined;\n }\n}\n\n/**\n * Checks if the request is a Vercel cron request and starts a check-in if it matches a configured cron.\n */\nexport function maybeStartCronCheckIn(span: Span, route: string | undefined): void {\n const vercelCronsConfig = getVercelCronsConfig();\n if (!vercelCronsConfig || !route) {\n return;\n }\n\n // The strategy here is to check if the request is a Vercel cron\n // request by checking the user agent, vercel always sets the user agent to 'vercel-cron/1.0'\n\n const headers = getIsolationScope().getScopeData().sdkProcessingMetadata?.normalizedRequest?.headers as\n | Record<string, string | string[] | undefined>\n | undefined;\n\n if (!headers) {\n return;\n }\n\n const userAgent = Array.isArray(headers['user-agent']) ? headers['user-agent'][0] : headers['user-agent'];\n if (!userAgent?.includes('vercel-cron')) {\n return;\n }\n\n const matchedCron = vercelCronsConfig.find(cron => cron.path === route);\n if (!matchedCron?.path || !matchedCron.schedule) {\n return;\n }\n\n // Use raw path as monitor slug to match legacy wrapApiHandlerWithSentryVercelCrons behavior,\n // so migration from automaticVercelMonitors to vercelCronsMonitoring keeps the same monitors.\n const monitorSlug = matchedCron.path;\n const startTime = _INTERNAL_safeDateNow() / 1000;\n\n const checkInId = captureCheckIn(\n { monitorSlug, status: 'in_progress' },\n {\n maxRuntime: 60 * 12,\n schedule: { type: 'crontab', value: matchedCron.schedule },\n },\n );\n\n DEBUG_BUILD && debug.log(`[Cron] Started check-in for \"${monitorSlug}\" with ID \"${checkInId}\"`);\n\n // Store marking attributes on the span so we can complete the check-in later\n span.setAttribute(ATTR_SENTRY_CRON_CHECK_IN_ID, checkInId);\n span.setAttribute(ATTR_SENTRY_CRON_MONITOR_SLUG, monitorSlug);\n span.setAttribute(ATTR_SENTRY_CRON_START_TIME, startTime);\n span.setAttribute(ATTR_SENTRY_CRON_SCHEDULE, matchedCron.schedule);\n}\n\n/**\n * Completes a Vercel cron check-in when a span ends.\n * Should be called from the spanEnd event handler.\n */\nexport function maybeCompleteCronCheckIn(span: Span): void {\n const spanData = spanToJSON(span).data;\n const checkInId = spanData?.[ATTR_SENTRY_CRON_CHECK_IN_ID];\n const monitorSlug = spanData?.[ATTR_SENTRY_CRON_MONITOR_SLUG];\n const startTime = spanData?.[ATTR_SENTRY_CRON_START_TIME];\n const schedule = spanData?.[ATTR_SENTRY_CRON_SCHEDULE];\n\n if (!checkInId || !monitorSlug || typeof startTime !== 'number') {\n return;\n }\n\n const duration = _INTERNAL_safeDateNow() / 1000 - startTime;\n const spanStatus = spanToJSON(span).status;\n // Span status is 'ok' for success, undefined for unset, or an error message like 'internal_error'\n const checkInStatus = spanStatus && spanStatus !== 'ok' ? 'error' : 'ok';\n\n // Include monitor_config for upsert in case the in_progress check-in was lost\n const monitorConfig =\n typeof schedule === 'string'\n ? {\n maxRuntime: 60 * 12,\n schedule: { type: 'crontab' as const, value: schedule },\n }\n : undefined;\n\n captureCheckIn(\n {\n checkInId: checkInId as string,\n monitorSlug: monitorSlug as string,\n status: checkInStatus,\n duration,\n },\n monitorConfig,\n );\n\n // Cleanup marking attributes so they don't pollute user span data\n span.setAttribute(ATTR_SENTRY_CRON_CHECK_IN_ID, undefined);\n span.setAttribute(ATTR_SENTRY_CRON_MONITOR_SLUG, undefined);\n span.setAttribute(ATTR_SENTRY_CRON_START_TIME, undefined);\n span.setAttribute(ATTR_SENTRY_CRON_SCHEDULE, undefined);\n\n DEBUG_BUILD && debug.log(`[Cron] Completed check-in for \"${monitorSlug}\" with status \"${checkInStatus}\"`);\n}\n"],"names":["DEBUG_BUILD","debug","getIsolationScope","_INTERNAL_safeDateNow","captureCheckIn","spanToJSON"],"mappings":"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"} |