---
title: "Quartz Integration"
description: "Learn how to send check-ins for your Quartz jobs."
url: https://docs.sentry.io/platforms/java/guides/jul/integrations/quartz/
---

# Quartz Integration for java.util.logging

Sentry's [Quartz](http://www.quartz-scheduler.org/) integration is provided through `SentryJobListener` which you have to add to your scheduler instance.

The Quartz integration will be configured automatically if you're using `spring-boot-starter-quartz` with either the `sentry-spring-boot-starter` or the `sentry-spring-boot-jakarta-starter` integration. However, you still have to specify the monitor slug as shown below.

Check-ins may also be [sent manually](https://docs.sentry.io/platforms/java/crons.md) or if you're using Sentry's Spring Boot integration you can send send check-ins for your `@Scheduled` tasks by using our [`@SentryCheckIn` annotation](https://docs.sentry.io/platforms/java/guides/spring-boot/crons.md).

## [Install](https://docs.sentry.io/platforms/java/guides/jul/integrations/quartz.md#install)

To install use:

**Gradle Plugin**

```groovy
plugins {
  id "io.sentry.jvm.gradle" version "6.27.0"
}
```

**Gradle**

```groovy
implementation 'io.sentry:sentry-quartz:8.64.0'
```

**\[Maven Plugin] pom.xml**

```xml
<plugin>
  <groupId>io.sentry</groupId>
  <artifactId>sentry-maven-plugin</artifactId>
  <version>0.12.0</version>
  <!-- Required to allow auto-install of Sentry SDK and Integrations -->
  <extensions>true</extensions>
</plugin>
```

**Maven**

```xml
<dependency>
    <groupId>io.sentry</groupId>
    <artifactId>sentry-quartz</artifactId>
    <version>8.64.0</version>
</dependency>
```

**SBT**

```scala
libraryDependencies += "io.sentry" % "sentry-quartz" % "8.64.0"
```

For other dependency managers, check out the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-quartz).

## [Set Up](https://docs.sentry.io/platforms/java/guides/jul/integrations/quartz.md#set-up)

You have to provide the monitor slug either

* when building a Quartz `JobDetail` instance
* or when building a Quartz `Trigger` instance

To do so, you have to add an entry to the jobs data map:

```java
import io.sentry.quartz.SentryJobListener;

// you can set the monitor slug on the job detail
JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
jobDetailFactory.setJobDataAsMap(Collections.singletonMap(SentryJobListener.SENTRY_SLUG_KEY, "<monitor-slug>"));

// you can also set the monitor slug on the trigger
SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean();
trigger.setJobDataAsMap(Collections.singletonMap(SENTRY_SLUG_KEY, "monitor_slug_simple_trigger"));
```

Setting the monitor slug on the `Trigger` will override what is set on the `JobDetail`. This also means you can set up a separate monitor per `Trigger`.

Setting a global job listener using a `SchedulerFactoryBeanCustomizer` in Spring Boot, will override the listener set by Sentry. For Sentry to work properly, you need to add a new `SentryJobListener` instance to the global job listeners.

## [Monitor Config](https://docs.sentry.io/platforms/java/guides/jul/integrations/quartz.md#monitor-config)

From Sentry Java SDK version `8.64.0`, `SentryJobListener` can send a monitor config derived from the job's trigger with each check-in, so Sentry creates the monitor (or updates its schedule) from your code.

To turn it on for a job, set `SentryJobListener.SENTRY_UPSERT_MONITOR_CONFIG_KEY` to the string `"true"` in the job data map, next to the monitor slug. Like the slug, it also works in the trigger's job data map:

```java
Map<String, Object> jobData = new HashMap<>();
jobData.put(SentryJobListener.SENTRY_SLUG_KEY, "<monitor-slug>");
jobData.put(SentryJobListener.SENTRY_UPSERT_MONITOR_CONFIG_KEY, "true");

JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
jobDetailFactory.setJobDataAsMap(jobData);
```

The config is derived like this:

* `CronTrigger`: the cron expression and the trigger's time zone. The seconds field must be a fixed number, and the year field, if set, must be `*`. If the seconds field isn't `0`, a check-in margin of 2 minutes is sent too, since the job checks in up to 59 seconds after the minute Sentry expects. This replaces a margin set in Sentry; set a larger `options.cron` default check-in margin to keep it.
* `SimpleTrigger` that repeats forever: the repeat interval, if it's a whole number of minutes.

No monitor config is sent for:

* Other trigger types
* Triggers with a `Calendar`
* Jobs with more than one trigger
* Cron expressions with syntax Sentry doesn't support, such as `15W`, `L-3`, or wrap-around ranges like `FRI-MON`
* Cron expressions with a step after a day or month name, such as `MON/2` (which Quartz runs every Monday)
* Time zones that aren't IANA time zone IDs, except whole-hour offsets such as `GMT+2`, which are sent as `Etc/GMT-2`

For these, create the monitor in Sentry first.

When you turn this on for a monitor you created in Sentry, it takes its schedule and time zone from the trigger.
