Il tuo cliente ti chiama alle 8 di mattina: “Il sito è giù da tre ore.” Tu non lo sapevi. Nessun alert, nessun log, nessuna notifica. Tre ore di downtime, vendite perse, e la fiducia del cliente che crolla. Se gestisci più di 5 siti WordPress, il monitoraggio non è un optional — è la differenza tra un’agenzia professionale e una che reagisce solo quando il danno è fatto.
In questa guida vediamo come costruire un sistema di monitoraggio WordPress completo: uptime, performance, sicurezza e alert automatici. Tutto quello che abbiamo imparato gestendo decine di siti WordPress per agenzie e PA con AgencyPilot.
TL;DR — Cosa Serve per Monitorare WordPress nel 2026
Un sistema di monitoraggio efficace per agenzie WordPress copre quattro aree: uptime monitoring (il sito risponde?), performance monitoring (quanto velocemente?), security monitoring (qualcuno sta attaccando?) e alert automatici (chi viene avvisato e come?). Servono check ogni 60 secondi, soglie personalizzabili, e notifiche che arrivano prima della telefonata del cliente. Il costo? Da zero con soluzioni open source a 20-50€/mese per tool SaaS dedicati. La soluzione migliore dipende da quanti siti gestisci e quanto vuoi automatizzare.
| Area | Cosa monitorare | Frequenza minima | Tool consigliati |
|---|---|---|---|
| Uptime | HTTP status, SSL, DNS | 60 secondi | UptimeRobot, Uptime Kuma, AgencyPilot |
| Performance | TTFB, LCP, CLS, FID | Giornaliera + on-demand | PageSpeed API, WebPageTest, Lighthouse CI |
| Sicurezza | Malware, file changes, login brute-force | Oraria | WPScan, Wordfence, AgencyPilot Security Scanner |
| Alert | Notifiche multi-canale | Real-time | Slack, Telegram, email, webhook |
Perché il Monitoraggio WordPress È Diverso da Quello Generico
WordPress non è un’applicazione statica. È un ecosistema dinamico dove plugin, temi, aggiornamenti core e cron job possono rompere tutto in qualsiasi momento. Un ping HTTP che restituisce 200 OK non significa che il sito funzioni — potrebbe mostrare una pagina bianca di errore PHP con status 200, o un tema rotto che carica comunque.
Nella nostra esperienza con oltre 40 siti WordPress gestiti simultaneamente, il 73% dei problemi che abbiamo intercettato non erano downtime puri. Erano:
- Degradazione lenta delle performance — il TTFB che passa da 400ms a 2.8 secondi dopo un aggiornamento plugin
- Certificati SSL in scadenza — Let’s Encrypt che fallisce il rinnovo silenziosamente
- Database bloat — tabelle wp_options che crescono da 2MB a 180MB per transient non puliti
- Cron WordPress bloccati — wp-cron.php che smette di funzionare e blocca pubblicazioni schedulate
- Errori PHP silenti — fatal error loggati ma non visibili, che rompono funzionalità specifiche
Per questo serve un monitoraggio specifico per WordPress, non un generico “il server risponde”. Serve qualcosa che capisca la struttura di WordPress e sappia dove guardare. Lo abbiamo documentato anche nella nostra guida alla gestione siti WordPress per agenzie.
Uptime Monitoring: Oltre il Semplice Ping
Il monitoraggio uptime base è semplice: mandi una richiesta HTTP e verifichi che torni un 200. Ma per WordPress serve di più. Ecco la configurazione che usiamo nei nostri progetti.
Check HTTP Avanzati
Non basta verificare lo status code. Serve controllare che il contenuto della pagina sia quello atteso. Ecco uno script bash che fa un health check completo:
#!/bin/bash
# wordpress-health-check.sh
# Check avanzato per siti WordPress
SITE_URL="$1"
EXPECTED_STRING="$2" # es. il nome del sito o un elemento footer
TIMEOUT=10
MAX_TTFB=2000 # millisecondi
# Check HTTP status + TTFB
RESPONSE=$(curl -s -o /tmp/wp-check-body.html -w "%{http_code}|%{time_starttransfer}" \
--max-time $TIMEOUT "$SITE_URL")
HTTP_CODE=$(echo "$RESPONSE" | cut -d'|' -f1)
TTFB=$(echo "$RESPONSE" | cut -d'|' -f2 | awk '{printf "%.0f", $1 * 1000}')
# Check status code
if [ "$HTTP_CODE" != "200" ]; then
echo "CRITICAL: HTTP $HTTP_CODE per $SITE_URL"
exit 2
fi
# Check TTFB
if [ "$TTFB" -gt "$MAX_TTFB" ]; then
echo "WARNING: TTFB ${TTFB}ms (soglia: ${MAX_TTFB}ms) per $SITE_URL"
exit 1
fi
# Check contenuto (evita false 200 con pagine errore)
if [ -n "$EXPECTED_STRING" ]; then
if ! grep -q "$EXPECTED_STRING" /tmp/wp-check-body.html; then
echo "CRITICAL: Contenuto atteso non trovato in $SITE_URL"
exit 2
fi
fi
# Check certificato SSL (scadenza)
SSL_EXPIRY=$(echo | openssl s_client -servername "$(echo $SITE_URL | sed 's|https://||;s|/.*||')" \
-connect "$(echo $SITE_URL | sed 's|https://||;s|/.*||')":443 2>/dev/null | \
openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -n "$SSL_EXPIRY" ]; then
DAYS_LEFT=$(( ($(date -d "$SSL_EXPIRY" +%s) - $(date +%s)) / 86400 ))
if [ "$DAYS_LEFT" -lt 7 ]; then
echo "WARNING: SSL scade tra $DAYS_LEFT giorni per $SITE_URL"
exit 1
fi
fi
echo "OK: HTTP $HTTP_CODE, TTFB ${TTFB}ms, SSL OK ($DAYS_LEFT giorni)"
exit 0
Monitorare il REST API di WordPress
Un check spesso trascurato: il REST API di WordPress. Se l’API non risponde, app mobile, integrazioni e headless frontend smettono di funzionare. Aggiungi sempre un check su /wp-json/wp/v2/posts?per_page=1 — se restituisce JSON valido, il backend PHP + database funzionano.
# Check REST API WordPress
REST_CHECK=$(curl -s --max-time 5 "${SITE_URL}/wp-json/wp/v2/posts?per_page=1" \
-H "Accept: application/json")
if echo "$REST_CHECK" | python3 -c "import sys,json; json.load(sys.stdin)" 2>/dev/null; then
echo "REST API: OK"
else
echo "REST API: ERRORE - risposta non JSON valida"
fi
Tool per Uptime Monitoring
Confronto rapido dei tool che abbiamo testato in produzione:
| Tool | Prezzo | Check minimo | Siti inclusi | Pro | Contro |
|---|---|---|---|---|---|
| UptimeRobot Free | Gratis | 5 min | 50 | Facile, affidabile | Intervallo troppo lungo |
| UptimeRobot Pro | $7/mese | 60 sec | 50 | Intervallo ok, status page | No check contenuto |
| Uptime Kuma | Gratis (self-hosted) | 20 sec | Illimitati | Open source, personalizzabile | Serve un server dedicato |
| AgencyPilot | Da 19€/mese | 60 sec | In base al piano | Integrato con gestione WP | Specifico per WordPress |
| Hetrix Tools | Gratis (base) | 60 sec | 15 | Monitoring multi-location | UI datata |
La nostra raccomandazione: per agenzie con meno di 10 siti, Uptime Kuma su un VPS da 3€/mese è imbattibile. Per agenzie più grandi che vogliono tutto integrato — monitoring, aggiornamenti, security — AgencyPilot centralizza tutto in un’unica dashboard.
Performance Monitoring: Intercettare la Degradazione Prima che Diventi un Problema
Il downtime è ovvio. La degradazione delle performance no. Un sito che passa da 1.2 a 3.5 secondi di caricamento perde il 40% dei visitatori secondo i dati di Google sui Core Web Vitals, ma nessuno ti chiama per dirti “il sito è lento”. Lo scopri quando il traffico organico crolla.
Metriche da Tracciare
Queste sono le metriche che monitoriamo su ogni sito WordPress gestito:
- TTFB (Time to First Byte) — soglia: sotto 800ms. Ideale: sotto 400ms. Misura la velocità del server PHP + database.
- LCP (Largest Contentful Paint) — soglia: sotto 2.5 secondi. L’elemento più grande nel viewport.
- CLS (Cumulative Layout Shift) — soglia: sotto 0.1. Stabilità visiva della pagina.
- INP (Interaction to Next Paint) — soglia: sotto 200ms. Ha sostituito FID nel 2024.
Automatizzare i Test con PageSpeed Insights API
Google offre un’API gratuita per PageSpeed Insights. Ecco come automatizzare i check giornalieri con un semplice script Python:
import requests
import json
from datetime import datetime
PAGESPEED_API = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed"
API_KEY = "YOUR_API_KEY" # opzionale, aumenta i limiti
def check_performance(url, strategy="mobile"):
"""Esegue un test PageSpeed e restituisce le metriche chiave."""
params = {
"url": url,
"strategy": strategy,
"category": ["performance", "accessibility"],
}
if API_KEY:
params["key"] = API_KEY
response = requests.get(PAGESPEED_API, params=params)
data = response.json()
metrics = data["lighthouseResult"]["audits"]
return {
"url": url,
"timestamp": datetime.now().isoformat(),
"strategy": strategy,
"performance_score": data["lighthouseResult"]["categories"]["performance"]["score"] * 100,
"ttfb_ms": metrics["server-response-time"]["numericValue"],
"lcp_ms": metrics["largest-contentful-paint"]["numericValue"],
"cls": metrics["cumulative-layout-shift"]["numericValue"],
"tbt_ms": metrics["total-blocking-time"]["numericValue"], # proxy per INP in lab
}
# Esempio: monitora più siti
sites = [
"https://cliente1.it",
"https://cliente2.it",
"https://cliente3.it",
]
for site in sites:
result = check_performance(site)
if result["performance_score"] < 70:
print(f"⚠️ ALERT: {site} — Performance score: {result['performance_score']}")
if result["ttfb_ms"] > 800:
print(f"⚠️ ALERT: {site} — TTFB: {result['ttfb_ms']}ms")
print(json.dumps(result, indent=2))
Noi eseguiamo questo check ogni notte alle 3:00 via cron job. I risultati vengono salvati in un database PostgreSQL e visualizzati nella dashboard di AgencyPilot con grafici di trend. Quando un sito scende sotto la soglia, parte un alert automatico.
Per chi vuole approfondire l’ottimizzazione delle performance, abbiamo scritto una guida completa ai Core Web Vitals per agenzie WordPress.
Security Monitoring: Rilevare le Minacce in Tempo Reale
WordPress è il CMS più attaccato al mondo. Non perché sia insicuro — perché è il più diffuso (43% del web secondo W3Techs). Un sistema di monitoraggio serio deve includere la sicurezza. Abbiamo trattato l’argomento in dettaglio nella nostra guida alla sicurezza WordPress per agenzie, ma qui ci concentriamo sugli aspetti di monitoraggio.
Cosa Monitorare per la Sicurezza
- Tentativi di login brute-force — più di 10 tentativi falliti in 5 minuti = alert
- Modifiche ai file core — se wp-includes o wp-admin cambiano senza aggiornamento, qualcosa non va
- Nuovi utenti admin — un classico segnale di compromissione
- Plugin con vulnerabilità note — check giornaliero contro il database WPScan
- Modifiche al database — nuove righe in wp_users o wp_options sospette
Script di File Integrity Monitoring
Questo script confronta i checksum dei file core di WordPress con quelli ufficiali:
#!/bin/bash
# wp-integrity-check.sh
# Verifica integrità file core WordPress
WP_PATH="$1"
ALERT_EMAIL="admin@agenzia.it"
if [ -z "$WP_PATH" ] || [ ! -f "$WP_PATH/wp-includes/version.php" ]; then
echo "Uso: $0 /percorso/wordpress"
exit 1
fi
# Ottieni versione WordPress
WP_VERSION=$(grep "wp_version = " "$WP_PATH/wp-includes/version.php" | cut -d"'" -f2)
# Scarica checksum ufficiali
CHECKSUMS=$(curl -s "https://api.wordpress.org/core/checksums/1.0/?version=${WP_VERSION}&locale=en_US")
# Verifica con wp-cli se disponibile
if command -v wp &>/dev/null; then
VERIFY=$(wp core verify-checksums --path="$WP_PATH" 2>&1)
if [ $? -ne 0 ]; then
echo "CRITICAL: File core modificati in $WP_PATH"
echo "$VERIFY"
echo "$VERIFY" | mail -s "ALERT: WordPress core modificato - $WP_PATH" "$ALERT_EMAIL"
exit 2
fi
fi
# Check permessi file critici
WRITABLE_CONFIGS=$(find "$WP_PATH" -name "wp-config.php" -perm -o+w 2>/dev/null)
if [ -n "$WRITABLE_CONFIGS" ]; then
echo "WARNING: wp-config.php è scrivibile da tutti"
exit 1
fi
# Check file PHP sospetti nella cartella uploads
SUSPICIOUS=$(find "$WP_PATH/wp-content/uploads" -name "*.php" -type f 2>/dev/null)
if [ -n "$SUSPICIOUS" ]; then
echo "CRITICAL: File PHP trovati in uploads/"
echo "$SUSPICIOUS"
exit 2
fi
echo "OK: WordPress $WP_VERSION — integrità verificata"
exit 0
Monitorare Vulnerabilità Plugin con WPScan API
WPScan mantiene il database più completo di vulnerabilità WordPress. Con la loro API (gratuita fino a 25 richieste/giorno), puoi automatizzare il check:
import requests
import subprocess
import json
WPSCAN_API_TOKEN = "YOUR_TOKEN"
WPSCAN_API = "https://wpscan.com/api/v3"
def get_installed_plugins(wp_path):
"""Ottiene la lista plugin installati via WP-CLI."""
result = subprocess.run(
["wp", "plugin", "list", "--format=json", f"--path={wp_path}"],
capture_output=True, text=True
)
return json.loads(result.stdout)
def check_vulnerabilities(plugin_slug, version):
"""Controlla vulnerabilità note per un plugin specifico."""
headers = {"Authorization": f"Token token={WPSCAN_API_TOKEN}"}
resp = requests.get(f"{WPSCAN_API}/plugins/{plugin_slug}", headers=headers)
if resp.status_code != 200:
return []
data = resp.json()
vulns = []
for vuln in data.get(plugin_slug, {}).get("vulnerabilities", []):
fixed_in = vuln.get("fixed_in")
if fixed_in is None or version_compare(version, fixed_in) < 0:
vulns.append({
"title": vuln["title"],
"severity": vuln.get("cvss", {}).get("severity", "unknown"),
"fixed_in": fixed_in or "non ancora fixata",
})
return vulns
Alert Automatici: Il Sistema Nervoso del Monitoraggio
Monitorare senza notificare è inutile. Ma notificare troppo è peggio — l'alert fatigue è reale. Dopo anni di fine-tuning, abbiamo stabilito queste regole per i nostri alert.
Livelli di Severità e Canali
| Livello | Esempio | Canale | Tempo risposta |
|---|---|---|---|
| 🔴 CRITICAL | Sito down, malware rilevato | Telegram + SMS + email | Immediato |
| 🟠 WARNING | TTFB alto, SSL in scadenza | Telegram + email | Entro 4 ore |
| 🟡 INFO | Aggiornamento disponibile, performance calata | Email + dashboard | Entro 24 ore |
| ⚪ DEBUG | Log errori PHP, query lente | Solo dashboard | Review settimanale |
Implementare Alert via Telegram Bot
Telegram è il canale più efficace per alert urgenti. Ecco come configurare un bot di notifica:
import requests
from datetime import datetime
TELEGRAM_BOT_TOKEN = "YOUR_BOT_TOKEN"
TELEGRAM_CHAT_ID = "YOUR_CHAT_ID" # gruppo o chat privata
def send_alert(level, site, message):
"""Invia alert su Telegram con formattazione."""
emoji = {"critical": "🔴", "warning": "🟠", "info": "🟡"}.get(level, "⚪")
timestamp = datetime.now().strftime("%H:%M:%S")
text = (
f"{emoji} *{level.upper()}* — {timestamp}\n"
f"🌐 `{site}`\n\n"
f"{message}\n\n"
f"#monitoring #{level}"
)
requests.post(
f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage",
json={
"chat_id": TELEGRAM_CHAT_ID,
"text": text,
"parse_mode": "Markdown",
"disable_web_page_preview": True,
}
)
# Esempio di utilizzo
send_alert("critical", "cliente1.it", "Sito non raggiungibile da 3 check consecutivi.\nHTTP Status: Connection Timeout\nUltimo OK: 14:32:10")
Anti-Flapping: Evitare Alert Ripetuti
Un errore comune: mandare un alert ogni volta che il check fallisce. Se il sito è giù per 30 minuti e fai check ogni minuto, sono 30 notifiche. La soluzione è implementare un sistema di anti-flapping:
import time
from collections import defaultdict
class AlertManager:
def __init__(self, cooldown_seconds=300, confirm_failures=3):
self.cooldown = cooldown_seconds
self.confirm = confirm_failures
self.failure_count = defaultdict(int)
self.last_alert = defaultdict(float)
self.in_alert = defaultdict(bool)
def process_check(self, site, is_ok, message=""):
if is_ok:
if self.in_alert[site]:
self.in_alert[site] = False
self.failure_count[site] = 0
send_alert("info", site, "✅ Sito tornato online")
self.failure_count[site] = 0
return
self.failure_count[site] += 1
# Conferma il problema con N check consecutivi
if self.failure_count[site] < self.confirm:
return
# Cooldown: non mandare alert troppo frequenti
now = time.time()
if now - self.last_alert[site] < self.cooldown:
return
self.in_alert[site] = True
self.last_alert[site] = now
send_alert("critical", site, message)
Con 3 check consecutivi falliti e un cooldown di 5 minuti, elimini i falsi positivi e l'alert fatigue. È lo stesso approccio che abbiamo implementato in AgencyPilot.
Dashboard Centralizzata: Vedere Tutto in un Colpo d'Occhio
Quando gestisci 20, 30 o 50 siti, non puoi aprire 50 tab per controllare lo stato. Serve una dashboard centralizzata. Le opzioni principali:
Uptime Kuma (Open Source)
La nostra scelta per chi vuole il controllo totale. Si installa in 5 minuti con Docker:
# docker-compose.yml per Uptime Kuma
version: "3"
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
volumes:
- ./data:/app/data
ports:
- "3001:3001"
restart: unless-stopped
Dopo il deploy, configuri i monitor per ogni sito. Uptime Kuma supporta HTTP(S), TCP, ping, DNS, e anche check personalizzati con keyword matching. La status page pubblica è inclusa — utilissima per mostrare ai clienti lo stato dei loro siti.
Grafana + Prometheus (Per Chi Vuole Tutto)
Se vuoi metriche avanzate e grafici storici, Grafana con Prometheus e il WordPress exporter è la soluzione enterprise. Più complessa da configurare, ma la flessibilità è incomparabile. Serve quando hai bisogno di correlare metriche server (CPU, RAM, disco) con metriche applicative (query lente, cache hit rate).
AgencyPilot (Tutto Integrato)
Il motivo per cui abbiamo costruito AgencyPilot è proprio questo: avere monitoring, gestione aggiornamenti, security scan e report clienti in un unico posto. Se la gestione WordPress è il tuo core business, vale la pena valutare un tool dedicato piuttosto che assemblare 5 servizi diversi. Il tempo risparmiato nella configurazione e manutenzione di tool separati si ripaga in poche settimane.
Automazione Completa: Cron Job e Orchestrazione
Ogni check che abbiamo visto finora va automatizzato. Ecco la struttura cron che usiamo in produzione:
# /etc/cron.d/wordpress-monitoring
# Uptime check — ogni minuto
* * * * * monitor /opt/monitoring/uptime-check.sh /var/www/sites.txt
# Performance check — ogni 6 ore
0 */6 * * * monitor /opt/monitoring/performance-check.py --all-sites
# Security scan — ogni notte alle 2:00
0 2 * * * monitor /opt/monitoring/security-scan.sh /var/www/sites.txt
# SSL expiry check — ogni giorno alle 8:00
0 8 * * * monitor /opt/monitoring/ssl-check.sh /var/www/sites.txt
# Plugin vulnerability check — ogni giorno alle 6:00
0 6 * * * monitor /opt/monitoring/vuln-check.py --all-sites
# Report settimanale — lunedì alle 9:00
0 9 * * 1 monitor /opt/monitoring/weekly-report.py --send-email
Orchestrazione con Systemd
Per check più complessi che richiedono retry e logging strutturato, usiamo systemd timer invece di cron:
# /etc/systemd/system/wp-monitoring.service
[Unit]
Description=WordPress Monitoring Suite
After=network-online.target
[Service]
Type=oneshot
ExecStart=/opt/monitoring/run-all-checks.sh
StandardOutput=journal
StandardError=journal
User=monitor
Group=monitor
# /etc/systemd/system/wp-monitoring.timer
[Unit]
Description=WordPress Monitoring Timer
[Timer]
OnCalendar=*:0/5
Persistent=true
RandomizedDelaySec=30
[Install]
WantedBy=timers.target
Metriche che Contano: Cosa Tracciare nel Tempo
Non tutto va monitorato con la stessa urgenza. Dopo anni di raccolta dati, queste sono le metriche che correlano di più con problemi reali:
- Uptime mensile — obiettivo: 99.9% (massimo 43 minuti di downtime/mese)
- TTFB medio settimanale — trend in salita = problema imminente
- Tempo medio di risposta agli alert — quanto ci metti a reagire?
- Plugin con aggiornamenti pendenti da più di 7 giorni — rischio sicurezza crescente
- Dimensione database — crescita anomala indica problemi
Queste metriche vanno in un report settimanale che condividiamo con i clienti. Non il dettaglio tecnico — un sommario chiaro: "Il tuo sito è stato online il 99.97% del tempo, le performance sono stabili, nessuna vulnerabilità critica rilevata." I clienti vogliono sapere che qualcuno vigila. I report trasformano il monitoraggio da costo nascosto a valore percepito.
FAQ — Domande Frequenti sul Monitoraggio WordPress
Ogni quanto devo controllare l'uptime dei siti WordPress?
Per siti business-critical, ogni 60 secondi è lo standard. Per siti con meno traffico, ogni 5 minuti è accettabile. La differenza è nel tempo di rilevamento: con check ogni 5 minuti, potresti scoprire un downtime con fino a 5 minuti di ritardo. Con check ogni minuto, il ritardo massimo è di 60 secondi più il tempo di conferma (di solito 2-3 check consecutivi).
Posso usare un tool gratuito per monitorare i miei siti WordPress?
Sì. Uptime Kuma è open source e gratuito — serve solo un piccolo VPS (anche da 3€/mese). UptimeRobot offre un piano gratuito con 50 monitor e check ogni 5 minuti. Per agenzie con meno di 10 siti, queste soluzioni gratuite sono più che sufficienti. Oltre i 10 siti, un tool integrato come AgencyPilot semplifica enormemente la gestione.
Come evito i falsi positivi nel monitoraggio uptime?
Tre strategie: (1) conferma il downtime con almeno 3 check consecutivi falliti prima di inviare un alert, (2) usa check da multiple location geografiche — un singolo nodo potrebbe avere problemi di rete, (3) implementa content matching oltre al semplice status code HTTP, così rilevi anche pagine di errore che restituiscono 200 OK.
Il monitoraggio rallenta il mio sito WordPress?
No, se fatto correttamente. Un check HTTP ogni 60 secondi è una singola richiesta — trascurabile rispetto al traffico reale. Evita di fare check su pagine non cachate o che eseguono query pesanti. La homepage o una pagina statica dedicata (/health-check) è la scelta migliore.
Come presento i dati di monitoraggio ai miei clienti?
I clienti non vogliono grafici tecnici. Vogliono tre informazioni: il sito funziona? È veloce? È sicuro? Un report mensile con uptime percentuale, performance score medio, e numero di vulnerabilità risolte è tutto ciò che serve. AgencyPilot genera questi report automaticamente con il branding della tua agenzia.