Skip to content

feat(hangfire): send the recurring job's cron schedule as the monitor config - #5665

Open
wedamija wants to merge 7 commits into
mainfrom
danf/hangfire-cron-config
Open

wedamija wants to merge 7 commits into
mainfrom
danf/hangfire-cron-config

Conversation

@wedamija

@wedamija wedamija commented Oct 2, 2026 •

Copy link
Copy Markdown
Member

Description

Adds a SendMonitorConfig option to the Hangfire integration. When it's on, the in-progress check-in of a recurring job includes the job's cron and time zone as the monitor config, so Sentry creates the monitor or updates its schedule. The slug still comes from [SentryMonitorSlug].

It's on by default. To turn it off:

GlobalConfiguration.Configuration.UseSentry(o => o.SendMonitorConfig = false);

When the schedule can't be represented exactly in Sentry (seconds other than a fixed value, day fields Hangfire combines differently, a time zone with no IANA ID), the check-in goes out without a config, as today, rather than with a schedule that would cause false missed-check-in alerts.

Hangfire jobs are only monitored when they already have [SentryMonitorSlug], so the user has opted in to monitoring, and the recurring job already knows its schedule. Sending it by default lets Sentry create or update the monitor, the same as the Spring and Quartz integrations. On upgrade, existing monitors get their schedule and time zone from the recurring job; set SendMonitorConfig = false to keep managing them in Sentry.

Motivation

Check-ins for a monitor that doesn't exist yet are dropped, so today every Hangfire monitor has to be created by hand, with its schedule copied from the recurring job. The schedule is already in Hangfire, so the SDK can send it.

Testing

ServerFilterTests and HangfireTests.

Docs: getsentry/sentry-docs#19781

Opt-in via UseSentry(o => o.SendRecurringJobSchedule = true). The
in-progress check-in of a recurring job carries the job's cron and time
zone so Sentry can create the monitor. Unsupported schedules fall back
to a check-in without config.

Co-Authored-By: Claude <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.80519% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.36%. Comparing base (ea7fa3a) to head (96c1d60).
⚠️ Report is 12 commits behind head on main.

Files with missing lines Patch % Lines
src/Sentry.Hangfire/SentryServerFilter.cs 93.93% 0 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5665      +/-   ##
==========================================
+ Coverage   74.93%   75.36%   +0.43%     
==========================================
  Files         515      517       +2     
  Lines       18975    19061      +86     
  Branches     3695     3716      +21     
==========================================
+ Hits        14219    14366     +147     
+ Misses       3876     3827      -49     
+ Partials      880      868      -12     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Check the crontab up front so the check-in goes out in a single call
instead of relying on the hub to swallow an exception from Interval.
The validator is shared with Sentry.Hangfire as a linked source file,
since the unsigned assembly can't see Sentry's internals.

Read the job through GetRecurringJobs, look up time zones with
FindSystemTimeZoneById on .NET 6+, and add tests for UTC, unknown
zones, deleted jobs, the UseSentry overload, and a real recurring job.

Co-Authored-By: Claude <noreply@anthropic.com>
@wedamija wedamija changed the title feat(hangfire): Optionally send the recurring job's cron schedule as the monitor config feat(hangfire): optionally send the recurring job's cron schedule as the monitor config Oct 2, 2026
The linux-musl CI containers have no time zone database, so lookups
of Europe/Berlin and Etc/UTC fail there.

Co-Authored-By: Claude <noreply@anthropic.com>
wedamija and others added 2 commits October 5, 2026 12:22
Hangfire runs a job only on days that match both the day-of-month and
day-of-week fields, while Sentry runs it on days that match either
unless one of them starts with '*'. Don't send those schedules, nor
ones with a reversed range such as 5-1 or SAT-SUN, which Sentry
rejects.

Co-Authored-By: Claude <noreply@anthropic.com>
Jobs are only monitored when they have [SentryMonitorSlug], so sending
the recurring job's schedule lets Sentry create or update the monitor,
like the Spring and Quartz integrations. Set SendRecurringJobSchedule
to false to keep managing the schedule in Sentry.

Co-Authored-By: Claude <noreply@anthropic.com>
@wedamija wedamija changed the title feat(hangfire): optionally send the recurring job's cron schedule as the monitor config feat(hangfire): send the recurring job's cron schedule as the monitor config Oct 6, 2026

@jamescrosswell jamescrosswell left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, looks good - I just have one question/suggestion re consistent naming.

The only other thing to note is that if someone deletes a monitor but leaves [SentryMonitorSlug] on the job, the monitor will be recreated on the next run... That's probably OK and better than a monitor that doesn't get created (which we have now). It means people have to remove the slug attribute and redeploy before they can remove a monitor. Any alternative technical workaround would probably have to be a bit more convoluted (leave some trace of the monitor having been deleted on the server).

Comment thread src/Sentry.Hangfire/SentryHangfireOptions.cs Outdated
The final check-in reused the ID returned for the in-progress one, which
is empty when that one isn't captured. Create the ID up front, send it
with the in-progress check-in, and store it in the job's items as before.

Co-Authored-By: Claude <noreply@anthropic.com>
@wedamija

wedamija commented Oct 8, 2026 •

Copy link
Copy Markdown
Member Author

Overall, looks good - I just have one question/suggestion re consistent naming.

The only other thing to note is that if someone deletes a monitor but leaves [SentryMonitorSlug] on the job, the monitor will be recreated on the next run... That's probably OK and better than a monitor that doesn't get created (which we have now). It means people have to remove the slug attribute and redeploy before they can remove a monitor. Any alternative technical workaround would probably have to be a bit more convoluted (leave some trace of the monitor having been deleted on the server).

On re-creating deleted monitors: agreed, that's inherent to upsert and works the same in the other SDKs. One other option here is to disable the monitor in Sentry, rather than deleting it. Since the monitor still exists, rather than recreating it the checkins will just be dropped. I can add that to the docs in this pr: getsentry/sentry-docs#19781

Matches SentryQuartzOptions.SendMonitorConfig.

Co-Authored-By: Claude <noreply@anthropic.com>
@wedamija
wedamija marked this pull request as ready for review October 8, 2026 22:18
@wedamija
wedamija requested a review from ric-oliv as a code owner October 8, 2026 22:18
@github-actions github-actions Bot added the risk: high PR risk score: high label Oct 8, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants