Perché analizzare i log del web server
Il log del web server è un file dove il server registra ogni singola richiesta HTTP ricevuta da client esterni — utenti, bot, crawler dei motori di ricerca. Ogni riga corrisponde a un evento: una pagina servita, un’immagine scaricata, un errore restituito, un redirect eseguito.
Analizzare i log è un’attività sottovalutata da molti professionisti SEO, eppure rappresenta l’unica fonte di dati che mostra esattamente cosa succede sul server. Google Search Console fornisce dati aggregati e parziali; i log forniscono il dato grezzo, completo, riga per riga.
Possiamo fare tutte le supposizioni di questo mondo, ma nulla ci darà dati pratici come un log.
Dall’analisi dei log è possibile estrarre informazioni operative su tre dimensioni fondamentali del crawling:
- Frequenza di scansione: quante volte una risorsa viene richiesta dallo spider in un dato intervallo di tempo.
- Volume di scansione: il numero totale di pagine del sito richieste dallo spider.
- Profondità di scansione: il numero di livelli di navigazione raggiunti dallo spider durante il crawling.
Oltre all’analisi SEO, i log sono essenziali per la diagnostica del web server, il monitoraggio delle performance, l’identificazione di attacchi e la compliance normativa (GDPR). Questa guida copre tutti questi aspetti in modo approfondito.
Dove trovare i file di log
Ogni web server scrive i propri log in posizioni predefinite, configurabili dall’amministratore di sistema. I due file principali sono l’access log (registra tutte le richieste ricevute) e l’error log (registra errori, warning e problemi di configurazione).
Apache HTTP Server
Su distribuzioni Debian/Ubuntu il path di default è:
/var/log/apache2/access.log
/var/log/apache2/error.log
Su CentOS/RHEL il path cambia in /var/log/httpd/. La posizione è configurabile tramite le direttive CustomLog e ErrorLog nel file di configurazione del virtualhost. Documentazione ufficiale: Apache HTTP Server 2.4 — Log Files.
Nginx
Il path di default è:
/var/log/nginx/access.log
/var/log/nginx/error.log
La posizione è configurabile tramite le direttive access_log e error_log nel blocco server o http della configurazione Nginx. Documentazione ufficiale: ngx_http_log_module.
Hosting condiviso vs VPS e dedicato
I servizi di hosting condiviso raramente forniscono accesso diretto ai log del server. Alcuni provider li rendono disponibili tramite pannello di controllo (cPanel, Plesk), altri li vendono come servizio aggiuntivo. Con un VPS, un server dedicato o un’infrastruttura cloud, avendo accesso root al sistema operativo, i file di log sono sempre raggiungibili. Se stai valutando un upgrade infrastrutturale, la guida su come configurare un server LEMP copre anche la configurazione dei log.
Anatomia di una riga di log
Ogni riga dell’access log rappresenta una singola richiesta HTTP. Il formato più diffuso è il Combined Log Format, utilizzato di default sia da Apache che da Nginx.
Common Log Format (CLF)
Il formato base definito dalla direttiva Apache:
LogFormat "%h %l %u %t \"%r\" %>s %b" common
Produce righe di questo tipo:
203.0.113.50 - - [20/Feb/2025:14:32:17 +0100] "GET /contatti/ HTTP/2" 200 11631
Combined Log Format
Estende il CLF aggiungendo i campi Referer e User-Agent:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
Esempio reale con il Combined Log Format:
203.0.113.50 - - [20/Feb/2025:14:32:17 +0100] "GET /blog/come-leggere-il-log-del-web-server/ HTTP/2" 200 28453 "https://www.google.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
I campi del log, campo per campo
| Campo | Formato Apache | Esempio | Descrizione |
|---|---|---|---|
| IP client | %h | 203.0.113.50 | Indirizzo IP del client che ha effettuato la richiesta. Se il sito è dietro un reverse proxy o una CDN, questo campo potrebbe contenere l’IP del proxy anziché quello del visitatore. |
| Identd | %l | – | Identità RFC 1413 del client. Quasi sempre un trattino (-) perché il protocollo identd è obsoleto e inaffidabile. |
| User | %u | – | Nome utente autenticato via HTTP Basic/Digest Auth. Trattino se la risorsa non richiede autenticazione. |
| Timestamp | %t | [20/Feb/2025:14:32:17 +0100] | Data e ora della richiesta nel formato [giorno/mese/anno:ora:min:sec timezone]. |
| Request line | %r | GET /blog/ HTTP/2 | Metodo HTTP + URI richiesto + versione del protocollo. |
| Status code | %>s | 200 | Codice di stato HTTP finale della risposta. |
| Bytes | %b | 28453 | Dimensione del corpo della risposta in byte, esclusi gli header. Un trattino se zero. |
| Referer | %{Referer}i | https://www.google.com/ | La pagina da cui proviene il visitatore. Utile per identificare le sorgenti di traffico (referral). |
| User-Agent | %{User-agent}i | Mozilla/5.0 (…) Chrome/131.0 | Stringa identificativa del client: browser, bot o altro software. |
Metodi HTTP nella request line
Il primo elemento della request line è il metodo HTTP. I più frequenti nei log:
- GET — Richiesta di una risorsa (pagina, immagine, file CSS/JS). È il metodo più comune nei log.
- HEAD — Come GET ma senza corpo della risposta. Legge solo l’intestazione HTTP. Usato da bot e sistemi di monitoring per verificare che una risorsa esista senza scaricarla.
- POST — Invio di dati al server (form, login, API). Frequente su endpoint come
/wp-login.php,/wp-admin/admin-ajax.php,/wp-json/. - PUT / DELETE / PATCH — Metodi delle REST API. Se appaiono nei log da IP sconosciuti, possono indicare tentativi di exploit.
Configurazione dei log: Apache vs Nginx
Entrambi i web server offrono un controllo granulare sul formato e sulla destinazione dei log. Capire le direttive di configurazione è fondamentale per personalizzare il logging in base alle esigenze di analisi.
Direttive Apache
Apache gestisce i log tramite il modulo mod_log_config (documentazione ufficiale). Le direttive principali:
# Definizione del formato
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
# Assegnazione del log a un virtualhost
CustomLog /var/log/apache2/access.log combined
# Error log con livello di severità
ErrorLog /var/log/apache2/error.log
LogLevel warn
# Log condizionale: escludi risorse statiche e health check
SetEnvIf Request_URI "^/health$" dontlog
SetEnvIf Request_URI "\.(css|js|ico|jpg|png|gif|woff2)$" dontlog
CustomLog /var/log/apache2/access.log combined env=!dontlog
Il log condizionale è particolarmente utile per ridurre il rumore nei log: escludendo le risorse statiche si ottiene un file più leggibile, focalizzato sulle richieste a pagine e endpoint significativi.
Direttive Nginx
Nginx gestisce i log tramite il modulo ngx_http_log_module (documentazione ufficiale). Le direttive principali:
# Definizione del formato (nel blocco http)
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
# Assegnazione nel blocco server
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
# Buffered logging per performance su siti ad alto traffico
access_log /var/log/nginx/access.log main buffer=32k flush=5m;
# Log condizionale: escludi risposte 2xx e 3xx
map $status $loggable {
~^[23] 0;
default 1;
}
access_log /var/log/nginx/errors-only.log main if=$loggable;
Variabili Nginx più utili per l’analisi
| Variabile | Descrizione |
|---|---|
$remote_addr | IP del client |
$time_iso8601 | Timestamp in formato ISO 8601 (ideale per parsing automatico) |
$request | Request line completa (metodo + URI + protocollo) |
$status | Codice di stato HTTP |
$body_bytes_sent | Byte inviati al client (esclusi header) |
$request_time | Tempo di elaborazione della richiesta in secondi (risoluzione ms) |
$upstream_response_time | Tempo di risposta del backend (PHP-FPM, upstream) |
$http_user_agent | User-Agent del client |
$http_referer | Header Referer |
$request_length | Dimensione totale della richiesta (riga + header + body) |
$connection | Numero seriale della connessione |
Nota: le variabili $request_time e $upstream_response_time sono cruciali per il performance monitoring. Aggiungendole al log format si ottiene visibilità immediata sui tempi di risposta di ogni richiesta, senza bisogno di strumenti di APM esterni.
Status code HTTP nei log
Il codice di stato HTTP è uno dei campi più importanti nell’analisi dei log. Definito dalla RFC 9110 (HTTP Semantics) e dal registro IANA, la prima cifra identifica la categoria di risposta. Per un approfondimento completo, consulta la guida dedicata agli status code HTTP.
1xx — Informational
| Codice | Nome | Rilevanza nei log |
|---|---|---|
| 100 | Continue | Raro nei log. Il client può proseguire con il corpo della richiesta. |
| 103 | Early Hints | Usato per il preload di risorse (link header). Visibile con HTTP/2+. |
2xx — Success
| Codice | Nome | Rilevanza nei log |
|---|---|---|
| 200 | OK | Risposta standard di successo. La risorsa è stata servita correttamente. |
| 201 | Created | Nuova risorsa creata (tipico delle REST API, POST). |
| 204 | No Content | Successo senza corpo. Comune nelle risposte a richieste AJAX e preflight CORS. |
| 206 | Partial Content | Range request soddisfatta. Frequente per download di file grandi e streaming video. |
3xx — Redirection
| Codice | Nome | Rilevanza nei log |
|---|---|---|
| 301 | Moved Permanently | Redirect permanente. Trasferisce il valore SEO alla nuova URL. Catene di 301 consecutive indicano un problema da correggere. |
| 302 | Found | Redirect temporaneo. Se usato al posto di un 301 può causare problemi di indicizzazione. |
| 304 | Not Modified | La risorsa non è cambiata dalla cache del client. Nei log di Googlebot indica che il bot sta usando la cache. |
| 307 | Temporary Redirect | Come 302 ma preserva il metodo HTTP. Usato da HSTS per il redirect HTTP→HTTPS. |
| 308 | Permanent Redirect | Come 301 ma preserva il metodo HTTP. |
Per capire la differenza tra rewrite e redirect e come ciascuno appare nei log, è importante notare che un rewrite è gestito internamente dal server e non genera una riga di log con status 3xx, mentre un redirect produce sempre una risposta con codice 301/302/307/308.
4xx — Client Error
| Codice | Nome | Rilevanza nei log |
|---|---|---|
| 400 | Bad Request | Richiesta malformata. Possibile indicatore di attacco o client buggato. |
| 401 | Unauthorized | Autenticazione richiesta. Molti 401 dallo stesso IP = possibile brute force. |
| 403 | Forbidden | Accesso negato. Può indicare permessi file errati o regole del WAF che bloccano la richiesta. |
| 404 | Not Found | Risorsa non trovata. Un alto volume di 404 verso Googlebot spreca crawl budget. Da monitorare costantemente. |
| 410 | Gone | Risorsa rimossa definitivamente. Più forte del 404: comunica a Google che la pagina non tornerà. |
| 429 | Too Many Requests | Rate limiting applicato. Se Googlebot riceve 429, rallenta il crawling del sito. |
5xx — Server Error
| Codice | Nome | Rilevanza nei log |
|---|---|---|
| 500 | Internal Server Error | Errore generico lato server. Spesso causato da plugin PHP, memory limit o errori di configurazione. |
| 502 | Bad Gateway | Il proxy/reverse proxy ha ricevuto una risposta invalida dal backend (es. PHP-FPM crash). |
| 503 | Service Unavailable | Server sovraccarico o in manutenzione. Se Googlebot lo riceve ripetutamente, de-indicizza temporaneamente le pagine. |
| 504 | Gateway Timeout | Il backend non ha risposto in tempo. Indica query lente, PHP timeout o risorse esaurite. |
Log strutturati in formato JSON
Il formato tradizionale dei log (testo piano con campi separati da spazi) è leggibile dall’uomo ma difficile da parsare in modo affidabile — basta uno spazio nell’URL o nel User-Agent per rompere il parsing basato su delimitatori. Il JSON logging risolve questo problema producendo eventi strutturati e machine-parsable, ideali per pipeline di analisi moderne (ELK, Loki, CloudWatch).
Configurazione JSON per Nginx
Nginx supporta nativamente il log in formato JSON dal parametro escape=json (disponibile dalla versione 1.11.8):
log_format json_combined escape=json
'{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.json json_combined;
Ogni riga del log sarà un oggetto JSON valido:
{"time":"2025-02-20T14:32:17+01:00","remote_addr":"203.0.113.50","request":"GET /blog/ HTTP/2","status":200,"body_bytes_sent":28453,"request_time":0.045,"http_referer":"https://www.google.com/","http_user_agent":"Mozilla/5.0 ..."}
Best practice per il logging strutturato
- Usa timestamp ISO 8601 (
$time_iso8601) invece del formato CLF — è parsabile senza ambiguità da qualsiasi tool. - Usa tipi corretti: numeri come numeri (
$status,$request_timesenza virgolette), stringhe tra virgolette. - Aggiungi un request_id per correlare le richieste tra access log, error log e log applicativi.
- Non loggare dati sensibili: password, token, cookie di sessione, dati di carte di credito.
- Mantieni il nesting piatto (massimo 2-3 livelli) per facilitare le query nei sistemi di log management.
Error log e livelli di severità
Oltre all’access log, ogni web server scrive un error log che registra errori, warning e messaggi diagnostici. Questo file è fondamentale per il debugging: permesso negato su un file, modulo non caricato, upstream timeout, configurazione errata. Per WordPress esiste anche il log di debug dedicato (debug.log), che registra errori PHP e notice generati da temi e plugin.
Esempio di riga dall’error log Apache:
[Thu Feb 20 14:32:17.902022 2025] [core:error] [pid 35708:tid 4328636416] [client 203.0.113.50] File does not exist: /var/www/html/favicon.ico
I componenti sono: timestamp (con precisione al microsecondo), modulo che ha generato l’errore, livello di severità, PID/TID del processo, IP del client, e il messaggio di errore.
Livelli di severità a confronto
| Livello | Apache | Nginx | Descrizione |
|---|---|---|---|
| 0 | emerg | emerg | Sistema inutilizzabile. Il server non può funzionare. |
| 1 | alert | alert | Azione immediata richiesta. |
| 2 | crit | crit | Condizione critica (es. errore SSL, socket esaurite). |
| 3 | error | error | Errore nell’elaborazione di una richiesta. Livello default di Nginx. |
| 4 | warn | warn | Situazione anomala ma non bloccante. |
| 5 | notice | notice | Evento normale ma degno di nota. |
| 6 | info | info | Messaggi informativi. |
| 7 | debug | debug | Messaggi di debug dettagliati. In Nginx richiede la compilazione con --with-debug. |
| 8-15 | trace1-trace8 | — | Solo Apache 2.4+. Livelli di tracciamento con dettaglio crescente, utili per il debug di moduli specifici. |
Apache 2.4 supporta anche il logging per modulo, che permette di alzare il livello di debug solo per componenti specifici senza inondare l’error log:
# Livello info generale, ma trace5 per il modulo rewrite
LogLevel info rewrite:trace5
Tool per l’analisi dei log
L’analisi manuale dei log (con Excel, grep o awk) funziona per verifiche puntuali su file piccoli, ma diventa impraticabile su siti con milioni di richieste giornaliere. Esistono tool dedicati che automatizzano il parsing, l’aggregazione e la visualizzazione dei dati.
Screaming Frog Log File Analyser
Screaming Frog — noto per il suo crawler SEO — ha sviluppato un tool specifico per l’analisi dei log: il Log File Analyser. Importa log di Apache, Nginx e IIS, identifica automaticamente Googlebot e altri bot, e produce report su: pagine più scansionate, frequenza di crawling, status code per bot, pagine orfane (non scansionate). È il tool più accessibile per chi viene dal mondo SEO.
GoAccess
GoAccess è un analizzatore di log open source, real-time, che funziona sia da terminale che come report HTML interattivo. Supporta Apache, Nginx, Amazon S3, CloudFront e formati custom. È leggero, veloce e ideale per analisi rapide direttamente sul server:
# Report HTML interattivo con aggiornamento real-time
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --real-time-html --log-format=COMBINED
# Analisi da terminale
goaccess /var/log/nginx/access.log --log-format=COMBINED
ELK Stack (Elasticsearch, Logstash, Kibana)
Lo stack ELK è la soluzione enterprise più diffusa per il log management centralizzato. I tre componenti lavorano in pipeline:
- Filebeat — Agent leggero installato sul server, raccoglie i log e li invia a Logstash o direttamente a Elasticsearch.
- Logstash — Pipeline di trasformazione: parsa i log, arricchisce i dati (geoIP, user-agent parsing), li indicizza.
- Elasticsearch — Motore di ricerca e analytics basato su Apache Lucene. Memorizza e indicizza i log.
- Kibana — Interfaccia di visualizzazione: dashboard, grafici, esplorazione real-time dei dati.
ELK è potente ma complesso da gestire. Richiede risorse significative (RAM, storage) e competenze di amministrazione. Adatto a infrastrutture con più server e volumi di log elevati.
Grafana Loki
Grafana Loki è un’alternativa più leggera a ELK, progettata da Grafana Labs. La differenza architetturale chiave: Loki indicizza solo le label/metadati dei log, non il contenuto completo. Questo lo rende molto più economico in termini di storage e risorse. La query language LogQL (simile a PromQL) permette ricerche potenti. Loki 3.0 (aprile 2024) ha introdotto bloom filter per accelerare le query e il supporto nativo per OpenTelemetry.
Graylog
Graylog è un sistema open source di log management con capacità SIEM (Security Information and Event Management). Supporta oltre 1M eventi/secondo, offre dashboard, alerting, e il supporto a Sigma 2.0 per regole di threat detection. Il tier gratuito copre fino a 5 GB/giorno con alerting e accesso API. È una buona via di mezzo tra la semplicità di GoAccess e la potenza di ELK.
Tabella comparativa
| Tool | Tipo | Real-time | Scalabilità | Complessità |
|---|---|---|---|---|
| Screaming Frog LFA | Desktop (GUI) | No | File singoli | Bassa |
| GoAccess | CLI / HTML | Sì | Server singolo | Bassa |
| ELK Stack | Self-hosted / Cloud | Sì | Multi-server, petabyte | Alta |
| Grafana Loki | Self-hosted / Cloud | Sì | Multi-server, costo-efficiente | Media |
| Graylog | Self-hosted | Sì | Multi-server, SIEM | Media |
Analisi dei log in tempo reale da terminale
Per verifiche rapide e debugging live, niente batte il terminale. I comandi seguenti permettono di monitorare il log in tempo reale, filtrare per pattern specifici e isolare le informazioni rilevanti usando espressioni regolari.
tail e grep
# Segui il log in tempo reale (tutte le richieste)
tail -f /var/log/nginx/access.log
# Filtra solo le richieste di Googlebot
tail -f /var/log/nginx/access.log | grep 'Googlebot'
# Filtra errori 5xx in tempo reale
tail -f /var/log/nginx/access.log | grep '" 5[0-9][0-9] '
# Mostra solo URL e status code delle richieste di Googlebot
grep 'Googlebot' /var/log/nginx/access.log | awk '{print $7, $9}'
# Conta le richieste per status code
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
Nota: i numeri dei campi awk ({print $7, $9}) dipendono dal formato del log. Con il Combined Log Format di Nginx, $7 è l’URI e $9 lo status code. Verifica sempre sul tuo file.
multitail
multitail permette di monitorare più file di log contemporaneamente in split-screen, con filtri colorati:
# Access log e error log in split-screen
multitail /var/log/nginx/access.log /var/log/nginx/error.log
# Con filtri colorati: verde per access, rosso per error
multitail -ci green /var/log/nginx/access.log -ci red /var/log/nginx/error.log
journalctl (systemd)
Sui sistemi con systemd, journalctl è il tool nativo per interrogare i log dei servizi:
# Segui i log di Nginx in tempo reale
journalctl -u nginx.service -f
# Log di Nginx degli ultimi 30 minuti
journalctl -u nginx.service --since "30 min ago"
# Solo errori (livello error e superiori)
journalctl -u nginx.service -p err
# Output in JSON per parsing automatico
journalctl -u nginx.service -o json-pretty
# Log combinati di più servizi (Nginx + PHP-FPM)
journalctl -u nginx.service -u php8.2-fpm.service -f
Comandi utili per filtrare Googlebot
# Top 20 URL più scansionati da Googlebot
grep 'Googlebot' /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20
# Richieste Googlebot con errore (4xx e 5xx)
grep 'Googlebot' /var/log/nginx/access.log | awk '$9 ~ /^[45]/ {print $9, $7}' | sort | uniq -c | sort -rn
# Volume giornaliero di richieste Googlebot
grep 'Googlebot' /var/log/nginx/access.log | awk '{print $4}' | cut -d: -f1 | tr -d '[' | sort | uniq -c
# Tempo medio di risposta per Googlebot (richiede $request_time nel log)
grep 'Googlebot' /var/log/nginx/access.log | awk '{sum+=$NF; n++} END {print sum/n " sec"}'
Gestione dei file di log
Concatenare più file di log
I log vengono spesso ruotati quotidianamente o settimanalmente, generando più file. Per analisi su periodi estesi è necessario concatenarli.
Linux/macOS:
# Concatena tutti i file di log in uno solo
cat /var/log/nginx/access.log.* > /tmp/combined.log
# Se i file ruotati sono compressi (.gz)
zcat /var/log/nginx/access.log.*.gz > /tmp/combined.log
# Concatena e ordina cronologicamente
cat /var/log/nginx/access.log.* | sort -t'[' -k2 > /tmp/combined_sorted.log
Windows (Command Prompt):
for /R %f in (*.log.*) do type "%f" >> c:\temp\output.log
Log rotation con logrotate
Senza rotazione, i file di log crescono indefinitamente fino a saturare il disco. Logrotate è il tool standard su Linux per gestire la rotazione automatica, la compressione e la retention dei log.
Configurazione tipica per Nginx in /etc/logrotate.d/nginx:
/var/log/nginx/*.log {
daily # Ruota ogni giorno
rotate 30 # Mantieni 30 file ruotati (30 giorni di storico)
compress # Comprimi i file ruotati con gzip
delaycompress # Comprimi dal secondo giorno (il file corrente resta in chiaro)
notifempty # Non ruotare se il file è vuoto
missingok # Non generare errore se il file non esiste
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
Il segnale USR1 nel postrotate dice a Nginx di riaprire i file di log senza riavviare il servizio. Senza questo passaggio, Nginx continuerebbe a scrivere nel file ruotato (rinominato).
Comandi utili per il debug di logrotate:
# Dry run: mostra cosa farebbe senza eseguire
logrotate -d /etc/logrotate.d/nginx
# Forza la rotazione manuale
logrotate -f /etc/logrotate.d/nginx
Analisi dei log per la SEO
L’analisi dei log è una delle attività più preziose nella SEO tecnica. I dati di Search Console mostrano cosa Google ha indicizzato e posizionato; i log mostrano come Googlebot interagisce con il sito — quali pagine scansiona, con che frequenza, con quali risultati.
Crawl budget e comportamento di Googlebot
Nel log troviamo gli accessi di tutti gli User-Agent, ma per l’analisi SEO è particolarmente importante filtrare solo gli spider di Google (Googlebot). Il User-Agent attuale di Googlebot è:
Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.69 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
Google ha dichiarato che Googlebot utilizza l’ultima versione stabile di Chrome per il rendering. Il numero di versione nel User-Agent viene aggiornato periodicamente per riflettere la versione di Chromium in uso.
Il crawl budget rappresenta la quantità di risorse che Google dedica alla scansione di un sito. Analizzando i log si può quantificare esattamente: quante richieste Googlebot effettua al giorno, quali sezioni del sito privilegia, e quanto tempo impiega il server a rispondere.
Fattori che influenzano il crawling
I comportamenti di Googlebot variano da sito a sito e da pagina a pagina. I fattori principali che determinano frequenza, volume e profondità di scansione:
- Originalità dei contenuti — Googlebot tende a scansionare meno siti con contenuti copiati o duplicati.
- Frequenza di pubblicazione — La frequenza con cui si pubblicano nuovi contenuti o si aggiornano quelli esistenti impatta direttamente sulla frequenza di scansione.
- Errori 4xx e 5xx — Quando Googlebot individua errori, in un primo momento esegue richieste successive per verificare un eventuale ripristino. In caso negativo, riduce il crawl rate.
- Velocità del server — Un sito veloce permette a Googlebot di scaricare più risorse nello stesso intervallo di tempo. Se il server è lento, Googlebot riduce il tasso di scansione per non sovraccaricarlo.
- PageRank — Il PageRank è uno dei fattori principali che determina la profondità delle scansioni di Googlebot.
- Link on-page — Una pagina con molti link in uscita di qualità viene controllata più frequentemente.
- Dimensione del sito — Il numero di pagine pubblicate induce lo spider a scansionare il sito più a fondo.
- Struttura di navigazione — Il numero di livelli di navigazione incide sulla profondità di scansione. Siti con troppi livelli vedono una riduzione della copertura nelle sezioni più profonde.
- Link interni — La struttura dei link interni impatta sulla distribuzione del PageRank e quindi sulle priorità di scansione.
- Robots.txt — Le direttive nel robots.txt determinano quali sezioni del sito Googlebot può scansionare e quali deve ignorare.
Domande chiave da porsi analizzando i log
Una volta estratti i dati di Googlebot dai log, queste sono le domande operative che guidano le decisioni SEO:
- Quali sono le pagine più scansionate da Googlebot? Corrispondono alle pagine strategiche del sito?
- Quali pagine importanti non vengono scansionate? Hanno problemi di raggiungibilità o di link interni?
- Con che frequenza Googlebot torna a controllare le pagine principali?
- Quanto tempo impiega il server a rispondere alle richieste di Googlebot? Ci sono pagine lente?
- Googlebot riceve errori 4xx o 5xx? Su quali URL?
- Quanta parte del crawl budget viene sprecata su risorse non importanti (URL parametrizzati, pagine di paginazione, risorse statiche)?
- Quanto rapidamente Googlebot rileva i nuovi contenuti pubblicati?
- Come reagisce Googlebot dopo un cambiamento strutturale (migrazione, redesign, cambio di dominio)?
- Ci sono bot aggressivi che consumano risorse del server senza beneficio?
Per un’analisi avanzata dei pattern di crawling con l’uso di Python e regex, la guida sull’analisi dei log per la negative SEO mostra una metodologia operativa replicabile.
Sicurezza: cosa cercare nei log
I log del web server sono la prima linea di difesa per la sicurezza del sito. Un’analisi regolare permette di identificare attacchi in corso o tentativi di intrusione prima che producano danni. L’OWASP Top 10 2025 classifica le carenze nel logging e nel monitoraggio tra le vulnerabilità più critiche delle applicazioni web (A09).
Tentativi di brute force
Pattern da cercare nei log: multiple richieste POST a /wp-login.php, /xmlrpc.php, /wp-admin/ dallo stesso IP in rapida successione, con status code 401 o 403:
203.0.113.50 - - [20/Feb/2025:10:23:01 +0100] "POST /wp-login.php HTTP/1.1" 401 4523
203.0.113.50 - - [20/Feb/2025:10:23:02 +0100] "POST /wp-login.php HTTP/1.1" 401 4523
203.0.113.50 - - [20/Feb/2025:10:23:03 +0100] "POST /wp-login.php HTTP/1.1" 401 4523
Per identificare rapidamente gli IP con più tentativi falliti:
grep "wp-login.php" /var/log/nginx/access.log | grep "POST" | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
Pattern di SQL injection e path traversal
Le richieste con tentativi di SQL injection contengono pattern riconoscibili nella request line:
- SQL injection:
UNION SELECT,OR 1=1,' OR ''=',%27(apice URL-encoded),%3B(punto e virgola) - Path traversal:
../../etc/passwd,/proc/self/environ - File sensibili: richieste a
/.env,/wp-config.php.bak,/backup.sql,/.git/config
# Cerca tentativi di SQL injection nei log
grep -iE "(union.*select|or\+1=1|%27|%3B)" /var/log/nginx/access.log
# Cerca tentativi di path traversal
grep -E "\.\./\.\." /var/log/nginx/access.log
# Cerca richieste a file sensibili
grep -iE "(\.env|wp-config\.php\.bak|backup\.sql|\.git)" /var/log/nginx/access.log
Bot malevoli e user-agent sospetti
User-Agent da monitorare nei log:
- Scanner di vulnerabilità:
sqlmap,nikto,nmap,masscan,ZmEu,DirBuster,Acunetix - User-Agent vuoti: spesso script automatizzati che non si identificano
- Googlebot fake: qualsiasi richiesta che dichiara di essere Googlebot ma proviene da un IP che non appartiene a Google. Verificabile con un reverse DNS lookup sull’IP.
- Bot AI/LLM aggressivi:
GPTBot,CCBot,ClaudeBot,Bytespider— il traffico di bot AI ha raggiunto il 37% del traffico bot totale nel 2025. Se non portano valore, è opportuno bloccarli via robots.txt.
Protezione automatica con fail2ban
fail2ban è un tool che legge i log del server in tempo reale e blocca automaticamente gli IP che mostrano pattern malevoli (brute force, scanning, DDoS). Analizza le righe di log, applica regex di matching e crea regole di firewall (iptables/nftables) per bannare temporaneamente gli IP offensivi. È il complemento naturale dell’analisi manuale dei log: quello che identifichi manualmente, fail2ban lo automatizza.
Log di CDN e servizi cloud
Quando un sito è dietro una CDN o un servizio cloud, i log del web server origin non contengono più tutto il traffico: le richieste servite dalla cache della CDN non raggiungono il server. Per avere il quadro completo è necessario accedere anche ai log della CDN.
Cloudflare
Cloudflare offre diverse opzioni di logging:
- Logpush — Export automatico dei log verso storage esterno (Amazon S3, Google Cloud Storage, Azure Blob, Cloudflare R2) o piattaforme SIEM.
- Log Explorer — Ricerca e analisi dei log direttamente nella dashboard Cloudflare (GA dal 2024).
- Instant Logs — Tailing in tempo reale dalla dashboard (piano Enterprise).
I log Cloudflare includono campi non disponibili nei log del server origin: country del client, ASN, stato della cache (HIT/MISS/BYPASS), azioni del WAF, bot score, versione TLS.
Nota: quando Cloudflare è attivo, l’IP nei log del server origin sarà quello del nodo Cloudflare, non del visitatore. Per recuperare l’IP reale, Cloudflare invia l’header CF-Connecting-IP. In Nginx, configurare il modulo ngx_http_realip_module con set_real_ip_from per gli IP range di Cloudflare.
AWS CloudWatch Logs
AWS CloudWatch Logs è il servizio di log management di Amazon Web Services. Raccoglie log da EC2, Lambda, ECS, ALB, CloudFront e altri servizi AWS. Offre CloudWatch Logs Insights per query interattive (supporta SQL e PPL), anomaly detection automatica, metric filter per estrarre metriche dai log, e Live Tail per il monitoring real-time. La retention è configurabile da 1 giorno a 10 anni.
Google Cloud Logging
Google Cloud Logging fornisce gestione real-time dei log per Google Cloud Platform. Include Logs Explorer per la ricerca e il filtraggio, Log Analytics per query SQL sui log, log-based metrics per creare alert basati sul contenuto dei log, e integrazione nativa con Cloud Monitoring, Error Reporting e Cloud Trace.
Privacy e GDPR
Il GDPR classifica esplicitamente gli indirizzi IP come dati personali. La Corte di Giustizia Europea lo ha confermato nel caso Breyer (C-582/14). Questo significa che gli access log contenenti IP completi sono soggetti alla normativa sulla protezione dei dati.
Anonimizzazione degli IP nei log
Le autorità garanti europee (CNIL, Garante italiano, DPA austriaca) hanno chiarito nel 2025 che la troncatura dell’ultimo ottetto dell’IP è pseudonimizzazione, non anonimizzazione completa. Il dato pseudonimizzato resta dato personale ai sensi del GDPR. Tuttavia, è una misura di mitigazione accettata dalla maggior parte dei DPA come best practice.
Configurazione per anonimizzare gli IP in Nginx:
# Anonimizzazione: azzera l'ultimo ottetto IPv4 e l'ultima parte IPv6
map $remote_addr $anonymized_addr {
~(?P<ip>\d+\.\d+\.\d+)\.\d+ $ip.0;
~(?P<ip>[^:]+:[^:]+): $ip::;
default 0.0.0.0;
}
log_format anonymized '$anonymized_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log anonymized;
Retention policy
Linee guida pratiche per la retention dei log in conformità al principio di minimizzazione (Art. 5(1)(c) GDPR):
- Log operativi (access log): 30-90 giorni sono generalmente considerati ragionevoli per il troubleshooting.
- Log di sicurezza (error log, WAF, fail2ban): periodi più lunghi (6-12 mesi) sono giustificabili per l’interesse legittimo alla sicurezza.
- Log SEO/analytics: definire una base giuridica chiara (interesse legittimo) e documentarla.
- Automatizzare la cancellazione: usare logrotate con retention definita, non affidarsi alla cancellazione manuale.
Le sanzioni GDPR hanno raggiunto 5,65 miliardi di EUR cumulativi entro marzo 2025, con una media di 2,36 milioni EUR per sanzione. La gestione corretta dei log è una delle aree in cui molte organizzazioni risultano inadempienti.
Video
Fonti e riferimenti
- Apache HTTP Server 2.4 — Log Files (documentazione ufficiale)
- Apache mod_log_config (direttive di configurazione log)
- Nginx ngx_http_log_module (documentazione ufficiale)
- Nginx Admin Guide — Configuring Logging
- RFC 9110 — HTTP Semantics (specifica HTTP corrente, sostituisce RFC 2616)
- IANA HTTP Status Code Registry
- GoAccess — Visual Web Log Analyzer
- Elastic Stack (ELK)
- Grafana Loki Documentation
- OWASP Top 10 2025 — A09 Security Logging and Monitoring Failures
- Cloudflare Logs Documentation
- AWS CloudWatch Logs
Articoli correlati
Autore
Mi chiamo Giovanni Sacheli e dal 2009 aiuto le aziende a farsi trovare online. Sono specializzato in SEO tecnica e PPC, competenze che applico quotidianamente nella mia agenzia, Searcus Swiss Sagl. Mi piace sviluppare strumenti a supporto del mio lavoro, ho creato SEOdata.app e cluster.army e co-scritto il libro SEO Audit Avanzato. Curo maniacalmente questo blog per colleghi e appassionati, dove mi "appunto" quello che imparo. Sono un NERD anni '80, motociclista e orgoglioso papà di due bambini.
Link:
Giovanni Sacheli
SEO Audit Avanzato
Searcus Swiss Sagl
SEOdata.app
cluster.army
Commenti |2
Lascia un commentoApprofitto dei commenti per complimentarmi per il libro SEO Audit Avanzato che ho ricevuto giusto oggi. Comincerò a leggerlo proprio dal capitolo dedicato all’analisi del log del server :-)
Grazie Max, buona lettura :)