Repository navigation
feat(nestjs): Add an option to monitor every @Cron method #25471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
wedamija
wants to merge
20
commits into
develop
Choose a base branch
from
danf/nestjs-cron-auto-monitor
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
5833c8f
feat(nestjs): Derive SentryCron monitor config from @Cron
wedamija 20a2edd
ref(nestjs): Make deriving the SentryCron config from @Cron opt-in
wedamija 2bd91a3
feat(nestjs): Send the @Cron schedule from SentryCron by default
wedamija 3c1da94
feat(nestjs): Send @Cron presets and warn when no config is derived
wedamija 6413911
fix(nestjs): Only send @Cron schedules Sentry reads the same way
wedamija 8cd5e98
fix(nestjs): Send @Cron month steps and canonical time zones
wedamija 258a3fc
fix(nestjs): Keep isolateTrace when no monitor config is sent
wedamija b253af4
ref(nestjs): Shorten SentryCron comments
wedamija 34f02f1
feat(nestjs): Add option to monitor every @Cron method
wedamija a191b86
fix(nestjs): Skip monitored @Cron jobs in the cron package integration
wedamija 47086d7
Merge remote-tracking branch 'origin/develop' into danf/nestjs-cron-c…
wedamija 9173773
Merge remote-tracking branch 'origin/danf/nestjs-cron-config' into da…
wedamija cb47dab
fix(nestjs): Use OrchestrionChannelContext in schedule explorer subsc…
wedamija 0c123c6
fix(nestjs): Mark the CronJob onTick when a decorator wraps @Cron()
wedamija 0c5e61c
fix(nestjs): Detect @SentryCron when another decorator sits between i…
wedamija 0576af0
fix(nestjs): Expand @Cron day fields like cron and send numeric month…
wedamija a9a89d7
docs(nestjs): Add changelog entry for SentryCron monitor config
wedamija 7a3b942
Merge remote-tracking branch 'origin/danf/nestjs-cron-config' into wt…
wedamija 481a052
fix(nestjs): Skip jobs with unsupported schedules when monitoring all…
wedamija f23a26f
Merge remote-tracking branch 'origin/develop' into wt-nestjs-cron-aut…
wedamija File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| import type { Client, MonitorConfig } from '@sentry/core'; | ||
| import { debug, getClient, stringMatchesSomePattern } from '@sentry/core'; | ||
| import { DEBUG_BUILD } from '../debug-build'; | ||
| import { nestCronOptionsToMonitorConfig } from '../decorators'; | ||
| import type { AnyFn } from './helpers'; | ||
| import { isSentryCronMethod } from './helpers'; | ||
|
|
||
| export interface NestCronMonitoringOptions { | ||
| /** | ||
| * Send check-ins for every `@Cron()` method of `@nestjs/schedule`. The monitor slug is the `name` | ||
| * option of `@Cron()`, or `ClassName.methodName`. Methods with `@SentryCron()` keep their own slug. | ||
| * Methods whose schedule Sentry can't represent, like every 10 seconds, are not monitored. | ||
| * | ||
| * Defaults to `false`. | ||
| */ | ||
| monitorCronJobs?: boolean; | ||
|
|
||
| /** | ||
| * Monitor slugs not to monitor when `monitorCronJobs` is enabled. Strings must match the slug exactly. | ||
| */ | ||
| excludeCronJobs?: Array<string | RegExp>; | ||
| } | ||
|
|
||
| interface CronMonitor { | ||
| slug: string; | ||
| config: MonitorConfig; | ||
| } | ||
|
|
||
| const MONITORING_OPTIONS = new WeakMap<Client, NestCronMonitoringOptions>(); | ||
|
|
||
| /** Enables `@Cron()` monitoring for the client. */ | ||
| export function setCronMonitoringOptions(client: Client, options: NestCronMonitoringOptions): void { | ||
| if (options.monitorCronJobs) { | ||
| MONITORING_OPTIONS.set(client, options); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Returns a function that resolves the monitor for a `@Cron()` method on each run, | ||
| * or `undefined` if the run should not be monitored. | ||
| */ | ||
| export function makeCronMonitorResolver( | ||
| cronArgs: unknown[], | ||
| target: unknown, | ||
| propertyKey: string | symbol | undefined, | ||
| scheduleVersion?: string, | ||
| ): (handler: AnyFn, wrapped: AnyFn) => CronMonitor | undefined { | ||
| let monitor: CronMonitor | null | undefined; | ||
|
|
||
| return (handler, wrapped) => { | ||
| const client = getClient(); | ||
| const options = client && MONITORING_OPTIONS.get(client); | ||
| if (!options || isSentryCronMethod(handler) || isSentryCronMethod(wrapped)) { | ||
| return undefined; | ||
| } | ||
|
wedamija marked this conversation as resolved.
|
||
|
|
||
| if (monitor === undefined) { | ||
| try { | ||
| monitor = getCronMonitor(cronArgs, target, propertyKey, scheduleVersion); | ||
| } catch (e) { | ||
| DEBUG_BUILD && debug.error('[Nest] Failed to set up the cron monitor:', e); | ||
| monitor = null; | ||
| } | ||
| } | ||
|
|
||
| if (!monitor || stringMatchesSomePattern(monitor.slug, options.excludeCronJobs, true)) { | ||
| return undefined; | ||
| } | ||
| return monitor; | ||
| }; | ||
| } | ||
|
|
||
| function getCronMonitor( | ||
| [cronTime, cronOptions]: unknown[], | ||
| target: unknown, | ||
| propertyKey: string | symbol | undefined, | ||
| scheduleVersion: string | undefined, | ||
| ): CronMonitor | null { | ||
| // A `Date` runs once, so there is nothing to monitor. | ||
| if (typeof cronTime !== 'string') { | ||
| return null; | ||
| } | ||
|
|
||
| const options = (cronOptions && typeof cronOptions === 'object' ? cronOptions : {}) as Record<string, unknown>; | ||
| const className = (target as { constructor?: { name?: unknown } } | undefined)?.constructor?.name; | ||
| const slug = | ||
| typeof options.name === 'string' && options.name | ||
| ? options.name | ||
| : typeof className === 'string' && className && propertyKey !== undefined | ||
| ? `${className}.${String(propertyKey)}` | ||
| : undefined; | ||
|
|
||
| if (!slug) { | ||
| DEBUG_BUILD && debug.warn('[Nest] Not monitoring a @Cron() method without a name.'); | ||
| return null; | ||
| } | ||
|
|
||
| const config = nestCronOptionsToMonitorConfig({ ...options, cronTime }, scheduleVersion); | ||
| if (!config) { | ||
| DEBUG_BUILD && debug.log(`[Nest] Not monitoring ${slug}: Sentry can't represent its schedule.`); | ||
| return null; | ||
| } | ||
|
|
||
| return { slug, config }; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,23 @@ | ||
| import { defineIntegration } from '@sentry/core'; | ||
| import type { NestCronMonitoringOptions } from './cron-monitoring'; | ||
| import { setCronMonitoringOptions } from './cron-monitoring'; | ||
| import { subscribeToNestChannels } from './orchestrion-subscriber'; | ||
|
|
||
| const INTEGRATION_NAME = 'Nest' as const; | ||
|
|
||
| export type NestIntegrationOptions = NestCronMonitoringOptions; | ||
|
|
||
| /** | ||
| * Integration capturing tracing data for NestJS. | ||
| */ | ||
| export const nestIntegration = defineIntegration(() => { | ||
| export const nestIntegration = defineIntegration((options: NestIntegrationOptions = {}) => { | ||
| return { | ||
| name: INTEGRATION_NAME, | ||
| setupOnce() { | ||
| subscribeToNestChannels(); | ||
| }, | ||
| setup(client) { | ||
| setCronMonitoringOptions(client, options); | ||
| }, | ||
| }; | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.