PABLO.ENGINEERING
// WRÓĆ DO WSZYSTKICH WPISÓW
// 2 min

Logi na VPS rosły bez końca. Ustawiłem limity i wyłapuję ciche błędy crona

Na moim małym serwerze VPS działa kilkanaście zadań w tle, kilka strażników i kontenery Docker. Najbardziej zaskoczyło mnie to, że problemem nie była pamięć RAM, tylko logi. Rosły po cichu, aż dysk zaczął się zapełniać.

Co znalazłem: dysk pęka, a zadania padają bez śladu

Zadania w cronie zapisywały wynik do plików bez dat i bez kodów wyjścia. Gdy skrypt padał, w logu zostawał tylko urwany fragment błędu i nie dało się ustalić, kiedy to się stało.

Największe pliki to nie aplikacje, tylko zapisy systemowe. Dziennik systemowy journald zajmował ponad 2 GB, kontenery Docker nie miały żadnego limitu, a w /tmp leżało prawie 1,8 GB plików, których nikt nie czyścił. Do tego strażnik kolejki budził się co 5 sekund, żeby sprawdzić pustą kolejkę, czyli około 60 razy w ciągu 5 minut.

Dlaczego to ważne

Serwer, który co noc ma pełny dysk, zawodzi w najgorszym możliwym momencie. Baza danych przestaje zapisywać, a ja dowiaduję się o tym rano. Bez dat i kodów wyjścia nawet znalezienie przyczyny zajmuje dużo czasu. Im mniej zbędnego zapisu i wybudzeń, tym mniej obciążenia dla dysku i procesora.

Jak to naprawiłem

  1. Napisałem mały wrapper run_logged.sh, który uruchamia każde zadanie crona i dopisuje do logu czas, numer procesu oraz kod wyjścia. Flaga --quiet-ok pomija wpisy po udanych zadaniach. Przepiąłem na niego 21 zadań, zamiast przerabiać każdy skrypt osobno.
  2. Ustawiłem limity: kontenery Docker przechowują po 3 pliki po 10 MB, a journald maksymalnie 2 GB. Logi crona trzymam 30 dni, logi strażników 90 dni.
  3. Strażnik kolejki budzi się co 15 sekund zamiast co 5. Wybudzeń jest teraz około 16 na 5 minut zamiast 60.
  4. Pliki z /tmp najpierw spakowałem razem z listą zawartości, a dopiero potem usunąłem oryginały. Katalog zmniejszył się z 1,8 GB do 45 MB, a w razie potrzeby da się wszystko odtworzyć.

Czego się nauczyłem

  • Zadanie bez polityki przechowywania logów to przyszła awaria. Każdy plik, który rośnie, potrzebuje limitu.
  • Logi powinny krzyczeć tylko wtedy, gdy coś poszło źle. Zapis udanych przebiegów to szum.
  • Jeden wrapper na poziomie crona zabezpiecza wszystkie zadania naraz. Poprawianie każdego skryptu osobno zajęłoby dużo czasu i łatwo byłoby coś przeoczyć.
#devops#automation#observability