Skip to content

Feature/sentry.quartz - #5505

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

michaelmairegger wants to merge 35 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

@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
Comment thread src/Sentry.Quartz/SentryMetricsMiddleware.cs Outdated

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 😄

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.

done

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.

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.

done

@michaelmairegger

Copy link
Copy Markdown
Author

@jamescrosswell I will review the proposed changes next week and provide code changes then


public SentryCronJobMiddleware(IHub hub, IOptions<SentryCronJobOptions> options, ILogger<SentryCronJobMiddleware> logger)
{
_hub = hub;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The _sentryCronInformation dictionary in the singleton middleware never removes entries, causing a memory leak in applications that dynamically create jobs.
Severity: MEDIUM

Suggested Fix

Implement a cleanup mechanism for the _sentryCronInformation dictionary. This could involve using a cache with an eviction policy (e.g., MemoryCache with sliding expiration) or hooking into Quartz.NET's job lifecycle events to remove entries when a job is unscheduled or deleted. This will prevent the dictionary from growing indefinitely.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/Sentry.Quartz/SentryCronJobMiddleware.cs#L16

Potential issue: The `SentryCronJobMiddleware` is a singleton that uses a
`ConcurrentDictionary` called `_sentryCronInformation` to cache information about jobs,
using the job key as the dictionary key. However, there is no mechanism to remove
entries from this dictionary. In long-running applications that dynamically create and
schedule jobs with unique keys, this dictionary will grow indefinitely, leading to a
memory leak. While applications with a fixed, static set of jobs are unaffected, those
with dynamic job creation will experience unbounded memory growth over time, which can
degrade performance and eventually cause the application to crash.

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