Skip to content
2 changes: 1 addition & 1 deletion platform-includes/crons/requirements/java.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
- Send a monitor configuration from your code as shown below, and Sentry creates the monitor on the first check-in. You can also [create the monitor in Sentry](https://sentry.io/issues/alerts/new/crons/) instead.
</PlatformSection>
<PlatformSection supported={["java.spring-boot"]}>
- [Create the monitor in Sentry](https://sentry.io/issues/alerts/new/crons/) first. `@SentryCheckIn` does not send a monitor configuration, so Sentry drops check-ins for a slug that has no monitor.
- From the next Sentry Java SDK release (after `8.59.0`), `@SentryCheckIn` sends a monitor configuration based on the method's `@Scheduled` annotation by default, and Sentry creates the monitor on the first check-in. With `upsertMonitorConfig = false`, on older SDK versions, or for schedules that can't be converted, [create the monitor in Sentry](https://sentry.io/issues/alerts/new/crons/) first, because Sentry drops check-ins for a slug that has no monitor.
</PlatformSection>
24 changes: 24 additions & 0 deletions platform-includes/crons/setup/java.spring-boot.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,30 @@ public class CustomJob {
}
```

### Monitor Configuration From `@Scheduled`

From the next Sentry Java SDK release (after `8.59.0`), `@SentryCheckIn` reads the method's `@Scheduled` annotation and sends a monitor configuration with the in-progress check-in by default, so Sentry creates the monitor, or updates its schedule, from your code:

```java
@Scheduled(cron = "0 0 * * * *")
@SentryCheckIn("<monitor-slug>") // 👈
Comment thread
wedamija marked this conversation as resolved.
void execute() {
// your task code
}
```

The schedule is converted like this:

- `cron`: a Spring cron expression with a fixed seconds field (for example `0 0 * * * *`) is sent as a crontab schedule without the seconds. Spring macros such as `@hourly` and `@daily` are supported.
- `fixedRate` (including `fixedRateString`, such as `"5m"` or `"PT5M"`, and `timeUnit`): sent as an interval schedule when the period is a whole number of minutes. `fixedDelay` jobs send no monitor config.
- `zone`: sent as the monitor's timezone for cron schedules. Without `zone`, the JVM's default time zone is sent, since that's where Spring runs the job. It must be an IANA time zone ID such as `Europe/Vienna`; whole-hour offsets such as `GMT+2` are sent as `Etc/GMT-2`.

Placeholders such as `${app.cleanup.cron}` are resolved. No configuration is sent for cron expressions with variable seconds (for example `*/30 * * * * *`), cron expressions that set both day-of-month and day-of-week (on Spring 5.3 and later, a day-of-month step such as `0 0 9 */2 * MON` is converted; on older Spring versions, none are), `#5` days of week on Spring 5.3 and later, cron syntax Sentry doesn't support (such as `15W`, `L-3`, or wrap-around ranges like `22-2`), other time zones, periods that aren't whole minutes, methods with more than one `@Scheduled`, or heartbeat check-ins. For those, for methods with `upsertMonitorConfig = false`, and for older SDK versions, [create the monitor in Sentry](https://sentry.io/issues/alerts/new/crons/) first.

Sentry only updates the fields that were sent. Margins, max runtime, and thresholds configured in Sentry are kept unless you set defaults for them in `options.cron`, which are sent only with check-ins that carry a monitor configuration.

When you upgrade, monitors that already exist get the schedule and timezone from `@Scheduled` (the JVM's default time zone if `zone` isn't set), overwriting the ones set in Sentry. To keep managing a monitor's schedule in Sentry, set `@SentryCheckIn(value = "<monitor-slug>", upsertMonitorConfig = false)`.

## Heartbeat

Heartbeat monitoring notifies Sentry of a job's status through one check-in. This setup will only notify you if your job didn't start when expected (missed). If you need to track a job to see if it exceeded its maximum runtime (failed), use check-ins instead. To start sending heartbeats simply add the `@SentryCheckIn(monitorSlug = "<monitor-slug>", heartbeat = true)` annotation to the method you want to send heartbeats for.
Expand Down
Loading