WordPress Activity Log per Agenzie: Monitorare Cambiamenti sui Siti Clienti [2026]

5 settembre 202613 minGuide

Gestire 50+ siti WordPress per clienti significa affrontare ogni giorno la stessa domanda: chi ha cambiato cosa, e quando? Un activity log WordPress strutturato non è un optional per le agenzie — è la differenza tra un’indagine di 5 minuti e un’ora di panico telefonico con il cliente. In questa guida spieghiamo come implementare un sistema di audit trail completo, confrontiamo i plugin migliori del 2026 e mostriamo configurazioni di codice reale che usiamo in AgencyPilot.

Cos’è un WordPress Activity Log e Perché Serve per le Agenzie

Un activity log WordPress registra ogni azione che avviene all’interno di un sito: pubblicazione di post, modifica di plugin, cambi di ruolo utente, tentativi di login, aggiornamenti del core. Per un’agenzia web che gestisce decine di siti clienti, questo registro è essenziale per tre motivi concreti:

  1. Accountability: sai esattamente quale membro del team ha disattivato un plugin o modificato una pagina
  2. Sicurezza: rilevi comportamenti anomali prima che diventino incidenti
  3. Compliance GDPR: l’articolo 30 del GDPR richiede un registro delle attività di trattamento — un audit log tecnico ne è la base

Nella nostra esperienza gestendo siti WordPress per clienti italiani, il 90% dei problemi “misteriosi” (pagina bianca, widget spostato, impostazione cambiata) si risolve in meno di 5 minuti quando hai un activity log attivo. Senza, sei costretto a scavare nei log del server o peggio a indovinare.

Se gestisci più siti WordPress, un sistema di activity log è complementare a quanto descriviamo nella nostra guida completa alla gestione multi-sito WordPress per agenzie.

I 5 Plugin WordPress Activity Log a Confronto nel 2026

Abbiamo testato i principali plugin di activity logging su 30 siti di clienti AgencyPilot per 6 mesi. Ecco il confronto reale:

Plugin Eventi Tracciati (Free) Notifiche Export Multi-sito Prezzo Premium
WP Activity Log (Melapress) Illimitati Email + SMS CSV, JSON, XML Sì (Network) €89/anno
WP Security Audit Log Limitati (free) Email Premium Premium €99/anno
Simple History Base (~30) No CSV No Gratuito
Activity Log (BestWebSoft) Base No (Premium) Premium Premium €45/anno
Stream (XWP) Illimitati No CSV Sì Gratuito

Il Nostro Setup Consigliato per Agenzie

Per le agenzie che gestiscono più di 10 siti, raccomandiamo WP Activity Log di Melapress per i seguenti motivi:

  • Registra ogni azione senza limiti nella versione gratuita — fondamentale per audit completi
  • Supporto nativo per WordPress Multisite e network dashboard
  • Integrazione con SIEM esterni via webhook (premium)
  • Notifiche real-time via email e Slack (premium)
  • Export in CSV per audit GDPR e reporting clienti

Per agenzie con budget ridotto, Stream è l’alternativa gratuita più solida, anche se manca di notifiche e ha un’interfaccia meno curata. Approfondiamo il confronto nella nostra guida agli strumenti di gestione WordPress per agenzie.

Come Configurare un Activity Log su WordPress: Guida Step-by-Step

Step 1 — Installazione Plugin

Dopo aver scelto il plugin (usiamo WP Activity Log come esempio), l’installazione è standard:

# Installazione via WP-CLI
wp plugin install wp-security-audit-log --activate

# Verifica che il plugin sia attivo
wp plugin list --status=active | grep audit

Per installazioni multi-sito, attiva a livello di network:

wp plugin install wp-security-audit-log --activate-network

Step 2 — Configurazione degli Eventi da Tracciare

Non tutti gli eventi hanno lo stesso valore per un’agenzia. Nella nostra configurazione standard di AgencyPilot, abilitiamo il tracking per queste categorie:

  • Contenuti: creazione, modifica, eliminazione di post e pagine
  • Plugin e Temi: installazione, attivazione, disattivazione, aggiornamento
  • Utenti: login, logout, tentativi falliti, cambi di ruolo, creazione/eliminazione utenti
  • Impostazioni: modifiche a permalink, general settings, reading settings
  • Media: upload, modifica, eliminazione file
  • Menu e Widget: modifiche alla struttura di navigazione

Disattiviamo invece il tracking dei singoli caricamenti media per siti con alto traffico — il log diventerebbe illeggibile.

Step 3 — Configurazione Notifiche Real-Time

Per le agenzie, le notifiche sono ciò che trasforma un log passivo in uno strumento proattivo. La configurazione ideale:

// functions.php — Notifiche custom via webhook Slack
add_action('admin_action_update', function() {
    $user = wp_get_current_user();
    $site = get_site_url();
    $message = sprintf(
        '🔔 *Activity su %s*: %s ha modificato impostazioni',
        $site,
        $user->display_name
    );
    
    wp_remote_post('https://hooks.slack.com/services/YOUR/WEBHOOK/URL', [
        'body' => json_encode(['text' => $message]),
        'headers' => ['Content-Type' => 'application/json'],
        'timeout' => 5,
    ]);
}, 10, 0);

Questo snippet invia una notifica a Slack ogni volta che qualcuno modifica le impostazioni del sito — l’evento più pericoloso e meno visibile. Approfondiamo le notifiche automatiche nella nostra guida all’automazione della gestione WordPress.

WordPress Activity Log Custom: Implementazione Senza Plugin

Per agenzie che preferiscono un controllo totale o che vogliono evitare plugin aggiuntivi, è possibile costruire un activity log custom usando gli hook di WordPress. Ecco un’implementazione che registri ogni modifica di contenuto in una tabella personalizzata:

Creazione della Tabella di Log

// functions.php — Creazione tabella activity log personalizzata
function agencypilot_create_activity_log_table() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'activity_log';
    $charset_collate = $wpdb->get_charset_collate();
    
    $sql = "CREATE TABLE $table_name (
        id bigint(20) NOT NULL AUTO_INCREMENT,
        user_id bigint(20) NOT NULL,
        user_email varchar(100) NOT NULL,
        action_type varchar(50) NOT NULL,
        object_type varchar(50) NOT NULL,
        object_id bigint(20) DEFAULT NULL,
        object_title varchar(255) DEFAULT NULL,
        action_description text NOT NULL,
        site_id bigint(20) DEFAULT 1,
        ip_address varchar(45) DEFAULT NULL,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY user_id (user_id),
        KEY action_type (action_type),
        KEY created_at (created_at)
    ) $charset_collate;";
    
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}
register_activation_hook(__FILE__, 'agencypilot_create_activity_log_table');

Registrazione degli Eventi

// functions.php — Hook per registrare modifiche a post e pagine
function agencypilot_log_post_change($post_id, $post, $update) {
    // Ignora autosave e revisioni
    if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) {
        return;
    }
    
    // Ignora post types non rilevanti
    if (!in_array($post->post_type, ['post', 'page', 'product'])) {
        return;
    }
    
    global $wpdb;
    $user = wp_get_current_user();
    
    $action = $update ? 'modificato' : 'creato';
    
    $wpdb->insert(
        $wpdb->prefix . 'activity_log',
        [
            'user_id' => $user->ID,
            'user_email' => $user->user_email,
            'action_type' => $update ? 'content_update' : 'content_create',
            'object_type' => $post->post_type,
            'object_id' => $post_id,
            'object_title' => $post->post_title,
            'action_description' => sprintf(
                '%s ha %s %s: "%s"',
                $user->display_name,
                $action,
                $post->post_type,
                $post->post_title
            ),
            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? null,
        ]
    );
}
add_action('save_post', 'agencypilot_log_post_change', 10, 3);

// Hook per registrare cambi di ruolo utente
function agencypilot_log_role_change($user_id, $role, $old_roles) {
    global $wpdb;
    $user = get_userdata($user_id);
    
    $wpdb->insert(
        $wpdb->prefix . 'activity_log',
        [
            'user_id' => $user_id,
            'user_email' => $user->user_email,
            'action_type' => 'role_change',
            'object_type' => 'user',
            'object_id' => $user_id,
            'object_title' => $user->display_name,
            'action_description' => sprintf(
                'Ruolo cambiato da %s a %s per l\'utente %s',
                implode(', ', $old_roles),
                $role,
                $user->display_name
            ),
            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? null,
        ]
    );
}
add_action('set_user_role', 'agencypilot_log_role_change', 10, 3);

// Hook per registrazione login falliti
function agencypilot_log_failed_login($username) {
    global $wpdb;
    
    $wpdb->insert(
        $wpdb->prefix . 'activity_log',
        [
            'user_id' => 0,
            'user_email' => $username,
            'action_type' => 'login_failed',
            'object_type' => 'authentication',
            'action_description' => sprintf(
                'Tentativo di login fallito per: %s',
                $username
            ),
            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? null,
        ]
    );
}
add_action('wp_login_failed', 'agencypilot_log_failed_login');

Query e Visualizzazione del Log

// functions.php — Endpoint REST API per consultare il log
add_action('rest_api_init', function() {
    register_rest_route('agencypilot/v1', '/activity-log', [
        'methods' => 'GET',
        'permission_callback' => function() {
            return current_user_can('manage_options');
        },
        'callback' => function(WP_REST_Request $request) {
            global $wpdb;
            $table = $wpdb->prefix . 'activity_log';
            
            $limit = min((int)$request->get_param('per_page'), 100);
            $offset = ((int)$request->get_param('page') - 1) * $limit;
            
            $results = $wpdb->get_results($wpdb->prepare(
                "SELECT * FROM $table ORDER BY created_at DESC LIMIT %d OFFSET %d",
                $limit,
                $offset
            ));
            
            return rest_ensure_response($results);
        },
    ]);
});

Questo endpoint REST API è utile per integrare i log di activity con dashboard esterne — esattamente come facciamo noi in AgencyPilot. Maggiori dettagli sulla REST API di WordPress nella nostra guida completa agli endpoint personalizzati REST API.

Activity Log e Sicurezza: Rilevare Minacce in Tempo Reale

Un activity log non serve solo a sapere “chi ha rotto cosa” — è il primo sistema di allarme per attacchi in corso. Ecco i pattern che monitoriamo attivamente sui siti dei nostri clienti:

Pattern di Allarme

Pattern Cosa Indica Severità
5+ login falliti in 5 minuti Brute force in corso 🔴 Alta
Creazione utente Admin fuori orario Possibile escalation di privilegi 🔴 Alta
Disattivazione plugin di sicurezza Preparazione ad attacco 🔴 Alta
Modifica file tema via editor Possibile injection di codice 🟡 Media
Cambio permalink struttura Impatto SEO, possibile errore 🟡 Media
Modifica impostazioni generali Verifica necessaria 🟢 Bassa

Implementazione Alert Automatici

// functions.php — Alert automatico per eventi critici
function agencypilot_critical_activity_alert($entry_id) {
    global $wpdb;
    $table = $wpdb->prefix . 'activity_log';
    
    $entry = $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM $table WHERE id = %d",
        $entry_id
    ));
    
    if (!$entry) return;
    
    // Pattern critici
    $critical_actions = ['login_failed', 'role_change', 'plugin_deactivate'];
    
    // Conta login falliti negli ultimi 5 minuti
    if ($entry->action_type === 'login_failed') {
        $failed_count = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM $table 
            WHERE action_type = 'login_failed' 
            AND ip_address = %s 
            AND created_at > DATE_SUB(NOW(), INTERVAL 5 MINUTE)",
            $entry->ip_address
        ));
        
        if ($failed_count >= 5) {
            agencypilot_send_alert(sprintf(
                '🚨 ALERT SICUREZZA: %d tentativi di login falliti da IP %s',
                $failed_count,
                $entry->ip_address
            ));
            
            // Blocca automaticamente l'IP
            agencypilot_block_ip($entry->ip_address);
        }
    }
    
    // Alert per cambi di ruolo o disattivazione plugin
    if (in_array($entry->action_type, ['role_change', 'plugin_deactivate'])) {
        agencypilot_send_alert(sprintf(
            '⚠️ Azione sensibile: %s',
            $entry->action_description
        ));
    }
}

function agencypilot_send_alert($message) {
    // Invia a Slack o email dell'agenzia
    wp_remote_post(get_option('agencypilot_alert_webhook'), [
        'body' => json_encode(['text' => $message]),
        'headers' => ['Content-Type' => 'application/json'],
        'timeout' => 5,
    ]);
    
    // Fallback email
    wp_mail(
        get_option('agencypilot_alert_email'),
        '[ALERT] Attività sensibile rilevata',
        $message
    );
}

Per un approccio completo alla sicurezza dei siti clienti, vedi la nostra guida alla sicurezza WordPress per agenzie.

Activity Log e GDPR: Cosa Devi Registrare

L’articolo 30 del GDPR richiede che i responsabili del trattamento mantengano un registro delle attività di trattamento. Per le agenzie web che gestiscono siti clienti, questo significa:

  1. Chi ha accesso ai dati personali (login, logout, accessi a dashboard)
  2. Cosa è stato modificato (cambi di contenuto, esportazioni dati, modifiche utenti)
  3. Quando è avvenuta l’azione (timestamp preciso)
  4. Dove (IP di origine, sito specifico in caso di multi-sito)

Un activity log WordPress ben configurato copre automaticamente i punti 1-3. Per il punto 4, è essenziale registrare l’IP di origine — il codice che abbiamo mostrato sopra lo fa già.

⚠️ Attenzione GDPR: I log contengono dati personali (email, IP, nome utente). Devi avere una policy di retention — raccomandiamo 90 giorni per i log di activity e 12 mesi per i log di sicurezza (login falliti). Configura una cancellazione automatica.
// Cron job per pulizia log oltre 90 giorni
add_action('agencypilot_cleanup_activity_log', function() {
    global $wpdb;
    $table = $wpdb->prefix . 'activity_log';
    
    // Elimina log di activity normali oltre 90 giorni
    $wpdb->query("DELETE FROM $table 
        WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY) 
        AND action_type NOT IN ('login_failed', 'role_change', 'plugin_deactivate')");
    
    // Elimina log di sicurezza oltre 12 mesi
    $wpdb->query("DELETE FROM $table 
        WHERE created_at < DATE_SUB(NOW(), INTERVAL 12 MONTH) 
        AND action_type IN ('login_failed', 'role_change', 'plugin_deactivate')");
});

// Schedule del cron
register_activation_hook(__FILE__, function() {
    if (!wp_next_scheduled('agencypilot_cleanup_activity_log')) {
        wp_schedule_event(time(), 'daily', 'agencypilot_cleanup_activity_log');
    }
});

Integrazione con Dashboard AgencyPilot

Nella nostra gestione di oltre 50 siti clienti, abbiamo integrato l'activity log direttamente nella dashboard di AgencyPilot. Questo ci permette di:

  • Visualizzare un feed unificato di tutti i cambiamenti su tutti i siti
  • Ricevere alert centralizzati quando qualcosa di critico accade su qualsiasi sito
  • Generare report mensili di attività per i clienti, inclusi nel nostro servizio di gestione e monitoring
  • Fornire al cliente un link diretto al log filtrato per il suo sito

L'integrazione sfrutta la REST API che abbiamo mostrato sopra, con un endpoint dedicato per ogni sito che invia i dati a un database centralizzato.

Ottimizzazione Performance dell'Activity Log

Un activity log su un sito ad alto traffico può generare migliaia di record al giorno. Ecco le ottimizzazioni che applichiamo in produzione:

  1. Indici database: la tabella personalizzata include indici su user_id, action_type e created_at per query veloci
  2. Rotazione log: cancellazione automatica oltre i 90 giorni per evitare tabelle enormi
  3. Scrittura asincrona: per siti ad alto traffico, usiamo wp_schedule_single_event per scrivere i log in background
  4. Object cache: i log recenti (ultimi 50 eventi) sono cachati in Redis con TTL di 5 minuti
  5. Batch insert: per siti con molte azioni, accumuliamo 50 eventi e li inseriamo in una singola query
// Scrittura asincrona via cron per siti ad alto traffico
function agencypilot_queue_activity_log($data) {
    $queue = get_transient('agencypilot_activity_queue') ?: [];
    $queue[] = $data;
    
    if (count($queue) >= 50) {
        agencypilot_flush_activity_queue($queue);
        $queue = [];
    }
    
    set_transient('agencypilot_activity_queue', $queue, 300);
}

function agencypilot_flush_activity_queue($queue) {
    global $wpdb;
    $table = $wpdb->prefix . 'activity_log';
    $values = [];
    $placeholders = [];
    
    foreach ($queue as $entry) {
        $values[] = $entry['user_id'];
        $values[] = $entry['user_email'];
        $values[] = $entry['action_type'];
        $values[] = $entry['object_type'];
        $values[] = $entry['action_description'];
        $values[] = $entry['ip_address'] ?? null;
        $placeholders[] = '(%d, %s, %s, %s, %s, %s)';
    }
    
    $sql = "INSERT INTO $table 
        (user_id, user_email, action_type, object_type, action_description, ip_address) 
        VALUES " . implode(', ', $placeholders);
    
    $wpdb->query($wpdb->prepare($sql, $values));
}

Per maggiori dettagli sull'ottimizzazione del database WordPress, consulta la nostra guida alle performance WordPress per agenzie.

FAQ — WordPress Activity Log per Agenzie

Quanto spazio occupa un activity log su WordPress?

Con una configurazione standard che traccia tutti gli eventi principali, un activity log occupa circa 2-5 MB per mese su un sito con 5-10 editor attivi. Con la rotazione automatica a 90 giorni, il totale rimane sotto i 15 MB — trascurabile rispetto al resto del database.

Qual è il miglior plugin gratuito per activity log WordPress?

WP Activity Log di Melapress è il migliore nella versione gratuita: traccia eventi illimitati senza restrizioni. Stream è una valida alternativa open source, ma manca di notifiche e ha un'interfaccia meno ricca. Per agenzie che gestiscono molti siti, WP Activity Log è la scelta più solida.

Un activity log rallenta WordPress?

No, se configurato correttamente. La scrittura di un log richiede meno di 1ms per evento. I problemi di performance si verificano solo se si eseguono query complesse sul log senza indici adeguati o se il log cresce oltre i 100.000 record senza rotazione. Le ottimizzazioni che abbiamo mostrato (indici, rotazione, batch insert) eliminano questo rischio.

L'activity log è obbligatorio per il GDPR?

L'articolo 30 del GDPR richiede un registro delle attività di trattamento per i responsabili del trattamento dei dati. Per le agenzie che gestiscono siti WordPress contenenti dati personali (praticamente tutti), un activity log è la base tecnica per questo requisito. Non è sufficiente da solo — deve essere accompagnato da policy di retention e procedure di risposta agli incidenti.

Posso centralizzare i log di più siti WordPress?

Sì, ed è esattamente ciò che raccomandiamo per le agenzie. L'approccio migliore è: ogni sito ha il proprio activity log locale, e un job programmato invia i nuovi eventi a un database centralizzato via REST API o webhook. Questo permette di avere una vista unificata di tutti i cambiamenti su tutti i siti clienti — fondamentale per il troubleshooting e il reporting.

Conclusione

Un WordPress activity log strutturato non è un lusso per le agenzie — è una necessità operativa, di sicurezza e di compliance. Che tu scelga un plugin come WP Activity Log o un'implementazione custom come quella che abbiamo mostrato, l'importante è avere visibilità completa su cosa succede sui siti dei tuoi clienti.

Nella nostra esperienza con AgencyPilot, l'activity log ci ha risparmiato decine di ore di indagini e ha reso il reporting ai clienti più trasparente. Se gestisci più di 5 siti WordPress, dovresti avere questo sistema in produzione già oggi.

Gestisci i siti WordPress dei tuoi clienti?

AgencyPilot ti dà report AI, uptime monitoring, backup e portale clienti in un’unica dashboard. Gratis per 3 siti.

Prova gratis
Leggi anche
Tutti gli articoli
Tutti gli articoli