Aby monitorować zadanie cron, daj mu heartbeat: unikalny adres URL, który zadanie wywołuje za każdym razem, gdy się zakończy. Usługa monitorująca oczekuje tego żądania w regularnych odstępach. Jeśli nie dotrze na czas, bo zadanie się nie uruchomiło, uległo awarii albo się zawiesiło, dostajesz alert. Wystarczy jedna dodatkowa linia w crontabie.
Ten poradnik pokazuje, jak działają heartbeaty, jak je dodać i jak dobrać odpowiednie ustawienia.
Dlaczego zadania cron potrzebują własnego monitoringu
Cron niezawodnie uruchamia polecenia, ale milczy o tym, co dzieje się dalej. Jeśli skrypt kopii zapasowej zawiedzie o 02:00, nic widocznego się nie psuje. Strona dalej działa, a testy dostępności świecą na zielono. Dowiadujesz się o tym po kilku tygodniach, gdy potrzebujesz kopii zapasowej, a jej nie ma.
Typowe ciche awarie:
W zaplanowanym czasie serwer nie działał albo się restartował.
Crontab został nadpisany podczas wdrożenia lub migracji serwera.
Polecenie nie działa pod cronem, bo PATH lub inne zmienne środowiskowe różnią się od tych w Twojej powłoce.
Skrypt się uruchamia, ale zawiesza się na blokadzie, wywołaniu sieciowym albo pełnym dysku.
Dane uwierzytelniające wygasły, więc zadanie startuje i kończy się błędem, którego nikt nie czyta.
Monitorowanie dostępności nie widzi żadnej z tych sytuacji, bo nic publicznego się nie psuje. Heartbeat działa odwrotnie: zamiast monitora sprawdzającego Twoje zadanie to zadanie zgłasza się do monitora.
Jak działa heartbeat
Tworzysz monitor heartbeat i dostajesz unikalny adres URL.
Określasz, kiedy zadanie ma się uruchamiać: jako interwał, np. co 24 godziny, albo jako harmonogram z crontaba tego zadania, z pewnym zapasem na wolniejsze uruchomienia.
Po zakończeniu zadanie wywołuje adres URL metodą GET lub POST.
Jeśli żądanie nie dotrze na czas, otwiera się incydent i wychodzą alerty.
Gdy dotrze kolejny ping, heartbeat wraca do normy, a Ty dostajesz powiadomienie o przywróceniu działania.
Tak działają monitory cron w Uptimecheck. Przyjmują harmonogram z crontaba w Twojej strefie czasowej, akceptują pingi startu i zakończenia w jednym monitorze, wysyłają alert, gdy uruchomienie przekroczy maksymalny czas działania, i mogą zapisywać kod wyjścia oraz dane wyjściowe zadania. Alerty trafiają na e-mail, Slack, Microsoft Teams, Discord, Google Chat, Mattermost, Telegram, PagerDuty, ntfy, Pushover, webhooki i jako powiadomienia push na telefon, w każdym planie.
Dodawanie heartbeatu do crontaba
Załóżmy, że kopia zapasowa uruchamia się co noc o 02:30:
30 2 * * * /usr/local/bin/backup.sh
Dodaj ping po zadaniu, łącząc je przez &&, aby uruchamiał się tylko wtedy, gdy kopia zapasowa się powiedzie:
30 2 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 –retry 3 https://heartbeat.example.com/your-unique-id > /dev/null
Co robią opcje curl:
-f sprawia, że curl zwraca błąd przy błędach HTTP, zamiast traktować je jako sukces.
-s wycisza komunikaty, a -S mimo to pokazuje błędy, jeśli coś pójdzie nie tak.
-m 10 przestaje czekać po 10 sekundach, więc wolna sieć nigdy nie zablokuje zadania.
–retry 3 ponawia próbę przy krótkich problemach z siecią.
W miejsce przykładowego adresu wstaw dokładny adres URL ze swojego monitora heartbeat.
Ping z wnętrza skryptu
W dłuższych skryptach umieść ping na końcu samego skryptu, po krokach, które mają znaczenie:
#!/usr/bin/env bash
set -euo pipefail
pg_dump northwind > /backups/northwind-$(date +%F).sql
gzip /backups/northwind-$(date +%F).sql
curl -fsS -m 10 –retry 3 https://heartbeat.example.com/your-unique-id > /dev/null
Dzięki set -e skrypt zatrzymuje się na pierwszym nieudanym poleceniu, więc ping jest wysyłany tylko wtedy, gdy wszystko wcześniej zadziałało.
Inne harmonogramy
Heartbeaty nie ograniczają się do crona. Pingować może wszystko, co potrafi wysłać żądanie HTTP: timery systemd, Harmonogram zadań Windows z poleceniem PowerShell Invoke-WebRequest, CronJob w Kubernetes, pipeline CI albo zaplanowana funkcja w Twojej aplikacji.
Wybór interwału
Interwał powinien odpowiadać harmonogramowi: 24 godziny dla zadania nocnego, 1 godzina dla zadania cogodzinnego. Zostaw zapas na normalne różnice w czasie trwania zadania. Jeśli kopia zapasowa trwa zwykle 20 minut, ale czasem 50, dodatkowa godzina zapasu pozwala uniknąć fałszywych alarmów, nie ukrywając przy tym długo prawdziwej awarii.
Zacznij od hojnego zapasu, przez tydzień lub dwa obserwuj, ile naprawdę trwają uruchomienia, a potem go zawęź. Jeśli Twój monitor przyjmuje samo wyrażenie z crontaba, tak jak monitor w Uptimecheck, wklej harmonogram i wybierz strefę czasową serwera. Oczekiwane czasy będą wtedy dokładnie odpowiadać harmonogramowi, a zapas stanie się okresem tolerancji.
Heartbeaty a inne podejścia
Zaplanowane zadania można pilnować też na inne sposoby, ale każdy ma luki:
E-maile z crona. Cron może wysyłać e-mailem wynik polecenia, ale tylko wtedy, gdy zadanie się uruchomi i coś wypisze. Jeśli zadanie w ogóle nie wystartuje, e-maila nie ma. A większość takich e-maili i tak pozostaje nieprzeczytana.
Monitorowanie logów. Przydaje się do szukania błędów, ale zadanie, które się nie uruchomiło, nie zostawia w logu żadnej linii do wyszukania.
Sprawdzanie wyników. Niektóre zespoły sprawdzają, czy istnieje plik kopii zapasowej albo czy tabela została zaktualizowana. To działa, ale wymaga osobnych testów dla każdego zadania.
Heartbeat działa tak samo dla każdego zadania i wychwytuje przypadek, który inne metody pomijają: zadanie, które w ogóle się nie uruchomiło.
Długo trwające zadania
W przypadku zadań, które trwają długo, takich jak duże kopie zapasowe czy migracje danych, wysyłaj ping zarówno na początku, jak i na końcu. Jeśli ping startowy dotrze, a końcowy nie, zadanie zawiesiło się lub uległo awarii w połowie. Wiesz wtedy, gdzie szukać, zanim otworzysz choćby jeden plik logu.
W Uptimecheck oba pingi trafiają do tego samego monitora: gdy zadanie się zaczyna, wywołaj adres URL z dopisanym /start, a gdy się kończy, sam adres. Czas pomiędzy nimi jest zapisywany jako czas działania, a jeśli ustawisz maksymalny czas działania, dostaniesz alert, gdy uruchomienie potrwa dłużej.
Którym zadaniom dać heartbeat
Nie każde zadanie go potrzebuje. W pierwszej kolejności zajmij się zadaniami, których awarię zauważyłbyś dopiero później:
Kopie zapasowe baz danych i plików.
Importy i eksporty danych, np. feedy produktowe lub synchronizacja z księgowością.
Wystawianie faktur, odnowienia i zadania rozliczeniowe.
Zadania odnawiające certyfikaty.
Czyszczenie, które chroni dysk przed zapełnieniem.
Generowanie raportów, od których zależą inni.
Daj każdemu zadaniu własny heartbeat. Wspólny powie Ci, że coś się nie uruchomiło, ale nie powie co.
Co zrobić, gdy heartbeat nie dotarł
Gdy przychodzi alert heartbeat:
Sprawdź, czy cron uruchomił zadanie. Zajrzyj do logu crona lub logu systemowego.
Uruchom polecenie ręcznie jako ten sam użytkownik, którego używa cron, i przeczytaj wynik.
Sprawdź środowisko. Używaj ścieżek bezwzględnych albo ustaw PATH na początku crontaba.
Sprawdź zasoby. Pełny dysk lub wyczerpana pamięć zatrzymują wiele zadań. Monitorowanie serwerów pokazuje dysk, RAM i obciążenie w chwili awarii.
Sprawdź ruch wychodzący. Zmiana w firewallu może zablokować ping, nawet gdy zadanie działa. Jeśli zadanie się wykonało, a ping się nie powiódł, błąd curl pojawi się w danych wyjściowych zadania.
Przekieruj dane wyjściowe zadania do pliku logu, żeby zawsze było co przeczytać:
30 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1 && curl -fsS -m 10 https://heartbeat.example.com/your-unique-id > /dev/null
Wynik możesz też wysłać razem z pingiem. W Uptimecheck zakończenie adresu URL kodem wyjścia (/0 oznacza sukces, każda inna wartość błąd) informuje, jak zakończyło się zadanie, a treść żądania POST jest zapisywana jako dane wyjściowe zadania i pokazywana razem z alertem. Ta linia wysyła ping na starcie, uruchamia zadanie i zgłasza jego kod wyjścia oraz dane wyjściowe:
30 2 * * * curl -fsS -m 10 –retry 3 -o /dev/null https://heartbeat.example.com/your-unique-id/start; /usr/local/bin/backup.sh > /tmp/backup.log 2>&1; curl -fsS -m 10 –retry 3 –data-binary @/tmp/backup.log -o /dev/null https://heartbeat.example.com/your-unique-id/$?
Lista kontrolna monitorowania zadań cron
Spisz ważne zaplanowane zadania na każdym serwerze.
Utwórz jeden heartbeat na zadanie.
Wysyłaj ping po udanym wykonaniu pracy, łącząc go przez && albo umieszczając na końcu skryptu z set -e.
Ustaw interwał zgodny z harmonogramem, z zapasem na wolniejsze uruchomienia.
Zapisuj dane wyjściowe zadania do pliku.
Wysyłaj alerty na kanał, który ktoś czyta, także w nocy w przypadku krytycznych zadań.
Przeglądaj historię heartbeatów po wdrożeniach i migracjach serwerów.
Podsumowanie
Cron nie powie Ci, że zadanie zawiodło. Heartbeat tak. Jedna linia z curl na zadanie zamienia ciche awarie w alerty, a historia pokazuje dokładnie, kiedy każde zadanie uruchomiło się po raz ostatni.
Heartbeaty są dostępne w każdym planie Uptimecheck, razem z monitorowaniem dostępności, SSL, domen, DNS i serwerów. Wypróbuj za darmo przez 14 dni, bez karty kredytowej.