From 3776e0e39e77d5e7d518561887308d119faf812d Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Tue, 14 Mar 2023 01:54:16 +0100 Subject: [PATCH 1/3] feat: Add support for Cron Monitoring --- composer.json | 2 +- src/Sentry/Laravel/ServiceProvider.php | 47 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d81a59a5..b1eef3d8 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "require": { "php": "^7.2 | ^8.0", "illuminate/support": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0", - "sentry/sentry": "^3.12", + "sentry/sentry": "^3.16", "sentry/sdk": "^3.3", "symfony/psr-http-message-bridge": "^1.0 | ^2.0", "nyholm/psr7": "^1.0" diff --git a/src/Sentry/Laravel/ServiceProvider.php b/src/Sentry/Laravel/ServiceProvider.php index c24aaebc..d1ffe6be 100644 --- a/src/Sentry/Laravel/ServiceProvider.php +++ b/src/Sentry/Laravel/ServiceProvider.php @@ -5,12 +5,16 @@ use Illuminate\Contracts\Container\BindingResolutionException; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Http\Kernel as HttpKernelInterface; +use Illuminate\Console\Scheduling\Event as LaravelEvent; use Illuminate\Foundation\Application as Laravel; use Illuminate\Foundation\Http\Kernel as HttpKernel; use Illuminate\Log\LogManager; use RuntimeException; +use Sentry\CheckIn; +use Sentry\CheckInStatus; use Sentry\ClientBuilder; use Sentry\ClientBuilderInterface; +use Sentry\Event as SentryEvent; use Sentry\Integration as SdkIntegration; use Sentry\Laravel\Console\PublishCommand; use Sentry\Laravel\Console\TestCommand; @@ -59,6 +63,7 @@ public function boot(): void $this->bindEvents(); $this->setupFeatures(); + $this->setupCronMonitoring(); if ($this->app->bound(HttpKernelInterface::class)) { /** @var \Illuminate\Foundation\Http\Kernel $httpKernel */ @@ -143,6 +148,48 @@ protected function setupFeatures(): void } } + /** + * Setup Cron Monitoring. + */ + private function setupCronMonitoring(): void + { + LaravelEvent::macro('sentryMonitor', function (string $monitorSlug) { + $hub = SentrySdk::getCurrentHub(); + $checkIn = new CheckIn( + $monitorSlug, + CheckInStatus::inProgress(), + null, + $hub->getClient()->getOptions()->getEnvironment(), + $hub->getClient()->getOptions()->getRelease() + ); + + /** @var \Illuminate\Console\Scheduling\Event $this */ + return $this + ->before(function () use ($hub, $checkIn) { + $event = SentryEvent::createCheckIn(); + $event->setCheckIn($checkIn); + + $hub->captureEvent($event); + }) + ->onSuccess(function () use ($hub, $checkIn) { + $checkIn->setStatus(CheckInStatus::ok()); + + $event = SentryEvent::createCheckIn(); + $event->setCheckIn($checkIn); + + $hub->captureEvent($event); + }) + ->onFailure(function () use ($hub, $checkIn) { + $checkIn->setStatus(CheckInStatus::error()); + + $event = SentryEvent::createCheckIn(); + $event->setCheckIn($checkIn); + + $hub->captureEvent($event); + }); + }); + } + /** * Register the artisan commands. */ From d13f52900f8e8823bc8922ce1915a99555d6cf43 Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Tue, 14 Mar 2023 21:48:51 +0100 Subject: [PATCH 2/3] =?UTF-8?q?Refactor=20to=20=E2=80=9Cfeature=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Laravel/Features/ConsoleIntegration.php | 84 +++++++++++++++++++ src/Sentry/Laravel/ServiceProvider.php | 48 +---------- 2 files changed, 85 insertions(+), 47 deletions(-) create mode 100644 src/Sentry/Laravel/Features/ConsoleIntegration.php diff --git a/src/Sentry/Laravel/Features/ConsoleIntegration.php b/src/Sentry/Laravel/Features/ConsoleIntegration.php new file mode 100644 index 00000000..6701b546 --- /dev/null +++ b/src/Sentry/Laravel/Features/ConsoleIntegration.php @@ -0,0 +1,84 @@ + The list of checkins that are currently in progress. + */ + private $checkInStore = []; + + public function isApplicable(): bool + { + return $this->container()->make(Application::class)->runningInConsole(); + } + + public function setup(): void + { + SchedulingEvent::macro('sentryMonitor', function (string $monitorSlug) { + /** @var SchedulingEvent $this */ + $mutex = $this->mutexName(); + + return $this + ->before(function () use ($mutex, $monitorSlug) { + $this->startCheckIn($mutex, $monitorSlug); + }) + ->onSuccess(function () use ($mutex) { + $this->finishCheckIn($mutex, CheckInStatus::ok()); + }) + ->onFailure(function () use ($mutex) { + $this->finishCheckIn($mutex, CheckInStatus::error()); + }); + }); + } + + private function startCheckIn(string $mutex, string $slug): void + { + $options = SentrySdk::getCurrentHub()->getClient()->getOptions(); + + $checkIn = new CheckIn( + $slug, + CheckInStatus::inProgress(), + null, + $options->getEnvironment(), + $options->getRelease() + ); + + $this->checkInStore[$mutex] = $checkIn; + + $this->sendCheckIn($checkIn); + } + + private function finishCheckIn(string $mutex, CheckInStatus $status): void + { + $checkIn = $this->checkInStore[$mutex] ?? null; + + // This should never happen (because we should always start before we finish), but better safe than sorry + if ($checkIn === null) { + return; + } + + // We don't need to keep the checkin in memory anymore since we finished + unset($this->checkInStore[$mutex]); + + $checkIn->setStatus($status); + + $this->sendCheckIn($checkIn); + } + + private function sendCheckIn(CheckIn $checkIn): void + { + $event = SentryEvent::createCheckIn(); + $event->setCheckIn($checkIn); + + SentrySdk::getCurrentHub()->captureEvent($event); + } +} diff --git a/src/Sentry/Laravel/ServiceProvider.php b/src/Sentry/Laravel/ServiceProvider.php index d1ffe6be..da7ad888 100644 --- a/src/Sentry/Laravel/ServiceProvider.php +++ b/src/Sentry/Laravel/ServiceProvider.php @@ -5,16 +5,12 @@ use Illuminate\Contracts\Container\BindingResolutionException; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Http\Kernel as HttpKernelInterface; -use Illuminate\Console\Scheduling\Event as LaravelEvent; use Illuminate\Foundation\Application as Laravel; use Illuminate\Foundation\Http\Kernel as HttpKernel; use Illuminate\Log\LogManager; use RuntimeException; -use Sentry\CheckIn; -use Sentry\CheckInStatus; use Sentry\ClientBuilder; use Sentry\ClientBuilderInterface; -use Sentry\Event as SentryEvent; use Sentry\Integration as SdkIntegration; use Sentry\Laravel\Console\PublishCommand; use Sentry\Laravel\Console\TestCommand; @@ -49,6 +45,7 @@ class ServiceProvider extends BaseServiceProvider */ protected const FEATURES = [ Features\CacheIntegration::class, + Features\ConsoleIntegration::class, Features\LivewirePackageIntegration::class, ]; @@ -63,7 +60,6 @@ public function boot(): void $this->bindEvents(); $this->setupFeatures(); - $this->setupCronMonitoring(); if ($this->app->bound(HttpKernelInterface::class)) { /** @var \Illuminate\Foundation\Http\Kernel $httpKernel */ @@ -148,48 +144,6 @@ protected function setupFeatures(): void } } - /** - * Setup Cron Monitoring. - */ - private function setupCronMonitoring(): void - { - LaravelEvent::macro('sentryMonitor', function (string $monitorSlug) { - $hub = SentrySdk::getCurrentHub(); - $checkIn = new CheckIn( - $monitorSlug, - CheckInStatus::inProgress(), - null, - $hub->getClient()->getOptions()->getEnvironment(), - $hub->getClient()->getOptions()->getRelease() - ); - - /** @var \Illuminate\Console\Scheduling\Event $this */ - return $this - ->before(function () use ($hub, $checkIn) { - $event = SentryEvent::createCheckIn(); - $event->setCheckIn($checkIn); - - $hub->captureEvent($event); - }) - ->onSuccess(function () use ($hub, $checkIn) { - $checkIn->setStatus(CheckInStatus::ok()); - - $event = SentryEvent::createCheckIn(); - $event->setCheckIn($checkIn); - - $hub->captureEvent($event); - }) - ->onFailure(function () use ($hub, $checkIn) { - $checkIn->setStatus(CheckInStatus::error()); - - $event = SentryEvent::createCheckIn(); - $event->setCheckIn($checkIn); - - $hub->captureEvent($event); - }); - }); - } - /** * Register the artisan commands. */ From eacc327bd9fa7871009b1a4cb76cd07ca17e2292 Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Wed, 15 Mar 2023 11:05:26 +0100 Subject: [PATCH 3/3] Fix $this referencing wrong $this --- .../Laravel/Features/ConsoleIntegration.php | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Sentry/Laravel/Features/ConsoleIntegration.php b/src/Sentry/Laravel/Features/ConsoleIntegration.php index 6701b546..ba0b5cef 100644 --- a/src/Sentry/Laravel/Features/ConsoleIntegration.php +++ b/src/Sentry/Laravel/Features/ConsoleIntegration.php @@ -23,19 +23,27 @@ public function isApplicable(): bool public function setup(): void { - SchedulingEvent::macro('sentryMonitor', function (string $monitorSlug) { + $startCheckIn = function (string $mutex, string $slug) { + $this->startCheckIn($mutex, $slug); + }; + $finishCheckIn = function (string $mutex, CheckInStatus $status) { + $this->finishCheckIn($mutex, $status); + }; + + SchedulingEvent::macro('sentryMonitor', function (string $monitorSlug) use ($startCheckIn, $finishCheckIn) { /** @var SchedulingEvent $this */ - $mutex = $this->mutexName(); - return $this - ->before(function () use ($mutex, $monitorSlug) { - $this->startCheckIn($mutex, $monitorSlug); + ->before(function () use ($startCheckIn, $monitorSlug) { + /** @var SchedulingEvent $this */ + $startCheckIn($this->mutexName(), $monitorSlug); }) - ->onSuccess(function () use ($mutex) { - $this->finishCheckIn($mutex, CheckInStatus::ok()); + ->onSuccess(function () use ($finishCheckIn) { + /** @var SchedulingEvent $this */ + $finishCheckIn($this->mutexName(), CheckInStatus::ok()); }) - ->onFailure(function () use ($mutex) { - $this->finishCheckIn($mutex, CheckInStatus::error()); + ->onFailure(function () use ($finishCheckIn) { + /** @var SchedulingEvent $this */ + $finishCheckIn($this->mutexName(), CheckInStatus::error()); }); }); }