DevOps Bootcamp · Lezione

Seguire i log in tempo reale e generare avvisi in streaming

Segua e filtri i flussi di log in tempo reale per attivare avvisi non appena compaiono pattern di errore.

Lezione 2 di 413 passaggi

Seguire i log in tempo reale e generare avvisi in streaming è una lezione DevOps Bootcamp gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento DevOps Bootcamp, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso DevOps Bootcamp include 4 lezioni in totale.

Perché seguire i log in tempo reale è importante

Nei sistemi di produzione, i file di log crescono continuamente. Aspettare che venga segnalato un problema prima di esaminare i log significa che il downtime ha già avuto un costo. Il seguimento dei log in tempo reale consente di osservare gli eventi nel momento stesso in cui vengono scritti, permettendo di reagire immediatamente a guasti, eventi di sicurezza e cali di prestazioni.

  • I server web scrivono una riga per ogni richiesta: gli errori compaiono immediatamente
  • I demoni delle applicazioni registrano le stack trace nel momento stesso in cui si verifica un'eccezione
  • I sistemi di autenticazione registrano in tempo reale i tentativi di accesso non riusciti

Lo strumento Unix fondamentale per questo scopo è tail -f, combinato con utility di filtraggio e avviso per trasformare i flussi di log grezzi in segnali utili.

tail -f: seguire un log in tempo reale

tail -f (follow) mantiene aperto il file e stampa le nuove righe man mano che vengono aggiunte. È lo strumento per i log in tempo reale più semplice e universalmente disponibile.

Modelli di utilizzo comuni:

  • tail -f /var/log/syslog — segue il log di sistema
  • tail -n 50 -f app.log — mostra le ultime 50 righe e poi continua a seguire il file
  • tail -f /var/log/nginx/access.log — segue in tempo reale le richieste a nginx

Premere Ctrl+C per interrompere. Il processo rimane collegato finché non lo annulla o il terminale non viene chiuso.

#!/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: superare la rotazione dei log

Molti sistemi ruotano i file di log a mezzanotte o quando raggiungono un determinato limite di dimensione. In tal caso, il file originale viene rinominato (ad esempio app.log.1) e ne viene creato uno nuovo, app.log. Con tail -f si continua a leggere silenziosamente il file vecchio rinominato, perdendo tutto il nuovo output.

tail -F (F maiuscola) risolve il problema monitorando il nome del file, non il descrittore del file. Quando il file scompare e ricompare, tail -F lo riapre automaticamente e continua a seguirlo.

  • Negli script di produzione, preferisca sempre tail -F a tail -f
  • Funziona con logrotate, newsyslog e i driver di log Docker che ruotano i file
# 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

Filtrare il flusso con grep

Seguire un log molto attivo senza filtrarlo può essere opprimente: un server web sotto carico può scrivere centinaia di righe al secondo. Inoltri l'output di tail -F a grep per isolare solo i modelli di interesse.

Opzioni principali di grep per i flussi:

  • --line-buffered — scarica immediatamente ogni riga corrispondente invece di memorizzarla nel buffer; è necessario nelle pipeline, altrimenti l'output potrebbe essere ritardato o perso
  • -i — corrispondenza senza distinzione tra maiuscole e minuscole
  • -E — espressione regolare estesa per le alternative (error|warn|crit)
  • -v — inverte la corrispondenza (esclude le righe)
# 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'

Aggiungere timestamp e contesto con awk

A volte le righe di log non contengono il contesto utile per il triage. Può arricchire il flusso in tempo reale utilizzando awk: aggiungendo un timestamp locale, estraendo campi o riformattando l'output per migliorarne la leggibilità.

awk viene inoltre eseguito in modalità streaming (con buffer per riga) quando riceve dati tramite una pipe, perciò può essere utilizzato in sicurezza nelle pipeline in tempo reale senza opzioni aggiuntive.

# 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'

Inviare avvisi con i webhook di Slack

Il filtraggio è solo metà del lavoro: una volta rilevato un modello di errore, è necessario avvisare qualcuno. Un webhook in ingresso di Slack consente di inviare un messaggio a un canale con una singola chiamata a curl, senza richiedere SDK di Slack né credenziali oltre all'URL del webhook.

Lo schema è il seguente: filtrare il flusso e inviare una richiesta HTTP POST per ogni riga corrispondente.

#!/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

Limitare la frequenza degli avvisi per evitare il rumore

Un'ondata di log può generare migliaia di righe di errore al minuto. Inviare un messaggio Slack per ogni riga inonderebbe il canale e causerebbe assuefazione agli avvisi. È necessario applicare un rate limiting: attivare l'avviso e poi sopprimere le notifiche successive per un periodo di cooldown.

Si ottiene questo risultato con un semplice file contenente un timestamp: si registra l'ora dell'ultimo avviso inviato e si evita di attivarne uno nuovo se il periodo di cooldown non è ancora trascorso.

#!/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

Contare le raffiche di errori con una finestra scorrevole

A volte una singola riga di errore non è significativa, ma 20 errori in 30 secondi rappresentano un problema serio. Un contatore a finestra scorrevole consente di attivare gli avvisi solo quando viene superata una soglia del tasso di errori, riducendo i falsi positivi.

La tecnica memorizza in un file temporaneo il timestamp epoch di ogni evento corrispondente, quindi conta quanti eventi rientrano nella finestra prima di decidere se inviare l'avviso.

#!/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: seguire i journal di systemd

Nei moderni sistemi Linux (RHEL, Ubuntu 20.04+, Debian 10+), i servizi scrivono nel journal di systemd anziché in semplici file di testo. journalctl -f è l'equivalente di tail -F per il journal.

Opzioni utili:

  • -u myapp.service — segue solo una determinata unità
  • -p err — filtra per priorità (emerg, alert, crit, err, warning, notice, info, debug)
  • --since '5 min ago' — inizia da un momento relativo
  • -o json — produce JSON strutturato per l'analisi automatica
# 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 e monitoraggio multifornte con codifica a colori

Quando deve monitorare diverse origini di log contemporaneamente, multitail divide il terminale in riquadri, ognuno dei quali segue un file o un comando diverso, con la possibilità di applicare colori in base al modello.

Se multitail non è installato, un'alternativa leggera in puro Bash consiste nel anteporre a ogni flusso il nome della relativa origine e unirli in un'unica vista.

# 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
)

Creare un demone di avvisi autonomo

Riunendo tutti gli elementi di questa lezione, un demone di avvisi adatto alla produzione dovrebbe:

  • Seguire il file di log in modo affidabile con tail -F
  • Filtrare i modelli critici con grep dotato di buffering
  • Limitare la frequenza delle notifiche per evitare l'assuefazione agli avvisi
  • Registrare la propria attività, così da consentire l'audit di ciò che è stato inviato
  • Eseguire come processo in background gestito da systemd o da un supervisor

Lo script seguente è un demone minimo ma completo, che può inserire in /usr/local/bin/ e gestire con 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

Verifica delle conoscenze: pipeline di log in streaming

Verifichi la sua comprensione del seguimento dei log in tempo reale e degli avvisi in streaming.

Una pipeline Bash segue un file di log e invia un avviso Slack per ogni riga corrispondente. Durante un'ondata di log, in 10 secondi vengono scritte 3.000 righe di errore. Quale singola modifica impedisce meglio allo script di inondare il canale Slack con 3.000 messaggi?

Riepilogo della lezione: seguimento dei log in tempo reale e avvisi in streaming

In questa lezione ha creato da zero una pipeline completa di osservabilità dei log in tempo reale:

  • tail -F segue un file di log in base al nome, resistendo alla rotazione dei log: in produzione lo preferisca sempre a tail -f
  • grep --line-buffered filtra il flusso in tempo reale senza introdurre latenza; aggiunga sempre questa opzione ai comandi grep con pipe
  • awk con fflush() arricchisce ogni riga con timestamp o campi estratti in modo sicuro per lo streaming
  • Webhook Slack tramite curl invia avvisi con una singola richiesta HTTP POST, senza SDK
  • I file di cooldown prevengono l'assuefazione agli avvisi durante le ondate di log, imponendo un intervallo minimo tra le notifiche
  • I contatori a finestra scorrevole rilevano le raffiche di errori (avvisi basati sul tasso) invece di reagire a ogni singola riga
  • journalctl -f è l'equivalente nativo di systemd di tail -F, con filtraggio integrato per priorità e output JSON
  • Uno script demone di avvisi autonomo combina tutti questi schemi e può essere gestito da systemd per garantire l'affidabilità in produzione

Queste primitive si combinano e costituiscono la base di qualsiasi pipeline di osservabilità personalizzata, senza bisogno di agenti di terze parti.

Gratis per iniziare

Impara DevOps Bootcamp con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
142
Lezioni
568

Domande Frequenti

La lezione «Seguire i log in tempo reale e generare avvisi in streaming» è gratuita?

Sì — il testo completo di «Seguire i log in tempo reale e generare avvisi in streaming» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso DevOps Bootcamp, passa a CoddyKit PRO. Il corso DevOps Bootcamp include 4 lezioni in totale.

Cosa imparerò in «Seguire i log in tempo reale e generare avvisi in streaming»?

Segua e filtri i flussi di log in tempo reale per attivare avvisi non appena compaiono pattern di errore. Eserciti DevOps Bootcamp con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare DevOps Bootcamp?

Non è richiesta alcuna esperienza precedente. DevOps Bootcamp su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Seguire i log in tempo reale e generare avvisi in streaming»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione DevOps Bootcamp?

Sì. Ogni lezione DevOps Bootcamp include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Analizzare log web e applicativi su larga scala
  2. Seguire i log in tempo reale e generare avvisi in streaming
  3. Interrogare journald negli script con journalctl
  4. Calcolare metriche e istogrammi dai flussi di log
← Torna a DevOps Bootcamp