Monitorowanie Linuxa dla webmastera: narzędzia do CPU, RAM, IO i logów w praktyce

0
50
Rate this post

Z tego tekstu dowiesz się...

Perspektywa webmastera: czego naprawdę trzeba pilnować w Linuxie

Monitoring oczami webmastera, a nie „pełnego” administratora

Webmastera nie interesuje stan każdego demona w systemie, tylko to, czy serwis ładuje się szybko, stabilnie i bez błędów. Monitoring Linuxa z tej perspektywy to nie kolekcjonowanie wszystkich możliwych metryk, ale skupienie się na kilku zasobach bezpośrednio wpływających na czas ładowania strony i błędy HTTP. Minimum to CPU, RAM, IO, sieć oraz logi serwera WWW i aplikacji.

System może mieć drobne ostrzeżenia w logach kernela i nadal działać bezproblemowo dla użytkowników, ale już małe opóźnienia w odpowiedzi bazy danych czy przepełniony dysk szybko przełożą się na 500 Internal Server Error. Z tego powodu priorytetem nie jest „czystość” systemu, tylko zdolność serwera do szybkie obsługi żądań HTTP i zapytań do bazy.

Monitoring dla webmastera to narzędzie decyzyjne: czy poprawiać kod, czy zmieniać konfigurację, czy skalować infrastrukturę. Żeby móc odpowiedzieć na te pytania, potrzebny jest stały zestaw poleceń i schemat diagnostyki, który da się powtórzyć przy każdym problemie, także pod presją czasu.

Kluczowe zasoby dla typowego stacku WWW

W typowym środowisku dla stron WWW (Nginx/Apache, PHP-FPM, MySQL/MariaDB, ewentualnie Redis/Memcached) krytyczne zasoby to:

  • CPU – wykonywanie kodu PHP, kompresja gzip, szyfrowanie TLS, sortowanie wyników w bazie.
  • RAM – cache w bazie, cache PHP OPCache, pamięć dla procesów PHP-FPM, buforowanie plików przez kernel.
  • IO dyskowe – odczyt plików aplikacji, zapis logów, odczyt/zapis tabel bazy danych, pliki tymczasowe uploadów.
  • Sieć – przepustowość, opóźnienia, kolejki połączeń na porcie HTTP/HTTPS, połączenia do bazy na innym serwerze.
  • Logi – błędy PHP, timeouty bazy, błędy 5xx z serwera WWW, wpisy OOM killera, ostrzeżenia o braku miejsca na dysku.

Każdy z tych zasobów może stać się „wąskim gardłem”. Dopiero zestawiając objawy widoczne z poziomu przeglądarki (czas TTFB, błędy, przerwy w działaniu) z realnymi danymi z systemu Linux, można wskazać przyczynę, zamiast zgadywać na oślep.

Typowe objawy z punktu widzenia użytkownika i biznesu

Dla właściciela serwisu i odwiedzających liczy się tylko efekt:

  • strony ładują się coraz wolniej, chociaż ruch nie rośnie w zauważalny sposób,
  • pojawiają się sporadyczne błędy 502/504 (gateway timeout) lub 500 (internal server error),
  • czasem wszystko działa bardzo szybko, a czasem następują „zawieszki” na kilka–kilkanaście sekund,
  • w trakcie kampanii lub promocji strona „pada” mimo zapewnień, że serwer jest „mocny”,
  • panel administracyjny (np. WordPress) muli, gdy strona główna dla zwykłych użytkowników ładuje się w miarę poprawnie.

Każdy z tych objawów powinien prowadzić do powtarzalnej checklisty diagnostycznej: sprawdzenie CPU, RAM, IO, sieci i logów według tego samego schematu, zamiast przypadkowego „klikania” po serwerze.

Prosty model przepływu żądania HTTP

Trudno skutecznie monitorować Linuxa, nie mając w głowie prostego modelu, gdzie szukać problemu. Minimalny model dla webmastera wygląda tak:

Przeglądarka → sieć → serwer WWW (Nginx/Apache) → interpreter (PHP-FPM/Node) → baza danych / cache → dysk / sieć zewnętrzna

W każdym z tych punktów może powstać opóźnienie:

  • serwer WWW – za mało workerów, kolejkowanie żądań, blokujące moduły, błąd w konfiguracji wirtualnych hostów,
  • PHP-FPM – za mało/zbyt dużo procesów, długie wykonywanie scriptów, blokujące funkcje (file_get_contents na zewnętrzne URL-e),
  • baza SQL – brak indeksów, zbyt duże zapytania, zablokowane transakcje,
  • dysk – duże I/O wait, procesy backupu, agresywnie zapisujące logi,
  • sieć – problemy z DNS, limity na interfejsie, opóźnienia do serwera bazy lub zewnętrznych API.

Jeśli użytkownik widzi „kółeczko ładowania” przez kilka sekund, a potem stronę – trzeba sprawdzić, na którym etapie żądanie utknęło. Monitoring Linuxa musi dostarczyć danych dla każdego z tych elementów, choćby w minimalnym zakresie.

Punkt kontrolny przed wdrożeniem projektu

Jeszcze przed wdrożeniem serwisu, webmaster powinien znać podstawowe parametry środowiska, na którym będzie działał kod. Minimum to:

  • liczba vCPU (rdzeni logicznych) – np. polecenie nproc,
  • ilość RAMfree -h,
  • typ dysku – SSD/NVMe vs HDD (często widoczne w panelu VPS lub z lsblk),
  • informacja o limitach IOPS / przepustowości dysku (z dokumentacji dostawcy VPS),
  • system plików i sposób montowania (np. opcje noatime mogą zmniejszyć I/O).

Jeżeli te dane są nieznane, każdy problem wydajnościowy staje się trudniejszy do oceny – nie wiadomo, czy serwer rzeczywiście jest przeciążony, czy po prostu jest zbyt słaby na zakładany ruch.

Jeżeli przed startem projektu zostanie zebrane to absolutne minimum informacji o zasobach, ocena późniejszych metryk CPU, RAM i IO będzie znacznie bardziej rzetelna.

Minimum narzędzi wbudowanych w każdą dystrybucję

Podstawowe polecenia: uptime, free, df, du, ps, top

Nawet na bardzo okrojonym serwerze Linux bez dodatkowych pakietów da się przeprowadzić prosty monitoring. Kluczowe polecenia, które praktycznie zawsze są dostępne:

  • uptime – pokazuje czas działania systemu, liczbę zalogowanych użytkowników oraz load average,
  • free -h – szybki podgląd użycia pamięci RAM i swapu,
  • df -h – użycie przestrzeni dyskowej na partycjach,
  • du -sh /ścieżka – rozmiar katalogu, np. /var/log lub katalogu projektu,
  • ps aux – lista procesów z użyciem CPU i pamięci,
  • top – interaktywny podgląd użycia CPU, RAM, procesów.

Na serwerze, do którego dostęp jest tylko przez SSH, te komendy stanowią monitoring „pierwszego kontaktu”. Dobrze je mieć w jednym, spójnym schemacie działania, zamiast uruchamiać je przypadkowo.

Interpretacja load average z uwzględnieniem vCPU

Load average z polecenia uptime (lub góry ekranu w top) ma sens tylko w odniesieniu do liczby dostępnych rdzeni. Load to średnia liczba procesów oczekujących na CPU lub I/O. Przykładowa linia:

load average: 0.50, 0.80, 1.20

Odpowiednio: średnia z 1, 5 i 15 minut. Punkt kontrolny wygląda inaczej na 1 vCPU i na 4 vCPU:

  • serwer 1 vCPU: load ~1.0 to już pełne obciążenie CPU – powyżej 1.0 to kolejka,
  • serwer 4 vCPU: load 1.0 oznacza użycie około 25% mocy, dopiero load ~4.0 to pełne zajęcie rdzeni.

Interpretacja:

  • load < liczba rdzeni – system ma zapas mocy,
  • load ≈ liczba rdzeni – system jest mocno zajęty, ale jeszcze pracuje płynnie,
  • load > 2 × liczba rdzeni – sygnał ostrzegawczy, czas sprawdzić, które procesy blokują CPU lub IO.

Jeśli load rośnie głównie z powodu I/O wait (widziane w top jako wa), wąskim gardłem jest dysk, a nie procesor.

free -m i /proc/meminfo: prawda o „pełnym” RAM-ie

Nowicjusze często widzą w free -m „prawie pełny” RAM i wyciągają błędny wniosek, że system potrzebuje więcej pamięci. Linux agresywnie używa wolnej pamięci jako cache dla plików, co jest pożądane. Kluczowa jest kolumna available, a nie surowe used.

Przykład:

free -m
              total        used        free      shared  buff/cache   available
Mem:           3944        1200         150          30        2594        2400
Swap:          2047          10        2037

Mimo że „used” wygląda duże, available = 2400 MB oznacza, że aplikacje mają jeszcze około 2,4 GB do dyspozycji. Część „used” to cache, który system może zwolnić przy potrzebie.

Dodatkowe szczegóły można podejrzeć w /proc/meminfo, np.:

  • Cached – pamięć używana na cache plików,
  • Buffers – bufory bloków,
  • SwapTotal/SwapFree – informacja o swapie.

Jeżeli available spada poniżej kilkunastu procent całości i system zaczyna używać swapu, to dopiero wtedy jest realny sygnał ostrzegawczy. Samo „wysokie used” nie powinno być powodem paniki.

df -h: kontrola miejsca na dysku przed zmianami

Brak miejsca na dysku potrafi zatrzymać logowanie, aktualizacje, a nawet działanie baz danych. df -h to punkt kontrolny obowiązkowy przed:

  • aktualizacją CMS (WordPress, Joomla, sklepy),
  • większym importem danych do bazy,
  • wgrywaniem dużej ilości plików (media, backupy, archiwa).

Przykład użycia:

df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        40G   30G   8G   80% /

Powierzchnia przy ~80–85% użycia to jeszcze normalna sytuacja, ale okolicę 95–100% należy traktować jako stan krytyczny. Warto okresowo (np. raz w tygodniu) sprawdzać:

  • du -sh /var/log – czy logi nie „puchną” bez kontroli,
  • du -sh /home lub katalogu projektu – rosnące uploady, cache, backupy wewnątrz projektu.

Jeśli /var/log lub katalog projektu zaczyna zajmować nieproporcjonalnie dużo miejsca, priorytetem staje się konfiguracja logrotate i usunięcie starych, niepotrzebnych danych.

Monitoring „minimum” przez SSH

Jeżeli nie ma dostępu do żadnych zewnętrznych systemów monitoringu, warto mieć własną, krótką check-listę komend, które dają szybki obraz sytuacji:

  • uptime – ocena load average vs liczba vCPU,
  • free -h – szybki rzut oka na available RAM i swap,
  • df -h – użycie przestrzeni dyskowej,
  • top – które procesy pochłaniają CPU/RAM,
  • tail -n 50 /var/log/syslog lub journalctl -xe – ostatnie błędy systemowe,
  • tail -n 50 /var/log/nginx/error.log lub apache2/error.log – błędy serwera WWW.

Jeśli tym zestawem komend da się przejść przez podstawową diagnozę, to znaczy, że monitoring minimum jest osiągnięty. W następnym kroku można go rozwijać, dokładkając bardziej wyspecjalizowane narzędzia dla CPU, RAM, IO i logów.

Monitorowanie CPU: identyfikacja „zabójców” procesora

top i htop: podstawowe narzędzia podglądu CPU

top jest domyślnie obecny w większości dystrybucji, htop zwykle trzeba doinstalować (apt install htop, yum install htop). Różnice:

  • top – bardziej surowy interfejs, ale zawsze dostępny,
  • htop – kolorowy interfejs, wygodniejsze sortowanie, podgląd drzew procesów i wątków.

W top kluczowe skróty:

  • P – sortowanie po CPU,
  • M – sortowanie po pamięci,
  • 1 – przełączanie widoku na poszczególne rdzenie CPU (w nowszych wersjach),
  • Shift + H – pokazanie wątków zamiast tylko procesów.

W praktyce analiza CPU w top/htop powinna przebiegać według stałego schematu. Najpierw górna linia: obciążenie CPU z podziałem na us (użytkownik), sy (kernel), wa (I/O wait). Jeśli us jest wysokie – procesy aplikacyjne realnie „palą” procesor. Jeżeli dominuje sy, problemem jest intensywna praca jądra (np. sieć, dysk, system plików). Z kolei wysoki wa oznacza, że procesy czekają na dysk i same w sobie nie są bezpośrednim winowajcą.

Dopiero po tej ocenie ma sens sortowanie listy procesów. Dwa podstawowe widoki: sortowanie po CPU i po pamięci, najlepiej przełączane naprzemiennie. Przykładowy scenariusz: PHP-FPM zajmuje 300% CPU na maszynie 4 vCPU – wtedy naturalnym krokiem jest sprawdzenie liczby procesów PHP, limitów w pm.max_children oraz logów błędów. Jeśli natomiast MySQL pokazuje umiarkowane użycie CPU, ale load average jest wysoki, a wa rośnie, to silniejsze podejrzenie pada na wolne zapisy na dysk niż na samą bazę.

W htop przydaje się widok drzewka procesów (klawisz F5), który pokazuje, co jest właścicielem danego procesu. Dla webmastera to prosty sposób, żeby zobaczyć pełną „rodzinę” usług: np. apache2 i jego workerów, proces główny php-fpm oraz potomne skrypty, czy mysqld i wątki robocze. Dobrą praktyką jest zapamiętanie typowego obrazu dla zdrowego serwera i porównywanie z nim sytuacji awaryjnej – wtedy szybko widać, że np. pojawiły się dziesiątki nowych procesów CLI, które wcześniej nie występowały.

Punkt kontrolny: jeśli load average przez kilka minut utrzymuje się powyżej liczby vCPU, w top widać stale kilka tych samych procesów na górze listy, a us lub sy jest podwyższone – problem jest w CPU i konfiguracji aplikacji lub serwera WWW. Jeśli natomiast load jest wysoki, ale dominują wa i procesy I/O (np. backup, intensywne importy), priorytetem staje się analiza dysku i kolejek zapisu. W obu przypadkach taki szybki audyt daje webmasterowi jasny kierunek działania, zamiast chaotycznego „restartowania wszystkiego”.

Dobrze ułożony monitoring – od prostych komend SSH, przez systematyczną analizę CPU, RAM i IO, po kontrolę logów – zamienia doraźne gaszenie pożarów w przewidywalny proces. Jeśli na każdym z tych poziomów istnieje choćby podstawowe minimum punktów kontrolnych, diagnoza problemów z wydajnością przestaje być zgadywanką, a staje się powtarzalnym audytem, który można przeprowadzić szybko nawet w stresie produkcyjnej awarii.

sar i mpstat: historia obciążenia zamiast „migawki”

Same top i htop pokazują tylko bieżący stan. Jeśli użytkownicy zgłaszają problem „wczoraj o 14:00 wszystko stało”, potrzebny jest wgląd historyczny. Dostarcza go pakiet sysstat, w którym kluczowe narzędzia to sar i mpstat.

Instalacja i włączenie zbierania danych (przykładowo w Debian/Ubuntu):

apt install sysstat
# w /etc/default/sysstat ustaw:
ENABLED="true"
systemctl enable --now sysstat

Podstawowe użycia:

  • sar -u 1 5 – 5 odczytów zużycia CPU co 1 sekundę,
  • sar -u -f /var/log/sysstat/saXX – przegląd dziennego logu (XX – dzień miesiąca),
  • mpstat -P ALL 1 – podgląd obciążenia wszystkich rdzeni co 1 s.

Przy diagnozie skoków CPU istotne są kolumny:

  • %user – kod aplikacji,
  • %system – jądro (syscalls, sterowniki, sieć),
  • %iowait – czekanie na I/O,
  • %steal – wirtualizacja „kradnąca” czas CPU (częste na tanich VPS).

Jeżeli w godzinach szczytu w sar -u widać utrzymujące się wysokie %steal, problem leży po stronie dostawcy VPS, a nie w konfiguracji serwera WWW. Z kolei stałe 80–90% %user w tych samych godzinach wskazuje na realny brak mocy obliczeniowej lub zbyt ciężkie zapytania do aplikacji.

Punkt kontrolny: jeśli incydenty wydajności występują o konkretnych porach, pierwszym krokiem jest przegląd historii z sar. Jeżeli w logach sysstat nie widać wyraźnych pików obciążenia CPU, winy należy szukać raczej w I/O, sieci lub zewnętrznych integracjach.

Monitorowanie RAM: kiedy brak pamięci zabija wydajność

top, htop i wskaźniki OOM: pierwsze sygnały problemów z pamięcią

W top/htop oprócz CPU należy stale obserwować:

  • kolumnę RES – fizycznie zajęta pamięć przez proces,
  • kolumnę VIRT – przestrzeń adresowa (mniej istotna dla praktyka),
  • wartość swap used w podsumowaniu pamięci.

Sygnały ostrzegawcze:

  • rosnące użycie swapu przy jednoczesnym spadku available w free -m,
  • pojedyncze procesy (np. php-fpm, java, node) z RES rosnącym w czasie bez powrotu w dół,
  • nagle ubite procesy aplikacji, mimo że nikt ich nie restartował.

To ostatnie wymaga weryfikacji w logach kernela. Wystąpienie OOM (Out Of Memory) najprościej zlokalizować tak:

dmesg | grep -i "out of memory"
journalctl -k | grep -i "killed process"

Jeśli pojawia się Out of memory: Killed process ..., system wybrał „ofiarę”, żeby uratować się przed całkowitym brakiem pamięci. Najczęściej cierpią na tym PHP-FPM, MySQL/PostgreSQL lub serwery aplikacyjne.

Punkt kontrolny: jeśli zauważalne są sporadyczne restarty usług bez czytelnej przyczyny, sprawdzenie logów OOM i bieżącego zużycia swapu jest obowiązkowe, zanim zacznie się podejrzewać „błędy w aplikacji”.

ps, smem i sortowanie po zużyciu pamięci

Do dokładniejszej identyfikacji „pożeraczy” RAMu przydaje się ps z odpowiednimi kolumnami albo narzędzia pokroju smem. Przykładowe komendy:

ps aux --sort=-%mem | head -n 15
ps -eo pid,ppid,user,pmem,pcpu,rss,vsz,command --sort=-rss | head -n 15

Interpretacja:

  • RSS – realny, fizyczny przydział pamięci (w KB),
  • VSZ – wirtualny rozmiar, często wielokrotnie większy niż realne użycie,
  • %MEM – udział procesu w całości RAM.

Jeżeli kilka procesów tej samej usługi (np. php-fpm) ma porównywalne, stabilne zużycie pamięci, konfiguracja zwykle jest poprawna. Problemem jest sytuacja, w której pojedyncze procesy skokowo rosną i nie zwalniają zasobów – to sygnał wycieków pamięci lub błędnych limitów (np. memory_limit w PHP ustawione abstrakcyjnie wysoko).

Po zainstalowaniu smem:

apt install smem
smem -r -k
smem -r -k -s uss | head

Kolumny USS (unikalna pamięć) i PSS (proporcjonalnie dzielona pamięć współdzielona) dają bardziej realistyczny obraz, gdy aplikacje korzystają z bibliotek współdzielonych i procesów potomnych. Dla webmastera to szczególnie użyteczne przy debugowaniu dużych stosów (Nginx + PHP-FPM + Redis + MySQL) – łatwiej ocenić, czy to Redis „puchnie”, czy jednak MySQL rezerwuje zbyt wiele buforów.

Punkt kontrolny: jeżeli ps pokazuje jeden typ procesu dominujący w zużyciu RAM, a dostępna pamięć spada do dolnych kilkunastu procent, naturalnym krokiem jest przegląd konfiguracji tej konkretnej usługi (limity workerów, buffory, cache wewnętrzne), a nie globalne „dokładanie RAMu w ciemno”.

Konfiguracja PHP-FPM, MySQL i cache pod kątem RAM

Najczęstsze przypadki nadmiernego zużycia pamięci na serwerach WWW to:

  • zbyt wysoka liczba procesów PHP-FPM w stosunku do RAM,
  • przekombinowane buffory MySQL/PostgreSQL,
  • nieograniczone cache w aplikacji lub w Redis/Memcached.

Przy PHP-FPM podstawowa kalkulacja wygląda następująco:

  1. zmierzyć średnie zużycie RAM jednego procesu php-fpm (RES),
  2. oszacować dostępny RAM dla PHP (całkowity – system – baza – inne usługi),
  3. dobrać pm.max_children tak, aby liczba_procesów × RAM_na_proces mieściła się w bezpiecznej rezerwie.

Przykładowo, jeśli pojedynczy proces PHP zużywa przeciętnie 100 MB, a realnie dostępne jest ~1,5 GB dla warstwy aplikacyjnej, pm.max_children ustawione na 50 to przepis na OOM. Dla takiego środowiska rozsądne będzie 10–12 procesów, połączone z mechanizmem kolejkowania żądań HTTP (np. przez workerów Nginx/Apache).

Przy MySQL sensowne jest użycie skryptów typu mysqltuner.pl, ale punktem wyjścia powinny być kluczowe parametry:

  • innodb_buffer_pool_size – najważniejszy bufor, często wystarczy 50–70% dostępnego RAM bazy,
  • query_cache_size (w starszych wersjach) – nadmiernie duży cache potrafi zaszkodzić,
  • tmp_table_size i max_heap_table_size – za duże wartości mnożone przez liczbę połączeń to czytelny sposób na zjedzenie RAM.

Jeżeli monitoring pokazuje, że MySQL stale rezerwuje kilka gigabajtów, a realny ruch i rozmiar danych są umiarkowane, warto przeprowadzić audyt konfiguracji w oparciu o rzeczywiste potrzeby aplikacji, zamiast bezmyślnie „podbijać” wartości z poradników.

Punkt kontrolny: jeśli OOM dotyka głównie PHP-FPM lub MySQL, pierwszym krokiem jest przeliczenie limitów procesów i buforów w oparciu o realnie dostępny RAM i średnie zużycie, a dopiero drugim rozważanie rozbudowy serwera.

Monitorowanie IO i dysku: jak rozpoznać wąskie gardło storage

iostat, iotop i vmstat: identyfikacja problemów z I/O

Gdy load average jest wysoki, CPU nie wygląda na mocno zajęte, a w top dominuje wa, konieczna jest analiza I/O. Podstawowy zestaw obejmuje iostat, iotop i vmstat.

iostat (część pakietu sysstat):

iostat -x 1 10

Wynik dla każdego dysku zawiera m.in.:

  • r/s, w/s – liczba operacji odczytu/zapisu na sekundę,
  • rkB/s, wkB/s – przepustowość,
  • await – średni czas obsługi żądania (ms),
  • util – procentowy czas zajęcia urządzenia (0–100%).

Sygnał ostrzegawczy: await rosnące znacznie powyżej kilku–kilkunastu ms na dyskach SSD oraz util utrzymujące się blisko 100%. W takim scenariuszu każda operacja dyskowa jest blokowana przez kolejkę, a aplikacje czekają.

iotop (często trzeba doinstalować):

iotop -oPa

Przełączniki:

  • -o – pokazuje tylko procesy wykonujące I/O,
  • -P – grupuje po procesie (nie po wątkach),
  • -a – akumulowana suma I/O od startu.

Dzięki temu widać bezpośrednio, które procesy generują najwięcej operacji odczytu/zapisu. Typowe obrazy: duży backup MySQL, skrypt generujący miniatury obrazów albo zadanie indeksujące wyszukiwarkę wewnętrzną.

vmstat daje ogólny podgląd kolejek:

vmstat 1 10

Kolumny istotne przy I/O:

  • r – liczba procesów oczekujących na CPU,
  • b – procesy zablokowane (często na I/O),
  • si/so – swap in / swap out,
  • wa – procent czasu CPU spędzonego na czekaniu na I/O.

Jeśli w szczycie b rośnie, wa jest wysokie, a iostat pokazuje długie await, wąskie gardło jest jednoznacznie na dysku. Wtedy optymalizacja SQL, cache HTTP czy tuning PHP nic nie da, dopóki nie zostanie ograniczona liczba ciężkich operacji na storage albo nie zostanie wymieniony typ dysku.

Punkt kontrolny: wysoki load average bez adekwatnego zużycia CPU, połączony z wysokim wa i zajętością dysku w iostat, oznacza, że kolejne próby „dokładania CPU” miną się z celem – trzeba ograniczać I/O lub przyspieszyć warstwę storage.

Diagnostyka „puchnących” katalogów: du, ncdu i logi

Problemy z miejscem na dysku wynikają najczęściej z niekontrolowanego wzrostu logów, katalogów uploadów oraz wewnętrznych cache aplikacji. Szybkie rozpoznanie winnych zapewnia du, a wygodniejszą wersję interaktywną oferuje ncdu.

Podstawowy przegląd:

du -h --max-depth=1 /var
du -h --max-depth=1 /home
du -h --max-depth=1 /var/www

W drugim kroku na problematycznym katalogu można użyć:

ncdu /var

Dzięki pogrupowaniu po katalogach łatwo znaleźć np.:

  • /var/log/journal – systemd z bardzo długą retencją logów,
  • /var/log/nginx – ogromne access.log bez rotacji,
  • /var/www/projekt/wp-content/uploads – nieczyszczone media, kopie i cache.

Po identyfikacji przyczyny konieczne są działania zapobiegawcze, nie tylko jednorazowe kasowanie. Konfiguracja logrotate (lub rotacji systemd-journald) oraz polityk cleanup w aplikacji to minimum. W przypadku WordPressa przydają się wtyczki do ograniczenia liczby wersji wpisów, czyszczenia transients czy kontrolowania generowania miniatur.

Punkt kontrolny: jeśli df -h zbliża się do 90% użycia, pierwszym ruchem powinien być du/ncdu na /var i katalogu projektu. Jeżeli głównym winowajcą są logi, trzeba od razu zająć się rotacją, a nie tylko jednorazowym ich usunięciem.

Specyfika baz danych i storage dla katalogów tymczasowych

Bazy danych są szczególnie wrażliwe na parametry I/O. Nawet szybki CPU i duży RAM nie pomogą, jeśli:

  • dane i logi transakcyjne leżą na wolnym HDD,
  • katalogi tymczasowe (np. /tmp, /var/tmp, /var/lib/mysqltmp) współdzielą wolny dysk z innymi obciążeniami,
  • binlogi, snapshoty i backupy trzymane są w tej samej przestrzeni, z której serwer bazodanowy obsługuje losowe odczyty.

Podstawowy przegląd sytuacji daje połączenie iostat z analizą katalogów danych i logów:

mysql -e "SHOW VARIABLES LIKE 'datadir';"
mysql -e "SHOW VARIABLES LIKE 'innodb_log_group_home_dir';"
mysql -e "SHOW VARIABLES LIKE 'tmpdir';"

df -h
iostat -x 1 10

Jeśli katalog datadir oraz katalog z logami transakcyjnymi leżą na tym samym, mocno obciążonym urządzeniu z wysokim await, każdy większy import lub raport analityczny będzie blokował zapytania online. Sygnał ostrzegawczy: w czasie backupu lub eksportu mysqldump rośnie czas odpowiedzi całego serwisu, a w monitoringu widać wyraźne skoki obciążenia jednego wolumenu.

Wielu webmasterów pomija też wpływ katalogów tymczasowych na bazę i aplikacje. Przy dużych sortowaniach, generowaniu raportów lub operacjach na plikach tymczasowych (np. ZIP, generowanie PDF, przetwarzanie obrazów) serwer może intensywnie korzystać z /tmp. Kryteria do sprawdzenia są trzy: wolne miejsce na filesystemie z /tmp, typ dysku pod tym mountem oraz to, czy nie jest on współdzielony z katalogiem danych bazy lub dużymi uploadami. Jeśli /tmp siedzi na tym samym HDD co /var/lib/mysql, krótkie, intensywne zadanie plikowe może chwilowo sparaliżować I/O dla SQL.

Proste uporządkowanie storage przynosi często większy efekt niż „tuning” parametrów. Sensowny układ to: osobny szybki wolumen (SSD/NVMe) na datadir i logi transakcyjne bazy, osobny na uploady / cache aplikacji oraz droższe operacje plikowe, a dodatkowo wydzielone, niewielkie, ale szybkie miejsce na /tmp jeśli aplikacja intensywnie z niego korzysta. Dla środowisk z dużą bazą krytyczne jest też włączenie i monitorowanie backupów typu snapshot po stronie storage – w przeciwnym razie cykliczny mysqldump o tej samej godzinie codziennie będzie generował szczyt I/O i skargi użytkowników.

Punkt kontrolny: jeśli w szczytach ruchu rośnie czas odpowiedzi SQL, a jednocześnie obserwujesz intensywną pracę backupów, importów lub zadań ETL, analizę trzeba zacząć od rozdzielenia ich na inne okno czasowe lub inny wolumen. Dopiero kiedy storage jest wydzielony i nieprzeciążony, ma sens dalszy tuning buforów i cache w samej bazie.

Stosując powyższe metody jak listę kontrolną – CPU, RAM, I/O i przestrzeń dyskową diagnozowane krok po kroku, z jasnymi punktami kontrolnymi i sygnałami ostrzegawczymi – webmaster przestaje działać „na wyczucie”. Zamiast nerwowych migracji na większe maszyny pojawia się powtarzalny proces: identyfikacja wąskiego gardła, weryfikacja konfiguracji usług, decyzja o optymalizacji lub dopiero na końcu o rozbudowie sprzętu. Dzięki temu kolejne awarie przestają być niespodzianką, a stają się zdarzeniami, które dało się przewidzieć w logach i metrykach.

Przeczytaj także:  Jak tworzyć i rozpakowywać pliki ZIP, TAR i TAR.GZ w systemie Linux
Administratorka z laptopem przechodzi między serwerami w data center
Źródło: Pexels | Autor: Christina Morillo

Monitorowanie logów: jak zamienić chaos w źródło sygnałów ostrzegawczych

Podstawowy zestaw: journalctl, tail, grep i less

Większość problemów aplikacyjnych i systemowych wcześniej czy później kończy w logach. Bez choćby minimalnego porządku w logach webmaster działa po omacku. Na start wystarczą narzędzia tekstowe, które są na każdym serwerze.

Dla systemów z systemd pierwszym krokiem jest journalctl:

journalctl -xe
journalctl -u nginx --since "10 min ago"
journalctl -u php-fpm --since "1 hour ago"
  • -xe – ostatnie wpisy z rozszerzonymi informacjami o błędach,
  • -u nazwa – logi konkretnego serwisu (nginx, php-fpm, mariadb),
  • –since – zawężenie do zakresu czasu, w którym wystąpił problem.

W tradycyjnych logach plikowych podstawą jest podgląd „na żywo”:

tail -f /var/log/nginx/error.log
tail -f /var/log/php8.1-fpm.log

Do przeszukiwania służy grep w kombinacji z less:

grep -i "fatal" /var/log/php8.1-fpm.log | less
grep -i "php fatal" /var/log/nginx/error.log | less
grep -i "denied" /var/log/nginx/access.log | less

Sygnał ostrzegawczy: powtarzające się co kilka sekund identyczne wpisy błędów (np. „PHP Fatal error”, „upstream timed out”), które widać w tail -f jako „flood” linii. Taki wzór oznacza zwykle pętlę błędu w aplikacji lub źle działający healthcheck.

Punkt kontrolny: jeśli CPU lub I/O rośnie bez wyjaśnienia, a w logach pojawiają się co chwilę podobne błędy, należy najpierw zatrzymać źródło spamujących żądań lub wadliwy cron, zamiast od razu dokręcać limity PHP czy MySQL.

Metodyczna analiza error.log dla nginx i Apache

Główne źródło informacji o awariach HTTP to logi błędów serwera WWW. Dla nginx:

/var/log/nginx/error.log

Dla Apache (w zależności od dystrybucji):

/var/log/apache2/error.log
/var/log/httpd/error_log

Zamiast przeklikiwać się ręcznie po tysiącach linii, szybciej jest najpierw policzyć powtarzalne wzory:

grep -i "upstream timed out" /var/log/nginx/error.log | wc -l
grep -i "PHP Fatal error" /var/log/nginx/error.log | wc -l
grep -i "client intended to send too large body" /var/log/nginx/error.log | wc -l

Następnie wyciągnąć najczęstsze fragmenty:

grep -i "upstream timed out" /var/log/nginx/error.log 
  | awk -F": " '{print $NF}' 
  | sort | uniq -c | sort -nr | head

Podobnie można zrobić dla 500/502/504 w Apache, wyszukując frazy "AH" związane z błędami mod_proxy czy PHP-FPM. W efekcie zamiast ogólnego wniosku „serwer się dławi”, pojawia się konkret: konkretna lokalizacja, konkretny backend, typowy timeout.

Sygnał ostrzegawczy: dominacja jednego komunikatu (np. „upstream timed out (110: Connection timed out) while reading response header from upstream”) w krótkim przedziale czasu. Zamiast losowych błędów mamy masowe przekroczenia limitu, co zwykle oznacza CPU/RAM/I/O wąskie gardło po stronie aplikacji lub bazy, a nie problem z nginx.

Punkt kontrolny: jeśli w error.logu HTTP ponad 80% błędów w 10–15-minutowym oknie to jeden typ komunikatu, priorytetem jest korekta konfiguracji lub optymalizacja fragmentu aplikacji wywołującego ten błąd, nie zaś ogólne „skalowanie serwera”.

Analiza access.log: wzorce ruchu, boty i „toksyczne” URL-e

Access logi są dobrym źródłem informacji o „źle działającym” ruchu – agresywnych botach, skanerach, nieudanych uploadach czy powtarzalnych błędnych żądaniach. Dla nginx typowa ścieżka to:

/var/log/nginx/access.log

Prosty przegląd najgorszych URL-i:

awk '{print $7}' /var/log/nginx/access.log 
  | sort | uniq -c | sort -nr | head

Najbardziej agresywne IP:

awk '{print $1}' /var/log/nginx/access.log 
  | sort | uniq -c | sort -nr | head

Filtracja po kodach odpowiedzi pozwala wychwycić nadużycia:

awk '$9 ~ /^404$/' /var/log/nginx/access.log 
  | awk '{print $7}' 
  | sort | uniq -c | sort -nr | head

lub:

awk '$9 ~ /^5[0-9][0-9]$/' /var/log/nginx/access.log 
  | awk '{print $7}' 
  | sort | uniq -c | sort -nr | head

Sygnał ostrzegawczy: setki lub tysiące żądań 404 na dziwne ścieżki (np. /wp-admin/admin-ajax.php, /xmlrpc.php, różne .php w losowych katalogach) z pojedynczych IP lub z jednej puli. Takie wzorce obciążają PHP i I/O, generując nic niewnoszący ruch.

Punkt kontrolny: jeśli CPU i I/O rosną w godzinach, gdy organiczny ruch nie jest wysoki, access.log powinien być pierwszym miejscem do analizy – agresywny ruch należy ograniczyć (rate limiting, blokady na WAF), zanim rozpocznie się tuning PHP czy bazy.

Łączenie logów HTTP z logami aplikacji i bazy

Sam access.log rzadko daje pełen obraz. Kluczowe jest powiązanie konkretnego żądania z wpisem w logach aplikacji (np. PHP, framework) i ewentualnym błędem w bazie.

Minimum to spójny format logowania czasu. Jeśli nginx/Apache, PHP-FPM i MySQL logują lokalny czas serwera w tej samej strefie i formacie, korelacja w oknie kilkudziesięciu sekund jest możliwa manualnie. Ułatwia to np. format %Y-%m-%dT%H:%M:%S%z w logach aplikacji (czas w ISO 8601 z przesunięciem strefy).

Przy większej liczbie instancji skuteczniejsze jest dodanie identyfikatora żądania. Dla nginx można użyć zmiennej $request_id:

log_format main '$remote_addr - $remote_user [$time_local] '
                '"$request" $status $body_bytes_sent '
                '"$http_referer" "$http_user_agent" '
                '$request_time $upstream_response_time $request_id';

access_log /var/log/nginx/access.log main;

Następnie ten sam $request_id można przekazać do aplikacji przez nagłówek (np. X-Request-ID) i zapisywać w logach aplikacyjnych. W efekcie w razie problemu można wyszukać dany identyfikator w trzech miejscach: access.log, logach aplikacji i logu serwera SQL (np. slow query log).

Sygnał ostrzegawczy: długi $request_time przy niewielkim $upstream_response_time – oznacza to, że duża część opóźnienia pojawia się po stronie frontu (np. TLS, sieć, ograniczenia na poziomie serwera WWW), a nie back-endu aplikacji. Odwrotnie, długie $upstream_response_time kieruje uwagę na PHP lub bazę.

Punkt kontrolny: jeżeli użytkownicy skarżą się na wolne odpowiedzi, access.log z metrykami $request_time i $upstream_response_time powinien zostać przeanalizowany w pierwszej kolejności, zanim rozpocznie się „ślepy” tuning bazy danych lub PHP-FPM.

Minimalna centralizacja logów dla małego zespołu

Dla pojedynczego serwera ręczna analiza logów jest jeszcze wykonalna. Przy kilku–kilkunastu maszynach potrzebne jest minimum centralizacji, inaczej każdy incydent kończy się chaotycznym logowaniem się na różne hosty.

Najniższy próg to wysyłka logów przez rsyslog lub syslog-ng do jednego serwera logów. Przykładowa konfiguracja rsyslog na serwerze aplikacyjnym:

*.* @@log-serwer.example.com:514

(@@ oznacza TCP, pojedyncze @ – UDP.) Na serwerze logów wystarczy skonfigurować nasłuchiwanie i prostą strukturę katalogów na pliki logów z podziałem na hosty i usługi.

Bardziej wygodną opcją jest lekki stack typu Filebeat + Elasticsearch/OpenSearch + Kibana albo Fluent Bit + Loki + Grafana. Z perspektywy webmastera nie chodzi jednak o wyrafinowane wykresy, ale o kilka konkretnych funkcji:

  • wspólne filtrowanie po czasie i frazie (np. „PHP Fatal”, „timeout”, „denied”),
  • szybkie porównanie logów z kilku hostów w jednym widoku,
  • proste alerty (np. liczba „502 Bad Gateway” > X w ciągu 5 minut).

Sygnał ostrzegawczy: brak możliwości odpowiedzi na pytanie „co działo się na wszystkich frontendach i bazie w tym samym czasie” bez ręcznego zgrywania logów z kilku maszyn. To oznacza, że centralizacja jest na poziomie poniżej minimum.

Punkt kontrolny: jeżeli liczba serwerów przekracza trzy–cztery instancje produkcyjne, należy wprowadzić choćby bardzo prosty centralny system logów, zanim pojawi się pierwsza poważniejsza awaria wymagająca korelacji zdarzeń między hostami.

Łączenie metryk systemowych z logami: od objawu do przyczyny

Timeline awarii: korelacja CPU/RAM/I/O z logami

Same logi nie pokażą, czy problemem jest CPU, RAM czy I/O. Kluczowe jest ustawienie wspólnej osi czasu. Nawet przy najprostszym podejściu można to zrobić, używając jednocześnie narzędzi systemowych i logów.

W momencie incydentu warto zebrać migawkę systemu:

date
uptime
top -b -n1 | head -n20
free -m
iostat -x 1 3
vmstat 1 3

Oznaczenie czasu date staje się punktem odniesienia. W logach aplikacji, HTTP i bazy można następnie przeskoczyć do tego samego momentu i kilku minut przed nim. Taki prosty „raport ręczny” bywa bardziej użyteczny niż wymyślne dashboardy, jeżeli jest tworzony konsekwentnie przy każdym incydencie.

Przykładowy schemat korelacji:

  • wysoki load average + niskie użycie CPU + wysokie wa → spojrzenie w logi SQL i access.log pod kątem masowych zapytań,
  • wysokie us lub sy w top + brak błędów w logach HTTP → podejrzenie intensywnej „normalnej” pracy (cron, batch),
  • brak skoków CPU, ale wysokie si/so w vmstat → analiza logów aplikacji pod kątem „Out of memory” i zabijanych procesów.

Sygnał ostrzegawczy: powtarzające się incydenty o podobnym przebiegu bez ich dokumentowania. Bez prostego timeline’u przy każdej awarii zespół dochodzi do tych samych wniosków od zera.

Punkt kontrolny: po każdym większym incydencie powinien powstać krótki raport z timestampem, snapshotem metryk i fragmentami logów, które wskazują na przyczynę. Taki szkielet raportu da się później zautomatyzować w narzędziu monitorującym.

Alerty progowe: co monitorować, zanim serwer „zgaśnie”

Bez automatycznych alertów webmaster dowiaduje się o problemie od użytkowników lub klienta. Minimum to progi ostrzegawcze na podstawowych metrykach systemowych i logach.

Przykładowe progi startowe (do dostosowania):

  • CPU: średnie użycie > 80% przez 5–10 minut,
  • RAM: dostępna pamięć < 15–20% + rosnący swap used,
  • I/O: util z iostat > 90% przez kilka minut,
  • dysk: użycie filesystemu > 85–90%,
  • HTTP: liczba błędów 5xx na minutę powyżej ustalonego progu,
  • SQL: liczba wpisów slow query w krótkim oknie powyżej normy.

Narzędzia do realizacji mogą być różne – od prostych skryptów crona wysyłających e-mail, przez Prometheus + Alertmanager, po zewnętrzne systemy monitoringu. Kryterium jakości nie jest „fancy UI”, tylko jasne powiązanie alertu z konkretnym parametrem, którego przekroczenie potwierdza realny problem.

Sygnał ostrzegawczy: alerty typu „server is down” bez wcześniejszych alarmów o dysku na 95%, powtarzających się błędach 500 lub rosnącej liczbie slow query. Taka sytuacja oznacza, że monitoring reaguje dopiero na skutek, a nie na przyczyny.

Punkt kontrolny: konfigurując pierwszy monitoring, lepiej mieć kilka prostych alertów progowych na CPU/RAM/dysk/logi HTTP niż rozbudowany dashboard bez powiązanych powiadomień. Dopiero stabilne alerty bazowe stanowią fundament do bardziej zaawansowanych reguł.

Profil „minimum monitoringu” dla typowego hostingu aplikacyjnego

Dla większości projektów WWW nie ma potrzeby budowania pełnego NOC. Zamiast tego przydaje się jasny profil minimum: co musi być mierzone, aby dało się szybko wskazać winowajcę.

Na poziomie systemu:

  • ciągłe zbieranie metryk CPU/RAM/I/O (np. node_exporter/Netdata/Zabbix agent),
  • monitoring dostępności i czasu odpowiedzi HTTP (health check + podstawowy syntetyczny test),
  • kontrola zajętości dysku i inodów z twardymi progami alertów,
  • podstawowe metryki sieci (przepływ, błędy interfejsów, liczba połączeń),
  • rejestrowanie restartów serwisów (systemd, crony) i awarii OOM w logach centralnych.

Na poziomie aplikacji i usług HTTP minimalny zestaw to: liczba żądań na minutę, udział kodów 5xx oraz podstawowe percentyle czasu odpowiedzi (np. 50. i 95.). Do tego prosty wgląd w limity i kolejki PHP-FPM (lub innego runtime) oraz liczba aktywnych połączeń do bazy. Jeżeli projekt korzysta z cache (Redis, Memcached), trzeba monitorować rozmiar pamięci, liczbę missów oraz ewentualne restarty.

Dla bazy danych wystarczy początkowo kilka wskaźników: liczba wolnych zapytań (slow queries), wykorzystanie połączeń (connection pool), podstawowe statystyki locków i czas odpowiedzi. Brak tych metryk oznacza, że przy każdym problemie z „wolnym systemem” zespół musi zgadywać, czy wina leży po stronie SQL, czy wyżej w stosie.

Sygnał ostrzegawczy: dashboard z dziesiątkami wykresów, ale bez jasno zdefiniowanych progów i bez powiązanych alertów. Punkt kontrolny: jeżeli na podstawie samego profilu „minimum monitoringu” da się w kilka minut odpowiedzieć na pytanie „czy problem jest w CPU/RAM/I/O, HTTP, aplikacji czy bazie”, to zakres monitoringu jest dobrany sensownie jak na standardowy hosting aplikacyjny.

Jeżeli każdy incydent kończy się szybką identyfikacją warstwy winnej problemu, a decyzja „skalować sprzęt czy optymalizować kod” opiera się na twardych metrykach i logach, to monitoring spełnia swoją rolę. Z tak ustawionym „minimum” webmaster przestaje reagować wyłącznie na skutek, a zaczyna wychwytywać sygnały ostrzegawcze na tyle wcześnie, by serwer nie „zgasł” w środku dnia.

Standard pracy webmastera podczas incydentu wydajnościowego

Procedura „pierwszych 10 minut”

Przy nagłym spadku wydajności czy seriach błędów 5xx najgorszy scenariusz to chaotyczne przełączanie się między zakładkami z logami i losowe „restartujmy wszystko”. Znacznie skuteczniejsza jest prosta checklista na pierwsze minuty, oparta o metryki CPU/RAM/I/O i logi.

Przykładowy szkic procedury:

  1. Potwierdzenie problemu z perspektywy użytkownika – szybki test HTTP z zewnątrz (curl z innej maszyny, monitoring syntetyczny), zanotowanie dokładnego czasu.
  2. Snapshot systemu – zestaw komend:
    date
    uptime
    top -b -n1 | head -n30
    free -m
    df -h
    iostat -x 1 3
    vmstat 1 3
    ss -s
    
  3. Sprawdzenie logów HTTP – liczba 5xx w krótkim oknie, średni czas odpowiedzi, najczęstsze URL-e z długim czasem obsługi.
  4. Sprawdzenie logów aplikacji – frazy typu „Fatal”, „Error”, „timeout”, „denied”, „Out of memory”.
  5. Sprawdzenie bazy danych – czy działa, czy ma wolne połączenia, czy rośnie liczba slow query.

Sygnał ostrzegawczy: incydenty, przy których nikt nie jest w stanie wskazać choćby podstawowego timeline’u zdarzeń i obciążenia systemu. Punkt kontrolny: po 10 minutach pracy webmaster musi mieć zapisaną krótką notatkę z timestampem, snapshotem systemu i pierwszym podejrzeniem warstwy winnej problemu (CPU, RAM, I/O, HTTP, SQL).

Szablon krótkiego raportu po incydencie

Nawet bardzo proste raporty „post-mortem” znacząco poprawiają jakość kolejnych reakcji na awarie. Nie chodzi o rozbudowane dokumenty, ale o powtarzalny szkielet, w którym da się wstawić konkretne metryki i fragmenty logów.

Przykładowy szablon w formie notatki tekstowej lub tiketu:

  • Czas zdarzenia: [data, godzina + strefa czasowa]
  • Objaw: [np. „wzrost kodów 502 na frontendach, RPS spadł o połowę”]
  • Wpływ: [które serwisy, jak długo, dane przybliżone]
  • Snapshot systemu: skrót najważniejszych metryk:
    • CPU: load average, us/sy/wa z top lub mpstat
    • RAM: wolna pamięć, użycie swapu, cache/buffers
    • I/O: util, await z iostat
    • dysk: procentowe użycie najważniejszych filesystemów (df -h)
  • Korelacja z logami:
    • HTTP: wzrost 5xx, długie $request_time, konkretne endpointy
    • aplikacja: powtarzające się błędy, stack trace, timeouty
    • baza: slow query, błędy połączeń, locki
  • Hipoteza przyczyny: [np. „brak indeksu na kolumnie X, masowy batch, oversubskrypcja CPU na hypervisorze”]
  • Doraźne działania: co zostało zrobione w trakcie incydentu (skalowanie, restart, blokada ruchu, rolling restart).
  • Działania trwałe: co ma zapobiec powtórce (zmiana konfiguracji, indeksy, dodatkowe alerty, limity PHP-FPM).

Jeżeli po kilku incydentach szablon zaczyna się powtarzać (te same objawy i te same doraźne działania), to znak, że problem strukturalny nie został rozwiązany. Jeżeli w raportach dominują stwierdzenia „brak danych” lub „nie logowaliśmy tego”, minimum monitoringu i logowania jest niedoszacowane.

Standardy konfiguracji i higiena monitoringu

Spójne strefy czasowe i formaty timestampów

Korelacja metryk CPU/RAM/I/O z logami wymaga jednego, prostego wymogu: spójnego czasu. Rozjechane zegary i różne strefy czasowe potrafią skutecznie uniemożliwić analizę nawet najlepiej zebranych danych.

Minimalny zestaw zasad:

  • wszystkie serwery (aplikacje, bazy, load balancery, system logów, monitoring) działają w tej samej strefie czasowej, zwykle UTC,
  • wszystkie maszyny mają aktywną synchronizację czasu (np. chronyd, systemd-timesyncd),
  • logi mają jednoznaczny format czasu, najlepiej ISO 8601 z oznaczeniem strefy (2026-04-29T12:34:56Z),
  • dashboardy w systemie monitoringu używają tej samej strefy co logi.

Sygnał ostrzegawczy: różnice rzędu kilku minut między timestampami w logach aplikacji, serwera HTTP i bazy, których nie da się wyjaśnić. Punkt kontrolny: podczas analizy ostatniej awarii zespół bez dyskusji ustala jedną godzinę zdarzenia i potrafi wskazać ją zarówno w logach, jak i na wykresach.

Tagowanie hostów i usług w monitoringu

Przy większej liczbie serwerów mapa środowiska bez sensownego podziału na role i środowiska przestaje być czytelna. Minimum to proste tagowanie hostów i usług w metrykach i logach.

Praktyczny podział:

  • Środowisko: env=prod, env=stage, env=dev,
  • Rola: role=frontend, role=app, role=db, role=cache,
  • Projekt: project=shop, project=blog itd.

Dzięki temu łatwo odfiltrować metryki „tylko z frontendów produkcyjnych” lub „tylko z baz dla konkretnego projektu”. W systemach typu Prometheus, Zabbix czy Netdata odpowiednikiem są etykiety/hostgroups; w stackach logowych – pola indeksu.

Sygnał ostrzegawczy: dashboardy z ogólnym „CPU wszystkich hostów”, bez możliwości szybkiego zawężenia do serwerów krytycznej aplikacji. Punkt kontrolny: przy incydencie dotyczących jednego projektu administrator jest w stanie jednym filtrem odseparować zarówno metryki, jak i logi tylko tej usługi.

Utrzymanie „szumu” na akceptowalnym poziomie

Zbyt agresywne alerty lub nadmiar logów informacyjnych prowadzą do ślepoty operacyjnej. Liczy się nie tylko to, co jest zbierane, ale też to, czego świadomie się nie zbiera lub na co nie wysyła się powiadomień.

Przy ustalaniu progów i poziomów logowania przydaje się krótka lista decyzji:

  • identyfikacja logów o charakterze diagnostycznym, które mogą trafiać tylko lokalnie (bez centralizacji),
  • decyzja, które informacje muszą zasilać system centralny (błędy, ostrzeżenia, działania automatyki),
  • ustalenie, które metryki wymagają alertów, a które tylko wizualizacji na dashboardzie,
  • zdefiniowanie, które alerty są krytyczne (telefon/komunikator), a które informacyjne (e-mail, ticket).

Jeżeli liczba alertów miesięcznie jest tak duża, że nikt nie jest w stanie ich rzetelnie przejrzeć, realny monitoring w praktyce nie działa. Jeżeli incydenty z istotnym wpływem na użytkowników zdarzają się częściej niż alerty, konfiguracja jest zbyt „cicha”.

Bezpieczne testowanie zmian konfiguracji pod kątem wydajności

Testy obciążeniowe na poziomie minimum

Zmiana konfiguracji PHP-FPM, Nginx czy bazy bez choćby podstawowego testu obciążeniowego jest ryzykowna, szczególnie gdy ma wpływ na zużycie CPU, RAM lub I/O. Nawet prosty test „przed/po” może uchronić przed wdrożeniem ustawień, które działają dobrze tylko na papierze.

Podstawowy scenariusz testu:

  1. Wybranie 1–3 reprezentatywnych endpointów (np. strona główna, kluczowy koszyk, logowanie).
  2. Uruchomienie narzędzia typu ab, wrk, hey lub prostego skryptu JMeter z rosnącym obciążeniem.
  3. Równoczesny podgląd metryk CPU/RAM/I/O oraz logów HTTP (czasy odpowiedzi, błędy 5xx).
  4. Zapisanie punktu przeciążenia – liczba żądań na sekundę przy akceptowalnym czasie odpowiedzi i osiągnięcie limitów CPU, RAM lub I/O.

Sygnał ostrzegawczy: wdrażanie globalnych zmian w konfiguracji bez żadnych danych liczbowych, opierając się jedynie na „będzie szybciej, bo tak ktoś napisał na forum”. Punkt kontrolny: po każdej istotnej zmianie limitów procesów, workerów lub cache istnieje krótki zapis testu z informacją, czy punkt przeciążenia przesunął się w dobrą stronę.

Ocena wpływu zmian na CPU, RAM i I/O

Kiedy zmienia się konfigurację, warto ocenić jej wpływ na poszczególne zasoby systemowe, zamiast patrzeć tylko na czas odpowiedzi HTTP. Uproszczony schemat oceny:

  • CPU:
    • czy rośnie średnie użycie us/sy przy podobnym ruchu,
    • czy liczba aktywnych workerów nie przekracza rozsądnie liczby vCPU,
    • czy nie pojawia się rosnące steal w środowiskach wirtualnych.
  • RAM:
    • czy nowa konfiguracja PHP-FPM nie powoduje wypychania w cache i wchodzenia w swap,
    • czy cache (Redis/Memcached) mieści się w zadeklarowanych limitach, bez częstych evictów,
    • czy wzrost buforów/dysk cache’a nie „zjada” pamięci potrzebnej aplikacji.
  • I/O:
    • czy w iostat nie pojawia się stały util blisko 100%,
    • czy await nie rośnie znacząco podczas szczytu ruchu,
    • czy logi nie pokazują masowych „too many open files”, „no space left on device” lub opóźnień w zapisach.

Jeżeli po zmianie konfiguracji czasy odpowiedzi lekko spadają, ale jednocześnie CPU jest stale na granicy 90–100%, stabilność w dłuższym okresie jest wątpliwa. Jeżeli poprawa czasów odpowiedzi wynika wyłącznie z przerzucenia problemu na I/O (masowe zapisy logów, agresywny cache na dysku), kolejna awaria będzie kwestią czasu.

Praktyczne wzorce i antywzorce w monitorowaniu Linuxa

Typowe pułapki przy interpretacji metryk

Nadmierna ufność w jeden wykres lub jedną wartość metryki prowadzi do błędnych diagnoz. Kilka powtarzalnych pułapek:

  • „RAM prawie pełny = za mało pamięci” – w Linuxie wolna pamięć jest z założenia używana na cache/buffers. Krytyczne są skoki swapu i intensywne si/so, a nie sam niski poziom „free”.
  • „Wysoki load average = CPU za słabe” – load obejmuje również procesy czekające na I/O. Wysokie wa i duże opóźnienia w iostat wskazują na problem z dyskiem, a nie z CPU.
  • „Niskie użycie CPU = serwer się nudzi” – przy problemach sieciowych lub blokadach w aplikacji CPU pozostaje nisko, podczas gdy użytkownicy odczuwają time-outy.
  • „Brak błędów 5xx = wszystko dobrze” – długie czasy odpowiedzi (np. 10–20 sekund) przy kodach 200 lub 302 są równie szkodliwe, choć nie manifestują się jako ewidentne błędy.

Jeżeli w diagnozach często pojawiają się głosy „CPU jest nisko, więc na pewno to nie serwer”, mimo wyraźnego niezadowolenia użytkowników, sposób czytania metryk wymaga korekty. Jeżeli zespołowi zdarza się winić dysk, a później okazuje się, że powodem były blokady w kodzie aplikacji, brakuje systematycznego porównania I/O z logami SQL i aplikacyjnymi.

Minimalne „dashboardy inspekcyjne”

Rozbudowane, efektowne dashboardy nie są wymagane. Przydatniejszy bywa zestaw trzech–czterech prostych widoków, które odpowiadają na konkretne pytania kontrolne.

Przykładowy zestaw:

  • Dashboard systemowy:
    • CPU (us/sy/wa, load average),
    • RAM (użycie, cache, swap),
    • I/O (util, await, odczyty/zapisy),
    • sieć (przepływ, błędy interfejsów).
  • Dashboard HTTP:
    • liczba żądań na minutę,
    • udział kodów 2xx/4xx/5xx,
    • percentyle czasu odpowiedzi (P50, P95),
    • top URL-e z najdłuższym czasem obsługi.
  • Dashboard aplikacyjno‑bazodanowy:
    • liczba zapytań SQL na sekundę i średni czas ich wykonania,
    • top zapytania według czasu i liczby wywołań,
    • statystyki cache (hit/miss) oraz błędy połączeń do usług zewnętrznych,
    • liczba błędów aplikacyjnych w czasie (np. wyjątki, time-outy).
  • Dashboard „zdrowia” projektu:
    • metryki biznesowe (logowania, zamówienia, kluczowe akcje),
    • połączone z kluczowymi metrykami technicznymi (P95 czasu odpowiedzi, błędy 5xx, zajętość CPU/RAM na hostach tej aplikacji),
    • prosty widok „przed” i „po” wdrożeniu (oznaczenia release’y).

Taki zestaw nie ma być encyklopedią wszystkich wykresów, tylko narzędziem do szybkiej inspekcji. Jeżeli do odpowiedzi na pytanie „co się dzieje z projektem X?” trzeba klikać przez pięć różnych widoków, układ dashboardów wymaga korekty. Jeżeli nowa osoba w zespole po tygodniu nie jest w stanie samodzielnie odczytać z nich stanu systemu, interfejs jest zbyt skomplikowany.

Łączenie metryk z logami i eventami zmian

Same liczby niewiele znaczą bez kontekstu. Krytyczne jest połączenie metryk systemowych i aplikacyjnych z logami oraz z informacją o zmianach: wdrożeniach, migracjach, restartach usług. Minimum to oznaczanie release’ów i większych modyfikacji konfiguracji na wykresach lub w postaci osobnych eventów w systemie monitoringu.

Przy diagnozie incydentów powtarza się prosty schemat: najpierw wykres (np. skok P95 czasu odpowiedzi), następnie filtrowanie logów HTTP i aplikacyjnych dla tego przedziału czasu, na końcu sprawdzenie, czy w tym samym momencie nie było wdrożenia lub zmiany infrastruktury. Sygnał ostrzegawczy pojawia się wtedy, gdy zespół regularnie spędza długie godziny na szukaniu korelacji „ręcznie” w kilku narzędziach, zamiast korzystać z jednego, spójnego widoku. Punkt kontrolny: dla losowo wybranego incydentu da się w kilka minut pokazać na jednym ekranie metryki, logi i event wdrożenia, który potencjalnie mógł mieć wpływ.

Jeśli system monitoringu jest w stanie dostarczyć takie powiązanie „z pudełka”, diagnozy przyspieszają o rząd wielkości. Jeśli każda analiza wymaga eksportu do arkusza kalkulacyjnego, kopiowania timestampów i ręcznego zestawiania danych, realna wartość metryk i logów jest mocno ograniczona.

Operacyjne minimum dla webmastera

Rola webmastera nie wymaga pełnej biegłości administracyjnej, ale zakłada umiejętność postawienia kilku prostych diagnoz przed zrzuceniem winy na „serwer” lub „kod”. Operacyjne minimum to: znajomość podstawowych narzędzi systemowych (top/htop, iostat, df, journalctl), umiejętność odczytu kilku kluczowych dashboardów oraz świadome podejście do limitów CPU, RAM i I/O dla własnych projektów.

Jeżeli webmaster przy każdym problemie wydajnościowym może pokazać krótką sekwencję: od sprawdzenia hosta, przez analizę logów HTTP, po weryfikację baz danych i cache, współpraca z administratorami przebiega szybciej i na konkretnych danych. Jeżeli rozmowa kończy się zwykle na stwierdzeniu „strona wolno chodzi”, bez liczbowych dowodów, monitoring istnieje tylko formalnie.

Najczęściej zadawane pytania (FAQ)

Jakie metryki Linuxa są absolutnym minimum dla webmastera?

Minimum to CPU, RAM, IO dyskowe, sieć oraz logi serwera WWW i aplikacji. Te pięć obszarów bezpośrednio przekłada się na czas TTFB, błędy 5xx i stabilność serwisu. Reszta (np. szczegółowe logi kernela) ma mniejszy wpływ na to, co widzi użytkownik przeglądarki.

Punkt kontrolny: jeśli monitorujesz wszystko „po trochu”, ale nie masz stałego podglądu na CPU, pamięć, dysk, sieć i logi HTTP/PHP, to tak naprawdę nie masz użytecznego monitoringu. Jeśli ogarniasz te pięć elementów, zwykle jesteś w stanie szybko wskazać źródło problemu.

Jak szybko sprawdzić na serwerze Linux, czy problemem jest CPU czy RAM?

Podstawowy zestaw komend „pierwszego kontaktu” to: uptime (load average), top lub htop (użycie CPU, procesy), free -h (RAM, swap) oraz ps aux --sort=-%cpu / ps aux --sort=-%mem (najcięższe procesy). To absolutne minimum, które powinno być odpalane przy każdym zgłoszeniu „serwis muli”.

Jeśli load average jest zbliżony lub wyższy od liczby vCPU, a w top widać wysokie %us lub %sy, to sygnał ostrzegawczy dla CPU. Jeśli w free -h pole available jest bardzo niskie, a swap zaczyna się zapełniać, problem przesuwa się w stronę pamięci.

Jak interpretować load average w kontekście vCPU na serwerze WWW?

Load average ma sens tylko w odniesieniu do liczby rdzeni logicznych (vCPU). Dla 1 vCPU load ≈1 oznacza pełne obciążenie, powyżej 1 pojawia się kolejka zadań. Dla 4 vCPU load ≈4 to dopiero wykorzystanie całej mocy CPU – load 1 w takim przypadku to w praktyce około 25% obciążenia.

Prosty schemat kontrolny:

  • load < liczba vCPU – serwer ma zapas mocy, szukaj problemu w IO, bazie lub sieci,
  • load ≈ liczba vCPU – system pracuje na wysokich obrotach, ale jeszcze kontrolowanie,
  • load > 2 × liczba vCPU – silny sygnał ostrzegawczy, trzeba zidentyfikować procesy blokujące CPU lub I/O (top, ps).

Jeśli jednocześnie rośnie udział wa (I/O wait) w top, to kolejka wynika raczej z dysku niż z „braku procesora”.

Dlaczego Linux pokazuje „prawie pełny RAM” i czy to oznacza problem?

Linux używa wolnej pamięci jako cache plików, dlatego kolumna used w free -m prawie zawsze wygląda „wysoko”. Kluczowe jest pole available, które mówi, ile pamięci może realnie przeznaczyć na nowe procesy bez agresywnego swapowania. Dopóki available jest sensowne, „pełny RAM” jest tylko pozorny.

Punkt kontrolny: dopiero sytuacja, gdy available spada do kilkunastu procent całości, a jednocześnie rośnie użycie swapu, jest realnym sygnałem problemu z pamięcią. Jeśli cache jest duży, ale swap prawie pusty, system działa zgodnie z założeniami i nie wymaga natychmiastowego „dorzucenia RAM-u”.

Jak rozróżnić, czy wolne ładowanie strony wynika z dysku (I/O), a nie z CPU?

Jeśli TTFB jest długie, a w top widać wysoki procent wa (I/O wait) przy stosunkowo niskim %us i %sy, wąskim gardłem jest dysk. Dodatkowo warto skontrolować iostat (jeśli dostępne), iotop oraz df -h (stan zajęcia partycji) i du -sh /var/log /ścieżka/projektu, bo przepełniony lub intensywnie zapisywany dysk szybko psuje responsywność serwisu.

Jeżeli w tym samym czasie load average rośnie, a większość procesów ma status „D” (uninterruptible sleep – w top), to kolejny sygnał ostrzegawczy, że serwer czeka na dysk, a nie na CPU. W takiej sytuacji optymalizowanie PHP lub zwiększanie liczby workerów tylko pogorszy problem.

Jakie logi w Linuxie powinien regularnie sprawdzać webmaster przy problemach z WWW?

Minimum to:

  • logi serwera WWW (Nginx/Apache) – access i error,
  • logi PHP/PHP-FPM – szczególnie timeouty, błędy krytyczne,
  • log bazy danych (MySQL/MariaDB) – slow queries, zablokowane transakcje,
  • systemowe logi o OOM killerze i braku miejsca na dysku (np. /var/log/syslog, /var/log/messages).

Te cztery źródła pozwalają zwykle szybko powiązać obserwowane błędy 500/502/504 z konkretnym poziomem stacku.

Jeśli w logach WWW widać błędy 5xx bez wpisów w logu PHP, punkt kontrolny to konfiguracja serwera HTTP i PHP-FPM. Jeśli pojawiają się wpisy OOM lub komunikaty o braku miejsca na dysku, priorytetem staje się RAM lub czyszczenie/przeniesienie danych z przepełnionych partycji.

Jak przygotować serwer Linux przed wdrożeniem nowego serwisu WWW?

Przed startem projektu należy zebrać twarde parametry środowiska: liczbę vCPU (nproc), ilość RAM (free -h), typ dysku (SSD/NVMe vs HDD, np. z panelu VPS lub lsblk), limity IOPS/przepustowości z dokumentacji dostawcy oraz system plików i opcje montowania (np. noatime). To absolutne minimum, bez którego trudno ocenić, czy serwer jest realnie przeciążony, czy po prostu zbyt słaby.

Jeżeli te dane są znane, każde późniejsze odczyty CPU, RAM i IO można interpretować w kontekście możliwości maszyny. Jeśli ich brakuje, każdy problem wydajnościowy zamienia się w zgadywankę typu „czy to wina kodu, czy hostingu”, bez szans na rzetelny audyt wydajnościowy.

Poprzedni artykułStartupy i robotyka – automatyzacja na wyciągnięcie ręki
Następny artykułJak budować zaufanie w relacjach zawodowych IT
Artykuły Czytelników

Artykuły Czytelników to przestrzeń na porady-it.pl dla osób, które chcą podzielić się własnym doświadczeniem z PHP, webmasteringu i tworzenia praktycznych skryptów. Publikujemy tu sprawdzone rozwiązania, case study, krótkie „tipy” oraz opisy problemów, które udało się rozwiązać w realnych projektach – od formularzy i baz danych, po integracje API i optymalizację działania stron. Każdy materiał jest redagowany tak, by był czytelny, użyteczny i bezpieczny do wdrożenia, a autor otrzymał jasne miejsce na swoją wiedzę i wkład w społeczność. Masz temat? Napisz: administrator@porady-it.pl