Quickstart
Take a job that already runs on a schedule and put a monitor around it. Five steps, and the only thing you need in advance is a DSN.
1. Get a DSN
From the panel: Settings → Projects → your project → Keys → Create key, then copy the DSN. Full walkthrough in projects, keys and DSNs.
https://a1b2c3d4e5f60718293a4b5c6d7e8f90@ingest.parsemend.com/422. Install a Sentry SDK
Check-ins ride the Sentry protocol, so you install the ordinary SDK for your language and point it at Parsemend. There is no Parsemend-specific package to install.
composer require sentry/sentrycomposer require sentry/sentry-laravelnpm install @sentry/node3. Point it at Parsemend
The DSN is the only configuration that matters here.
\Sentry\init([
'dsn' => 'https://a1b2c3d4e5f60718293a4b5c6d7e8f90@ingest.parsemend.com/42',
'environment' => 'production',
'release' => '1.4.2',
]);// .env
SENTRY_LARAVEL_DSN=https://a1b2c3d4e5f60718293a4b5c6d7e8f90@ingest.parsemend.com/42import * as Sentry from '@sentry/node';
Sentry.init({
dsn: 'https://a1b2c3d4e5f60718293a4b5c6d7e8f90@ingest.parsemend.com/42',
environment: 'production',
release: '1.4.2',
});environment and release are optional. They are worth setting, because both land on the check-in and give you a way to tell staging noise from a real production failure.
4. Wrap the job
Two check-ins per run: one when it starts, one when it ends. The first is what makes hang detection possible, the second is what stops a missed check-in from firing.
use Sentry\CheckInStatus;
use Sentry\MonitorConfig;
use Sentry\MonitorSchedule;
use Sentry\MonitorScheduleUnit;
$config = new MonitorConfig(
MonitorSchedule::crontab('0 * * * *'), // hourly, on the hour
checkinMargin: 5, // minutes of grace before "missed"
maxRuntime: 30, // minutes before "timeout"
timezone: 'UTC',
);
$checkInId = \Sentry\captureCheckIn(
slug: 'hourly-sync',
status: CheckInStatus::inProgress(),
monitorConfig: $config,
);
$started = microtime(true);
try {
run_the_job();
\Sentry\captureCheckIn(
slug: 'hourly-sync',
status: CheckInStatus::ok(),
duration: microtime(true) - $started,
checkInId: $checkInId,
);
} catch (\Throwable $e) {
\Sentry\captureCheckIn(
slug: 'hourly-sync',
status: CheckInStatus::error(),
duration: microtime(true) - $started,
checkInId: $checkInId,
);
throw $e;
}// routes/console.php — one macro, no manual check-ins
Schedule::command('sync:hourly')
->hourly()
->sentryMonitor('hourly-sync');import * as Sentry from '@sentry/node';
// withMonitor sends in_progress before, and ok or error after.
await Sentry.withMonitor(
'hourly-sync',
async () => {
await runTheJob();
},
{
schedule: { type: 'crontab', value: '0 * * * *' },
checkinMargin: 5,
maxRuntime: 30,
timezone: 'UTC',
},
);The Laravel macro derives the schedule from the scheduled task itself, which is why it needs no config argument. See PHP and Laravel for what it sends and what it does not.
Passing checkInId back on the second call is what ties the two check-ins to one run. Without it you get two unrelated rows and no timeout detection.
5. Run it once, then look
Trigger the job. Within a second or two of the run finishing, open Monitoring → Monitors in the panel.
You should see a row:
| Monitor | Status | Schedule | Last check-in | Next expected |
|---|---|---|---|---|
hourly-sync | ok | 0 * * * * | a few seconds ago | in an hour |
If Next expected is empty, the monitor_config did not arrive and missed detection is off for this monitor. That is the one failure mode worth checking on the first run. Troubleshooting covers the rest.
Open the row to see its check-in history, one entry per run, with duration, environment and release.
6. Prove the alarm actually fires
A monitor that has only ever been green has not been tested. The cheapest real test is to stop the job and wait.
Pick a monitor on a short interval, disable the job, and wait for the schedule plus the margin to elapse. Within a minute of that the monitor should flip to missed and an issue titled Monitor "hourly-sync" missed its expected check-in should appear in Issues. Re-enable the job, let one run succeed, and the issue resolves itself.
Do this once per team, not once per monitor. What you are testing is that the notification path works, and that is the same path for every monitor you add later.
Next
- Schedules and timing for what the margin and runtime numbers actually do.
- Failures, issues and alerts to get notified rather than having to look.
