Article in English can be found on dev.to/arxeiss/cron-monitoring-for-better-sleep-3o4g
Chyby, které se projevují přímo uživateli většinou někdo nahlásí, protože jim to nefunguje před očima. Když se ale přestane spouštět pravidelná úloha, může to trvat, než si to někdo uvědomí. Proto je vhodné takové úlohy monitorovat. A nemusí to být vůbec složitá ani drahá záležitost.
Každý určitě slyšel historku o nefungujících zálohách databáze. Na které se přišlo až v momentě, kdy tato záloha byla potřeba. Stačilo však monitorovat, že se zálohy pravidelně spouštějí.
Healthchecks.io - Dead's man switch
Již dříve jsem psal článek o Cron jobu, službě, která dokáže spouštět v pravidelných intervalech skripty na webových adresách. Co když ale skript vrátí kód 200, ale reálně se nic neprovede? Přijít na takovou chybu může být komplikované, nebo se na to může přijít pozdě. Naštěstí služba Healthchecks.io s tím může dosti pomoct. A pro malé projekty nabízí velmi štědrý tarif zdarma.
Služba funguje na principu tlačítka mrtvého muže. Je tedy nutné službu notifikovat vždy v určený interval, že operace proběhla. A pokud se tak nestane, služba začne odesílat notifikace. Například na email, telefon (hovor i SMS), Slack, Discord, Teams, Trello, Whatsapp a dalších 16 služeb.
Kontrolu lze nastavit buď zadáním intervalu v jakém se úloha má spouštět. Nebo definováním pomocí Cron syntaxe včetně časového pásma. Kromě toho lze nastavit tzv. Grace time, který definuje, jak dlouho se může úloha zpozdit, než bude odeslána notifikace.
Success Ping, Start, Fail, Exit code
Nejjednodušší je používat pouze Ping endpoint. Tím se službě řekne, že vše proběhlo. Endpoint Start pak slouží k notifikaci, že úloha začala. Pokud do nastaveného limitu není odeslán Ping, opět se odesílá notifikace. Lze tak detekovat zacyklené úlohy. Endpointy Fail a Exit code slouží k notifikování chyby. Exit code navíc umožňuje specifikovat číselný chybový kód. U všech endpointů lze navíc v těle zprávy odeslat také až 10 kB log. Vše je krásně popsáno v dokumentaci.
Pro zachytávání chyb a výjimek nedoporučuji používat log v Healthchecks, není na to určen. Lepší je použít službu Sentry, o které jsem psal dříve Sentry - Jak a proč logovat chyby.
HTTP požadavky a Retry
Odesílání signálů přes HTTP není příliš spolehlivé. Často se stane, že request trvá příliš dlouho, nebo se prostě ztratí. Proto je vhodné nastavit rozumný timeout a také opakování pokusů. Kód níže může posloužit jako zjednodušení pro Laravel projekty. Ideální by bylo použít Retry plugin, ale i obyčejný for
cyklus může postačit pro tento jednoduchý případ.
<?php namespace App\Services; use GuzzleHttp\Client; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Log; class HealthChecksService { private $client; public function __construct() { $this->client = new Client([ 'base_uri' => Config::get('healthchecks.api_endpoint') ]); } private function makeRequest(string $action, string $checkName, string $log = ""): void { $options = [ 'timeout' => 2, 'connect_timeout' => 2, 'body' => $log, ]; $exception = null; $i = 0; for (; $i < 3; $i += 1) { try { $this->client->request('POST', \rtrim("/{$action}", '/'), $options); $exception = null; break; } catch (\Throwable $e) { $exception = $e; \usleep(\pow(2, $i) * 500000); } } if ($exception) { Log::warning( 'Cannot perform HealthChecks request', ['checkName' => $checkName, 'action' => $action, 'exception' => $exception, 'retry' => $i + 1], ); } } public function start(string $checkName): void { $this->makeRequest('start', $checkName); } public function success(string $checkName, string $log = ""): void { $this->makeRequest('', $checkName, $log); } public function exitStatus(string $checkName, $exitStatus, string $log = ""): void { $this->makeRequest("$exitStatus", $checkName, $log); } }
Máte zkušenosti s monitorováním Cron úloh pomocí jiných služeb? Podělte se v komentářích
K tomuto článku již není možné přidávat další komentáře