Skip to content

Feature/sentry.quartz - #5505

Open
michaelmairegger wants to merge 30 commits into
getsentry:mainfrom
michaelmairegger:feature/sentry.quartz
Open

Feature/sentry.quartz#5505
michaelmairegger wants to merge 30 commits into
getsentry:mainfrom
michaelmairegger:feature/sentry.quartz

Conversation

@michaelmairegger

@michaelmairegger michaelmairegger commented Aug 24, 2026

Copy link
Copy Markdown

This PR implements and showcases Quartz.Net integration for Sentry

Note: Quartz.Net v4 is still alpha, therefore we should wait until v4 is finally released.

fixes #4601

@github-actions github-actions Bot added the risk: high PR risk score: high label Aug 24, 2026
Comment thread samples/Sentry.Samples.Quartz/Program.cs Outdated
Comment thread samples/Sentry.Samples.Quartz/Program.cs
Comment thread samples/Sentry.Samples.Quartz/Program.cs
Comment thread samples/Sentry.Samples.Quartz/Sentry.Samples.Quartz.csproj
Comment thread src/Sentry.Quartz/GlobalConfigurationExtensions.cs Outdated
Comment thread src/Sentry.Quartz/GlobalConfigurationExtensions.cs Outdated
@michaelmairegger michaelmairegger changed the title Feature/sentry.quartz Feature/sentry.quartz (Quartz v4 Alpha version) Aug 24, 2026
Comment thread samples/Sentry.Samples.Quartz/Program.cs Outdated
Comment thread src/Sentry.Quartz/SentryCronJobListener.cs Outdated
Comment thread src/Sentry.Quartz/SentryCronJobMiddleware.cs Outdated
Comment thread src/Sentry.Quartz/Sentry.Quartz.csproj Outdated
@michaelmairegger

Copy link
Copy Markdown
Author

@jamescrosswell I will continue watching Quartz.Net alpha releases and adopt it until final bits of 4.0 will be released.
I will notify you when ready.

@jamescrosswell

jamescrosswell commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

@jamescrosswell I will continue watching Quartz.Net alpha releases and adopt it until final bits of 4.0 will be released. I will notify you when ready.

Fantastic, thank you @michaelmairegger !

Maybe we mark the PR as draft until then? That let's me know it doesn't yet need my attention (you can always tag me directly if you want my input on something before v4 is released).

@michaelmairegger michaelmairegger changed the title Feature/sentry.quartz (Quartz v4 Alpha version) 🚧 Feature/sentry.quartz (Quartz v4 Alpha version) Sep 1, 2026
Comment thread src/Sentry.Quartz/SentryCronJobMiddleware.cs Outdated
Comment thread src/Sentry.Quartz/IQuartzBuilderExtensions.cs
Comment thread src/Sentry.Quartz/SentryCronJobMiddleware.cs Outdated
Comment thread src/Sentry.Quartz/Sentry.Quartz.csproj Outdated
Comment thread src/Sentry.Quartz/SentryCronJobMiddleware.cs

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread src/Sentry.Quartz/SentryCronJobMiddleware.cs
Comment thread src/Sentry.Quartz/SentryCronJobMiddleware.cs

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread src/Sentry.Quartz/SentryCronJobMiddleware.cs
Comment thread samples/Sentry.Samples.Quartz/Properties/launchSettings.json Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread src/Sentry.Quartz/SentryCronJobMiddleware.cs
@michaelmairegger

Copy link
Copy Markdown
Author

@jamescrosswell quartz.net released final bits of v4. I updated the package to the final version and would say this first version of the package is feature complete.

@michaelmairegger michaelmairegger changed the title 🚧 Feature/sentry.quartz (Quartz v4 Alpha version) 🚧 Feature/sentry.quartz Sep 7, 2026
@michaelmairegger michaelmairegger changed the title 🚧 Feature/sentry.quartz Feature/sentry.quartz Sep 7, 2026
@jamescrosswell

Copy link
Copy Markdown
Collaborator

@jamescrosswell quartz.net released final bits of v4. I updated the package to the final version and would say this first version of the package is feature complete.

Nice - thanks @michaelmairegger. I wasn't expecting them to get v4 out so quickly!

Apologies in advance... I might be a bis slow on reviewing - there's quite a but going on right now and the invention of AI has made it much easier for people to make PRs - so I'm spread a bit thin.

@codecov

codecov Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.30769% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.93%. Comparing base (5094196) to head (dc22b2f).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/Sentry.Quartz/IQuartzBuilderExtensions.cs 40.00% 3 Missing ⚠️
src/Sentry.Quartz/SentryCronJobMiddleware.cs 94.54% 1 Missing and 2 partials ⚠️
src/Sentry.Quartz/RegionInfoExtensions.cs 33.33% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5505      +/-   ##
==========================================
+ Coverage   74.72%   74.93%   +0.21%     
==========================================
  Files         515      523       +8     
  Lines       18949    19061     +112     
  Branches     3696     3706      +10     
==========================================
+ Hits        14159    14284     +125     
+ Misses       3908     3890      -18     
- Partials      882      887       +5     

☔ 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.

jamescrosswell and others added 3 commits September 8, 2026 12:40
The format-code workflow can't push its auto-fix to a fork branch, so it
fails the check instead. Applying the fix here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every package needs a name/packageUrl/mainDocsUrl entry so craft can create
its registry entry on first publish; a missing `name` fails the whole
registry target rather than just that package.

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

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 688c054. Configure here.

Comment thread src/Sentry.Quartz/SentryCronJobOptions.cs
Comment thread src/Sentry.Quartz/Sentry.Quartz.csproj Outdated
Comment thread src/Sentry.Quartz/IQuartzBuilderExtensions.cs

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.

I think the key metrics (like job duration) Sentry infers/tracks automatically from the checkins. So you get things like this in the job monitoring dashboard:

Image

Are there some things missing from the build in dashboards that prompted you to add the metrics middleware?

Everything we have to build to get those default dashboard visualisations should be covered in the developer docs for check ins.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I am not seeing this screen. I am using self hosted v26.8.0 and there the view does not have any duration chart. This is all I see. Therefore I started writing the SentryMetricsMiddleware.
image

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.

Hm, sounds like there might be an issue with your self hosted setup. I asked the Sentry docs about this and they came back with:

In general, self-hosted Sentry has near-feature-parity with SaaS for cron monitoring — Crons is included in the default "Feature Complete" self-hosted deployment.

Self-Hosted Errors-Only

Regarding the missing average duration issue your user is seeing, there are a few known causes worth investigating:

  1. Known Bug: Missing Duration on Check-ins
    There is a known issue where cron monitors show an "invalid duration" error or display — for duration when no duration parameter is included in the check-in request. This has been reported on SaaS as well.

#105192 - Invalid Duration Issue

  1. Ingestion Pipeline Issues
    If a check-in's in_progress event is dropped (e.g., due to an ingestion outage or network issue), the resulting check-in will have no duration because the start time was never recorded. The OK check-in then creates a check-in with no corresponding in_progress, so duration cannot be calculated.

#59607 - Missed Check-in Issue

  1. Self-Hosted: Missing ingest-monitors Consumer
    On older self-hosted setups, if the ingest-monitors Kafka consumer is not running, check-ins may not be processed correctly at all. This was a known configuration gap before Crons went GA.

#1993 - Add Crons Issue

  1. Latency / Tight Timeout Margins
    If a job's completion check-in arrives very close to the max runtime threshold, queue processing latency can cause it to be marked as timed out before the completion is registered — resulting in missing duration data.

#71671 - Cron Inconsistent Behavior

You could always add this SentryMetricsMiddleware to your own project if you need it but we shouldn't add it in the Sentry.Quartz integration.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I see everything you mention above, just the chart with duration is missing. The recent check-ins table is just cropped in the screenshot, but it has valid data.

Neither docker nor when opening the dev tools in the browser shows any error when loading the page. So I think that there is a slight feature diff between SaaS and self-hosted. As far as I can remember, some time ago, there was a chart showing the average duration.

For me there is no problem to remove this middleware from code and use it in my projects only.

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.

I'm not too sure why the duration isn't showing - that would be a question for support as it isn't controlled anywhere in SDKs like sentry-dotnet.

Let's remove the Metrics middleware from the SDK. We don't want to duplicate information that is already there for most people.


public async ValueTask Invoke(IJobExecutionContext context, JobExecutionDelegate next, CancellationToken cancellationToken)
{
using var _ = _sentryHub.PushScope();

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.

I like the idea of pushing a fresh scope for each job.

Maybe worth adding the job id as an attribute to the scope here... that way it's easy to match errors with the job they relate to?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

do you mean something like this?

using var _ = _sentryHub.PushScope();
_sentryHub.ConfigureScope(scope => scope.SetTag("quartz.job", context.JobDetail.Key.Name));
[...]

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.

I haven't used Quartz for about 10 years but assuming context.JobDetail.Key.Name uniquely identifies either the job or the job run, yes, something like that 😄

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Comment thread src/Sentry.Quartz/SentryCronJobMiddleware.cs
public async ValueTask Invoke(IJobExecutionContext context, JobExecutionDelegate next, CancellationToken cancellationToken)
{
var jobType = context.JobInstance.GetType();
var info = _sentryCronInformation.GetOrAdd(jobType, _ => new SentryCronInformation(context.JobInstance));

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.

I think this might be a mistake. _sentryCronInformation caches the jobs but currently the key used in the cache is the job type.

Quartz identifies a scheduled job by its JobKey (name + group), not by its class... which is what should be used as the cache key.

This has only worked until now since your sample happens to assign the class names as the job keys... but that's specific to your usage of Quartz in the sample application.

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.

Support Quartz.NET like Sentry.Hangfire

2 participants