0Pricing
DevOps Bootcamp · Lekcja

Śledzenie logów w czasie rzeczywistym i alerty strumieniowe

Śledź i filtruj strumienie logów na żywo, aby wyzwalać alerty natychmiast po pojawieniu się wzorców błędów.

Śledzenie logów w czasie rzeczywistym i alerty strumieniowe to bezpłatna lekcja DevOps Bootcamp na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej DevOps Bootcamp, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs DevOps Bootcamp zawiera 4 lekcji w sumie.

Dlaczego śledzenie dzienników w czasie rzeczywistym ma znaczenie

W systemach produkcyjnych pliki dzienników stale rosną. Czekanie z analizą dzienników do momentu zgłoszenia problemu oznacza, że przestój już Państwa kosztuje. Śledzenie dzienników w czasie rzeczywistym pozwala obserwować zdarzenia w chwili ich zapisu, umożliwiając natychmiastową reakcję na awarie, zdarzenia związane z bezpieczeństwem i pogorszenie wydajności.

  • Serwery internetowe zapisują jeden wiersz na żądanie — błędy pojawiają się natychmiast
  • Demoni aplikacji rejestrują ślady stosu w chwili wystąpienia wyjątku
  • Systemy uwierzytelniania rejestrują nieudane próby logowania w czasie rzeczywistym

Podstawowym narzędziem Unix służącym do tego celu jest tail -f, połączone z narzędziami do filtrowania i wysyłania alertów, które przekształcają surowe strumienie dzienników w użyteczne sygnały.

tail -f: śledzenie dziennika na żywo

tail -f (follow) utrzymuje otwarty plik i wyświetla nowe wiersze w miarę ich dopisywania. To najprostsze i powszechnie dostępne narzędzie do monitorowania dzienników w czasie rzeczywistym.

Typowe sposoby użycia:

  • tail -f /var/log/syslog — śledzenie dziennika systemowego
  • tail -n 50 -f app.log — wyświetlenie 50 ostatnich wierszy, a następnie ich śledzenie
  • tail -f /var/log/nginx/access.log — śledzenie żądań nginx na żywo

Aby zatrzymać działanie, należy nacisnąć Ctrl+C. Proces pozostaje aktywny do momentu anulowania go przez Państwa lub zamknięcia terminala.

#!/usr/bin/env bash
# Simulate a live log and follow it
LOGFILE='/tmp/demo_app.log'

# Write a header
echo '[INFO] Application started' >> "$LOGFILE"

# In a real scenario you would run:
# tail -f "$LOGFILE"
# Below we demonstrate tail showing the last 3 lines then exit
tail -n 3 "$LOGFILE"

tail -F: odporność na rotację dzienników

Wiele systemów rotuje pliki dzienników o północy lub po osiągnięciu przez nie określonego rozmiaru. W takiej sytuacji oryginalny plik otrzymuje nową nazwę (np. app.log.1), a tworzony jest nowy plik app.log. W przypadku tail -f będzie ono nadal po cichu odczytywać stary, przemianowany plik, przez co nie zobaczą Państwo nowych danych.

tail -F (wielka litera F) rozwiązuje ten problem, obserwując nazwę pliku, a nie deskryptor pliku. Gdy plik zniknie i pojawi się ponownie, tail -F automatycznie otworzy go ponownie i będzie kontynuować śledzenie.

  • W skryptach produkcyjnych należy zawsze preferować tail -F zamiast tail -f
  • Działa z narzędziami logrotate, newsyslog oraz sterownikami dzienników Dockera, które rotują pliki
# Follow nginx access log, surviving log rotation
tail -F /var/log/nginx/access.log

# Follow multiple files simultaneously
tail -F /var/log/nginx/access.log /var/log/nginx/error.log

Filtrowanie strumienia za pomocą grep

Surowe śledzenie intensywnie zapisywanego dziennika szybko przytłacza — aktywny serwer internetowy może zapisywać setki wierszy na sekundę. Należy przekierować wyjście tail -F do grep, aby wyodrębnić tylko interesujące Państwa wzorce.

Najważniejsze opcje grep używanego do przetwarzania strumieni:

  • --line-buffered — natychmiast opróżnia bufor po każdym dopasowanym wierszu zamiast buforować dane; jest to wymagane w potokach, ponieważ w przeciwnym razie dane wyjściowe będą opóźnione lub utracone
  • -i — dopasowanie bez uwzględniania wielkości liter
  • -E — rozszerzone wyrażenia regularne dla alternatyw (error|warn|crit)
  • -v — odwrócenie dopasowania (wykluczanie wierszy)
# Show only ERROR and WARN lines from a live application log
tail -F /var/log/myapp/app.log | grep --line-buffered -Ei 'error|warn|critical'

# Follow nginx and exclude health-check requests
tail -F /var/log/nginx/access.log | grep --line-buffered -v '/health'

Dodawanie znaczników czasu i kontekstu za pomocą awk

Wierszom dziennika czasami brakuje kontekstu pomocnego podczas wstępnej analizy problemu. Mogą Państwo wzbogacać strumień w czasie rzeczywistym za pomocą awk — dodawać lokalny znacznik czasu, wyodrębniać pola lub formatować dane wyjściowe w czytelniejszy sposób.

awk działa również w trybie strumieniowym (z buforowaniem wierszy) po przekazaniu danych potokiem, dzięki czemu można go bezpiecznie używać w potokach działających na żywo bez dodatkowych opcji.

# Prepend a reception timestamp to every ERROR line
tail -F /var/log/myapp/app.log | \
  grep --line-buffered -i 'error' | \
  awk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0; fflush() }'

# Extract HTTP status code (field 9) and URL (field 7) from nginx combined log
tail -F /var/log/nginx/access.log | \
  awk '{ print $9, $7; fflush() }' | \
  grep --line-buffered '^5'

Wysyłanie alertów za pomocą webhooków Slack

Filtrowanie to tylko połowa zadania — po wykryciu wzorca błędu trzeba kogoś powiadomić. Przychodzący webhook Slack pozwala wysłać wiadomość do kanału za pomocą pojedynczego wywołania curl, bez użycia Slack SDK i bez poświadczeń innych niż URL webhooka.

Wzorzec jest następujący: filtrować strumień i dla każdego pasującego wiersza wysyłać żądanie HTTP POST.

#!/usr/bin/env bash
# Real-time alert: send every ERROR line to a Slack channel
LOGFILE='/var/log/myapp/app.log'
WEBHOOK_URL='https://hooks.slack.com/services/T000/B000/XXXX'

tail -F "$LOGFILE" | grep --line-buffered -i 'error' | while IFS= read -r line; do
  payload=$(printf '{"text":"*[ERROR ALERT]*\n%s"}' "$line")
  curl -s -o /dev/null -X POST -H 'Content-Type: application/json' \
    -d "$payload" "$WEBHOOK_URL"
done

Ograniczanie częstotliwości alertów, aby zapobiec nadmiarowi powiadomień

Gwałtowny napływ wpisów do dziennika może generować tysiące wierszy błędów na minutę. Wysyłanie jednej wiadomości Slack na każdy wiersz przepełni kanał i doprowadzi do zmęczenia alertami. Potrzebują Państwo ograniczania częstotliwości — należy wysłać alert, a następnie wstrzymać kolejne powiadomienia na czas ochłodzenia.

Można to osiągnąć za pomocą prostego pliku ze znacznikiem czasu: zapisuje się w nim moment wysłania ostatniego alertu i pomija wysyłanie, jeśli czas ochłodzenia jeszcze nie upłynął.

#!/usr/bin/env bash
# Alert on ERROR lines but no more than once every 60 seconds
LOGFILE='/var/log/myapp/app.log'
WEBHOOK_URL='https://hooks.slack.com/services/T000/B000/XXXX'
COOLDOWN=60
LAST_ALERT_FILE='/tmp/last_alert_ts'

tail -F "$LOGFILE" | grep --line-buffered -i 'error' | while IFS= read -r line; do
  now=$(date +%s)
  last=0
  [ -f "$LAST_ALERT_FILE" ] && last=$(cat "$LAST_ALERT_FILE")

  if (( now - last >= COOLDOWN )); then
    echo "$now" > "$LAST_ALERT_FILE"
    payload=$(printf '{"text":"*[ERROR ALERT]*\n%s"}' "$line")
    curl -s -o /dev/null -X POST -H 'Content-Type: application/json' \
      -d "$payload" "$WEBHOOK_URL"
    echo "[$(date)] Alert sent: $line"
  else
    echo "[$(date)] Suppressed (cooldown): $line"
  fi
done

Zliczanie serii błędów za pomocą okna przesuwnego

Pojedynczy wiersz błędu nie zawsze jest istotny — ale 20 błędów w ciągu 30 sekund to poważny problem. Licznik oparty na oknie przesuwnym pozwala uruchamiać alerty dopiero po przekroczeniu progu częstości błędów, ograniczając liczbę fałszywych alarmów.

Technika ta zapisuje znaczniki czasu epoki dla każdego pasującego zdarzenia w pliku tymczasowym, a następnie przed podjęciem decyzji o wysłaniu alertu zlicza te, które mieszczą się w oknie.

#!/usr/bin/env bash
# Alert when more than 10 errors occur within any 60-second window
LOGFILE='/var/log/myapp/app.log'
WINDOW=60
THRESHOLD=10
TS_FILE='/tmp/error_timestamps'
WEBHOOK_URL='https://hooks.slack.com/services/T000/B000/XXXX'

tail -F "$LOGFILE" | grep --line-buffered -i 'error' | while IFS= read -r line; do
  now=$(date +%s)
  echo "$now" >> "$TS_FILE"

  # Keep only timestamps within the window
  cutoff=$(( now - WINDOW ))
  tmp=$(mktemp)
  awk -v c="$cutoff" '$1 > c' "$TS_FILE" > "$tmp" && mv "$tmp" "$TS_FILE"

  count=$(wc -l < "$TS_FILE")
  if (( count > THRESHOLD )); then
    msg="*[BURST ALERT]* ${count} errors in ${WINDOW}s — last: ${line}"
    curl -s -o /dev/null -X POST -H 'Content-Type: application/json' \
      -d "{\"text\":\"$msg\"}" "$WEBHOOK_URL"
    # Clear to avoid re-alerting until next burst
    > "$TS_FILE"
  fi
done

journalctl -f: śledzenie dzienników systemd

We współczesnych systemach Linux (RHEL, Ubuntu 20.04+, Debian 10+) usługi zapisują dane w dzienniku systemd, a nie w zwykłych plikach tekstowych. journalctl -f jest odpowiednikiem tail -F dla dziennika.

Przydatne opcje:

  • -u myapp.service — śledzenie tylko określonej jednostki
  • -p err — filtrowanie według priorytetu (emerg, alert, crit, err, warning, notice, info, debug)
  • --since '5 min ago' — rozpoczęcie od względnego punktu w czasie
  • -o json — wyjście w postaci ustrukturyzowanego JSON do przetwarzania maszynowego
# Follow only error-and-above entries for nginx
journalctl -f -u nginx.service -p err

# Stream journal as JSON and extract MESSAGE field with jq
journalctl -f -u myapp.service -o json | \
  jq --unbuffered -r 'select(.PRIORITY <= "3") | .MESSAGE'

multitail i monitorowanie wielu źródeł z oznaczeniami kolorami

Gdy trzeba jednocześnie obserwować kilka źródeł dzienników, multitail dzieli terminal na panele — każdy śledzi inny plik lub polecenie — i opcjonalnie stosuje kolory według wzorca.

Jeśli multitail nie jest zainstalowany, lekką alternatywą napisaną wyłącznie w Bashu jest poprzedzenie każdego strumienia nazwą źródła i połączenie ich w jednym widoku.

# multitail: watch nginx access + error + app log in split panes
# (requires: apt install multitail  or  brew install multitail)
multitail /var/log/nginx/access.log /var/log/nginx/error.log /var/log/myapp/app.log

# Pure-Bash alternative — merge three streams with labeled prefixes
(
  tail -F /var/log/nginx/access.log | sed --unbuffered 's/^/[nginx-access] /' &
  tail -F /var/log/nginx/error.log  | sed --unbuffered 's/^/[nginx-error]  /' &
  tail -F /var/log/myapp/app.log    | sed --unbuffered 's/^/[myapp]        /' &
  wait
)

Budowanie samodzielnego demona alertów

Łącząc wszystkie elementy tej lekcji, demon alertów klasy produkcyjnej powinien:

  • Niezawodnie śledzić plik dziennika za pomocą tail -F
  • Filtrować krytyczne wzorce za pomocą buforowanego grep
  • Ograniczać częstotliwość powiadomień, aby uniknąć zmęczenia alertami
  • Rejestrować własną aktywność, aby można było kontrolować, co zostało wysłane
  • Działać jako proces w tle zarządzany przez systemd lub nadzorcę

Poniższy skrypt to minimalny, ale kompletny demon, który można umieścić w /usr/local/bin/ i zarządzać nim za pomocą systemd.

#!/usr/bin/env bash
# log_alert_daemon.sh — tail a log and fire Slack alerts with cooldown
set -euo pipefail

LOGFILE=${1:-'/var/log/myapp/app.log'}
PATTERN=${2:-'error|critical|fatal'}
WEBHOOK_URL=${SLACK_WEBHOOK_URL:?'Set SLACK_WEBHOOK_URL env var'}
COOLDOWN=${ALERT_COOLDOWN:-120}
DAEMON_LOG='/var/log/log_alert_daemon.log'
LAST_SENT_FILE='/tmp/log_alert_last_sent'

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$DAEMON_LOG"; }

log "Starting alert daemon: watching $LOGFILE for pattern: $PATTERN"

tail -F "$LOGFILE" | grep --line-buffered -Ei "$PATTERN" | while IFS= read -r line; do
  now=$(date +%s)
  last=0
  [ -f "$LAST_SENT_FILE" ] && last=$(cat "$LAST_SENT_FILE")

  if (( now - last >= COOLDOWN )); then
    echo "$now" > "$LAST_SENT_FILE"
    msg=$(printf '{"text":"*[ALERT]* %s\n%s"}' "$(hostname)" "$line")
    if curl -s -o /dev/null -w '%{http_code}' -X POST \
         -H 'Content-Type: application/json' -d "$msg" "$WEBHOOK_URL" | grep -q '^200$'; then
      log "Alert sent: $line"
    else
      log "Alert FAILED to send: $line"
    fi
  else
    log "Suppressed (cooldown ${COOLDOWN}s): $line"
  fi
done

Sprawdzenie wiedzy: potoki dzienników strumieniowych

Sprawdźcie Państwo swoją znajomość śledzenia dzienników w czasie rzeczywistym i alertów strumieniowych.

Potok Bash śledzi plik dziennika i wysyła alert Slack dla każdego pasującego wiersza. Podczas gwałtownego napływu wpisów w ciągu 10 sekund zostaje zapisanych 3000 wierszy błędów. Która pojedyncza zmiana najskuteczniej zapobiega zalaniu kanału Slack 3000 wiadomościami przez skrypt?

Podsumowanie lekcji: śledzenie dzienników w czasie rzeczywistym i alerty strumieniowe

W tej lekcji zbudowali Państwo od podstaw kompletny potok obserwowalności dzienników w czasie rzeczywistym:

  • tail -F śledzi plik dziennika na podstawie jego nazwy i działa mimo rotacji dzienników — w środowisku produkcyjnym należy zawsze preferować je zamiast tail -f
  • grep --line-buffered filtruje strumień na żywo bez wprowadzania opóźnień; tę opcję należy zawsze dodawać do poleceń grep używanych w potoku
  • awk z fflush() wzbogaca każdy wiersz o znaczniki czasu lub wyodrębnione pola w sposób bezpieczny dla przetwarzania strumieniowego
  • Webhooki Slack za pośrednictwem curl dostarczają alerty za pomocą pojedynczego żądania HTTP POST — bez potrzeby używania SDK
  • Pliki czasu ochłodzenia zapobiegają zmęczeniu alertami podczas gwałtownego napływu wpisów, wymuszając minimalny odstęp między powiadomieniami
  • Liczniki okna przesuwnego wykrywają serie błędów (alertowanie oparte na częstości), zamiast reagować na każdy pojedynczy wiersz
  • journalctl -f jest natywnym dla systemd odpowiednikiem tail -F, z wbudowanym filtrowaniem według priorytetu i obsługą wyjścia JSON
  • Samodzielny skrypt demona alertów łączy wszystkie te wzorce i może być zarządzany przez systemd, zapewniając niezawodność w środowisku produkcyjnym

Te podstawowe mechanizmy składają się na fundament dowolnego niestandardowego potoku obserwowalności — bez potrzeby używania agenta innej firmy.

Często zadawane pytania

Czy lekcja „Śledzenie logów w czasie rzeczywistym i alerty strumieniowe” jest bezpłatna?

Tak — pełny tekst „Śledzenie logów w czasie rzeczywistym i alerty strumieniowe” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu DevOps Bootcamp, przejdź na CoddyKit PRO. Kurs DevOps Bootcamp zawiera 4 lekcji w sumie.

Co nauczysz się w „Śledzenie logów w czasie rzeczywistym i alerty strumieniowe”?

Śledź i filtruj strumienie logów na żywo, aby wyzwalać alerty natychmiast po pojawieniu się wzorców błędów. Ćwiczysz DevOps Bootcamp z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć DevOps Bootcamp?

Nie wymagamy żadnego doświadczenia. DevOps Bootcamp w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Śledzenie logów w czasie rzeczywistym i alerty strumieniowe”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji DevOps Bootcamp?

Tak. Każda lekcja DevOps Bootcamp zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Parsowanie logów internetowych i aplikacyjnych na dużą skalę
  2. Śledzenie logów w czasie rzeczywistym i alerty strumieniowe
  3. Odpytywanie journald za pomocą journalctl w skryptach
  4. Obliczanie metryk i histogramów ze strumieni logów
← Powrót do DevOps Bootcamp