Skip to content

Commit

Permalink
Add cron monitor wrapper (#1679)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex Bouma <alex@bouma.me>
  • Loading branch information
cleptric and stayallive authored Jan 17, 2024
1 parent 65d9ff3 commit 7c2f605
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 7 deletions.
32 changes: 31 additions & 1 deletion src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,37 @@ function captureCheckIn(string $slug, CheckInStatus $status, $duration = null, ?
return SentrySdk::getCurrentHub()->captureCheckIn($slug, $status, $duration, $monitorConfig, $checkInId);
}

/**
* Execute the given callable while wrapping it in a monitor check-in.
*
* @param string $slug Identifier of the Monitor
* @param callable $callback The callable that is going to be monitored
* @param MonitorConfig|null $monitorConfig Configuration of the Monitor
*
* @return mixed
*/
function withMonitor(string $slug, callable $callback, ?MonitorConfig $monitorConfig = null)
{
$checkInId = SentrySdk::getCurrentHub()->captureCheckIn($slug, CheckInStatus::inProgress(), null, $monitorConfig);

$status = CheckInStatus::ok();
$duration = 0;

try {
$start = microtime(true);
$result = $callback();
$duration = microtime(true) - $start;

return $result;
} catch (\Throwable $e) {
$status = CheckInStatus::error();

throw $e;
} finally {
SentrySdk::getCurrentHub()->captureCheckIn($slug, $status, $duration, $monitorConfig, $checkInId);
}
}

/**
* Records a new breadcrumb which will be attached to future events. They
* will be added to subsequent events to provide more context on user's
Expand Down Expand Up @@ -157,7 +188,6 @@ function startTransaction(TransactionContext $context, array $customSamplingCont

/**
* Execute the given callable while wrapping it in a span added as a child to the current transaction and active span.
*
* If there is no transaction active this is a no-op and the scope passed to the trace callable will be unused.
*
* @template T
Expand Down
80 changes: 74 additions & 6 deletions tests/FunctionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
use function Sentry\init;
use function Sentry\startTransaction;
use function Sentry\trace;
use function Sentry\withMonitor;
use function Sentry\withScope;

final class FunctionsTest extends TestCase
Expand Down Expand Up @@ -200,7 +201,7 @@ public function testCaptureCheckIn(): void
'UTC'
);

$hub = $this->createMock(StubHubInterface::class);
$hub = $this->createMock(HubInterface::class);
$hub->expects($this->once())
->method('captureCheckIn')
->with('test-crontab', CheckInStatus::ok(), 10, $monitorConfig, $checkInId)
Expand All @@ -217,6 +218,78 @@ public function testCaptureCheckIn(): void
));
}

public function testWithMonitor(): void
{
$hub = $this->createMock(HubInterface::class);
$hub->expects($this->exactly(2))
->method('captureCheckIn')
->with(
$this->callback(function (string $slug): bool {
return $slug === 'test-crontab';
}),
$this->callback(function (CheckInStatus $checkInStatus): bool {
// just check for type CheckInStatus
return true;
}),
$this->anything(),
$this->callback(function (MonitorConfig $monitorConfig): bool {
return $monitorConfig->getSchedule()->getValue() === '*/5 * * * *'
&& $monitorConfig->getSchedule()->getType() === MonitorSchedule::TYPE_CRONTAB
&& $monitorConfig->getCheckinMargin() === 5
&& $monitorConfig->getMaxRuntime() === 30
&& $monitorConfig->getTimezone() === 'UTC';
})
);

SentrySdk::setCurrentHub($hub);

withMonitor('test-crontab', function () {
// Do something...
}, new MonitorConfig(
new MonitorSchedule(MonitorSchedule::TYPE_CRONTAB, '*/5 * * * *'),
5,
30,
'UTC'
));
}

public function testWithMonitorCallableThrows(): void
{
$this->expectException(\Exception::class);

$hub = $this->createMock(HubInterface::class);
$hub->expects($this->exactly(2))
->method('captureCheckIn')
->with(
$this->callback(function (string $slug): bool {
return $slug === 'test-crontab';
}),
$this->callback(function (CheckInStatus $checkInStatus): bool {
// just check for type CheckInStatus
return true;
}),
$this->anything(),
$this->callback(function (MonitorConfig $monitorConfig): bool {
return $monitorConfig->getSchedule()->getValue() === '*/5 * * * *'
&& $monitorConfig->getSchedule()->getType() === MonitorSchedule::TYPE_CRONTAB
&& $monitorConfig->getCheckinMargin() === 5
&& $monitorConfig->getMaxRuntime() === 30
&& $monitorConfig->getTimezone() === 'UTC';
})
);

SentrySdk::setCurrentHub($hub);

withMonitor('test-crontab', function () {
throw new \Exception();
}, new MonitorConfig(
new MonitorSchedule(MonitorSchedule::TYPE_CRONTAB, '*/5 * * * *'),
5,
30,
'UTC'
));
}

public function testAddBreadcrumb(): void
{
$breadcrumb = new Breadcrumb(Breadcrumb::LEVEL_ERROR, Breadcrumb::TYPE_ERROR, 'error_reporting');
Expand Down Expand Up @@ -440,8 +513,3 @@ public function testContinueTrace(): void
});
}
}

interface StubHubInterface extends HubInterface
{
public function captureCheckIn(string $slug, CheckInStatus $status, $duration = null, ?MonitorConfig $monitorConfig = null, ?string $checkInId = null): ?string;
}

0 comments on commit 7c2f605

Please sign in to comment.