Files
claude-plugins/wordpress/skills/wp-activity-log/SKILL.md
T
Claude Code 4a55d51329 feat(wordpress): EMCP Tools workflow skills + widget catalogs + pending wordpress skills
- emcp-page-building, emcp-content-ops, emcp-site-audit: EMCP Tools MCP
  workflows verified live (atomic/legacy interplay, apply-template overwrite
  risk, create-theme-template goes live immediately, false-positive malware
  pattern in scan-security, change ledger + rollback)
- elementor-pro-widgets: 30+5 native Elementor Pro widgets (curated catalog)
- elementskit-widgets / powerpack-widgets: 42 + 97 third-party widgets,
  widgetType extracted from plugin source (not guessed by convention)
- plugin.json bumped 1.2.0 -> 1.3.0, keywords + description updated
- commits pending wordpress skills already present as untracked files
  (emcp-tools, wordfence, wp-activity-log, seguranca-descomplicar,
  webp-express, wp-fastest-cache, wp-font-perf, wp-meteor,
  wp-activity-log, redis-object-cache, app-for-cloudflare) and pending
  edits (rank-math, wp-cli, wp-content-seo-gate)
2026-08-19 03:44:00 +01:00

29 KiB
Raw Blame History

name, description
name description
wp-activity-log Gestão e auditoria do WP Activity Log (Melapress, slug wp-security-audit-log — rebranding do antigo "WP Security Audit Log") via WP-CLI/SQL em servidores CWP. Cobre consulta ao log de eventos (tabelas wsal_occurrences/wsal_metadata), replicação do padrão stealth mode + log restrito a um único utilizador, confirmação do gotcha "wp-cli bypassa restrições de UI", e gestão de retenção/volume do log. Usar quando "wp activity log", "wsal", "wp security audit log", "log de auditoria wordpress", "quem alterou isto no site", "histórico de acções wordpress", "esconder plugin de auditoria", "stealth mode plugin", "restringir log a um utilizador".

/wp-activity-log — WP Activity Log (Melapress) via WP-CLI/SQL

Plugin de log de auditoria WordPress (equivalente a Syslog para WP). Nome comercial mudou de "WP Security Audit Log" para "WP Activity Log" (rebranding Melapress) mas o slug mantém-se wp-security-audit-log — usar sempre este slug em wp plugin get/activate/deactivate, nunca o nome comercial.

Fonte: CONFIG-Plugins-Referencia.md §9 + verificação SSH ao vivo nesta sessão (emanuelalmeida.pt, versão 5.6.5, prefixo de tabelas wpne_).


Contexto CWP — sempre obrigatório

PATH=/home/USER/public_html
PREFIX=$(wp db prefix --allow-root --path=$PATH)   # ex.: wpne_, wp_, wpah_

Acesso via SSH: server.descomplicar.pt, porta 9443. Existe sim um comando WP-CLI nativo — corrige o que estava documentado antes: o plugin regista WP_CLI::add_command( 'wsal_cli_commands', ... ) em classes/class-wp-security-audit-log.php. Ver §1.1 para a lista completa de subcomandos. Fora desses 7 comandos, o resto passa por wp option, wp db query e wp eval.


1. Identificação e configuração (18 opções wp_options)

Prefixos: wsal_* (config principal), Wsal* (raro), fs_wsalp (estado Freemius). Ler tudo de uma vez:

wp option list --search='wsal*' --format=table --fields=option_name,option_value --allow-root --path=$PATH
wp option get fs_wsalp --allow-root --path=$PATH
wp plugin get wp-security-audit-log --format=json --allow-root --path=$PATH

Tabela de configuração real (emanuelalmeida.pt, verificado ao vivo)

Opção Valor O que faz
wsal_restrict-log-viewer only_me Só o utilizador em only-me-user-id vê o log no wp-admin
wsal_restrict-plugin-settings only_me Só esse utilizador altera a configuração do plugin
wsal_only-me-user-id 17 ID do utilizador autorizado — confirmar sempre com wp user get <ID> que é a conta de IT correcta, não um utilizador órfão/comprometido
wsal_hide-plugin yes Stealth mode — esconde o plugin da lista wp-admin/plugins.php (filtro all_plugins); um atacante com sessão de browser comprometida não sabe que o site está a ser auditado
wsal_mwp-child-stealth-mode yes Idem, mas para dashboards multisite externos (ManageWP e similares)
wsal_disabled-alerts array de IDs (ver §3) Tipos de evento que NÃO são registados
wsal_plugin_version 5.6.5 Versão instalada
wsal_freemius_state / fs_wsalp skipped / no Não activou licenciamento Freemius (versão free)
wsal_built-in-notifications array serializado Config de e-mail de resumo diário (daily_summary_notification, daily_email_address)
wsal_notified_plugin_updates, wsal_notified_theme_updates, wsal_notified_wp_core_update arrays/strings Cache interna de versões já notificadas — não é config de segurança, ignorar em auditorias
wsal_feature-highlight-notice-show, wsal_upgrade-notice-show, wsal_notification-modal-dismissed, wsal_free-search-try flags de UI Estado de notices dispensados — irrelevante para segurança

1.1 Comandos WP-CLI nativos (wp wsal_cli_commands <subcomando>)

Confirmado em classes/Controllers/WP_CLI/class-wp-cli-commands.php (registados desde a v4.6, set_retention inclusive). Todos aceitam --allow-root --path=$PATH.

Subcomando Argumentos O que faz
remove_wizard nenhum Marca o wizard de setup inicial como dispensado (setup-modal-dismissed=true)
remove_daily_notification nenhum Desactiva o resumo diário por e-mail (built-in-notifications.daily_summary_notification=false) — dispara evento 6310
remove_weekly_notification nenhum Desactiva o resumo semanal por e-mail (weekly_summary_notification=false) — dispara evento 6319
disable_enable_alert <alert_id> Activa/desactiva um alert_id específico (alternativa CLI ao array wsal_disabled-alerts)
set_hide_plugin <1|true|0|false> Equivalente CLI a wp option update wsal_hide-plugin (stealth mode)
login_page_notification --enabled=<bool> --text=<html> Activa/desactiva o aviso "este site tem log de actividade" na página de login (wsal_login-page-notification + wsal_login-page-notification-text) — não confirmado activo em nenhum site auditado; texto aceita HTML
set_retention --enabled=<bool> --pruning-value=<int> --pruning-unit=<days|months|years> Configura a purga automática (pruning) — ver §6
wp wsal_cli_commands disable_enable_alert 1002 --allow-root --path=$PATH
wp wsal_cli_commands set_hide_plugin 1 --allow-root --path=$PATH
wp wsal_cli_commands set_retention --enabled=true --pruning-value=6 --pruning-unit=months --allow-root --path=$PATH

2. Consultar o log de eventos (wsal_occurrences + wsal_metadata)

O log real vive em duas tabelas dedicadas (não em postmeta/options):

wp db query "SHOW TABLES LIKE '%wsal%';" --allow-root --path=$PATH

Estrutura de ${PREFIX}wsal_occurrences (1 linha = 1 evento)

Campo Tipo Nota
id bigint PK
site_id bigint Para multisite
alert_id bigint Tipo de evento (ver tabela §3)
created_on double Unix timestamp com microssegundos — usar FROM_UNIXTIME(created_on)
client_ip varchar IP de origem
severity varchar Código numérico (ver §3)
object varchar Categoria (user, post, plugins, system, ...)
event_type varchar created/modified/deleted/login/...
username, user_id, user_roles Quem fez a acção — user_id=0 é sistema/anónimo
session_id, user_agent
post_status, post_type, post_id Preenchido só em eventos de conteúdo

Detalhe extra (nome do plugin alterado, ficheiro, etc.) fica em ${PREFIX}wsal_metadata (occurrence_id, name, value — schema key/value, LEFT JOIN por occurrence_id).

Queries úteis

PREFIX=$(wp db prefix --allow-root --path=$PATH)

# Volume total + janela temporal coberta
wp db query "SELECT COUNT(*) total, FROM_UNIXTIME(MIN(created_on)) primeiro, FROM_UNIXTIME(MAX(created_on)) ultimo FROM ${PREFIX}wsal_occurrences;" --allow-root --path=$PATH

# Últimos 50 eventos de um utilizador específico
wp db query "SELECT FROM_UNIXTIME(created_on) quando, alert_id, object, event_type, client_ip FROM ${PREFIX}wsal_occurrences WHERE username='it' ORDER BY id DESC LIMIT 50;" --allow-root --path=$PATH

# Eventos num intervalo de datas
wp db query "SELECT FROM_UNIXTIME(created_on) quando, username, object, event_type FROM ${PREFIX}wsal_occurrences WHERE created_on BETWEEN UNIX_TIMESTAMP('2026-08-01') AND UNIX_TIMESTAMP('2026-08-16') ORDER BY id;" --allow-root --path=$PATH

# Filtrar por tipo de evento (alert_id) — ex.: falhas de login (1002)
wp db query "SELECT FROM_UNIXTIME(created_on) quando, username, client_ip FROM ${PREFIX}wsal_occurrences WHERE alert_id=1002 ORDER BY id DESC LIMIT 30;" --allow-root --path=$PATH

# Distribuição por tipo de evento (para ver o que domina o log)
wp db query "SELECT alert_id, COUNT(*) total FROM ${PREFIX}wsal_occurrences GROUP BY alert_id ORDER BY total DESC LIMIT 20;" --allow-root --path=$PATH

# Distribuição por severidade
wp db query "SELECT severity, COUNT(*) total FROM ${PREFIX}wsal_occurrences GROUP BY severity ORDER BY total DESC;" --allow-root --path=$PATH

# Ver metadados de um evento específico (ex.: qual plugin foi alterado)
wp db query "SELECT name, value FROM ${PREFIX}wsal_metadata WHERE occurrence_id=<ID>;" --allow-root --path=$PATH

3. Tipos de evento e severidade (dados reais observados, emanuelalmeida.pt)

severity (código Melapress padrão): 200=informational, 250=user activity, 300=notification, 400=warning, 500=critical.

Top alert_id observados em 60.337 eventos (~1,5 anos de histórico) — usar como referência de "normal" ao auditar um site novo, não como lista exaustiva (o WSAL tem 100+ tipos de evento definidos):

alert_id Ocorrências Interpretação provável
6070 26.476 Verificação periódica de sistema (cron interno do WSAL)
1003 20.276 Actividade de sessão/login
2008 3.202 Conteúdo modificado (post/página)
6066 2.615 Verificação periódica de sistema
6069 2.329 Verificação periódica de sistema
1002 1.965 Login falhado
1000 389 Login com sucesso
2053/2054 305/133 Conteúdo criado/eliminado

Não confiar em interpretações de alert_id sem confirmar contra a documentação oficial Melapress (https://melapress.com/support/kb/) ou o código do plugin (wp-content/plugins/wp-security-audit-log/) — os números acima são inferência a partir do padrão de volume, não confirmados individualmente nesta sessão.

3.1 Categorias de eventos (mapa completo, defaults.php)

Ficheiro central de definições: defaults.php (raiz do plugin, função set_wsal_alerts(), ~3.760 linhas). Define as categorias core — os eventos de integrações de terceiros (WooCommerce, Yoast, ACF, Rank Math, etc.) vivem em ficheiros separados (ver §3.2). Categorias core, por ordem de aparição no ficheiro (nome + intervalo aproximado de alert_id):

Categoria (grupo topo) Subcategorias Intervalo alert_id Conteúdo
Users Logins & Sessions Events User Activity 1000–1099 Login/logout, falhas de login, sessões, alteração de password
Content & Comments Content, Categories, Custom Fields, Custom Fields (ACF), Comments, Widgets, Menus, Custom Post Types, Pages 2000–2999 Posts/páginas criados/editados/eliminados, categorias, comentários, widgets, menus, custom post types, ACF
User Accounts User Profiles, Multisite User Profiles 4000–4999 Utilizadores criados/editados/eliminados, mudança de role, password reset
Plugins & Themes Plugins, Themes, Themes on Multisite 5000–5599 Instalação/activação/desactivação/actualização de plugins e temas
Activity Logs Activity log plugin 6000–6099, 6300–6399 Config do próprio WSAL alterada (ex.: 6310/6311/6312/6319 já usados pelos comandos WP-CLI de notificação — ver §1.1); também cobre eventos de "Notifications & Integrations" (Slack/SMS/e-mail custom)
WordPress & System System 6000–6099 Cron interno do WSAL, verificações periódicas (os IDs 6066/6069/6070 de alto volume observados em §3 pertencem aqui)
— WordPress Site Settings 4700–4799 (aprox.) Alteração de opções core do WP (site title, timezone, permalinks, etc.)
— Email Events 8800–8899 (aprox.) Falhas de envio de e-mail via wp_mail
— Database Events 9000–9099 (aprox.) Erros de query, updates de schema da BD

Nota: as gamas de alert_id acima são aproximadas (extraídas da ordem de definição em defaults.php, não documentadas oficialmente pela Melapress como ranges fixos) — para confirmar a categoria exacta de um alert_id específico, o método fiável é grep -A6 "^\s*$ALERT_ID,$" defaults.php no código-fonte do servidor.

3.2 Alertas de integrações de terceiros (activados só se o plugin correspondente estiver presente)

Ficheiros em classes/WPSensors/Alerts/ (18 ficheiros, um por integração suportada) — cada um define o próprio bloco de alert_id, só carregado se o plugin alvo estiver activo no site:

Ficheiro Integração Volume aprox. de alertas
class-woocommerce-custom-alerts.php WooCommerce ~417 linhas de definição (produtos, encomendas, cupões, definições da loja)
class-yoast-custom-alerts.php Yoast SEO Meta SEO, sitemaps, redirects
class-rank-math-custom-alerts.php Rank Math Meta SEO, schema, redirects
class-acf-custom-alerts.php Advanced Custom Fields Grupos de campos, campos criados/editados
class-gravity-forms-custom-alerts.php Gravity Forms Formulários, entradas, notificações
class-wpforms-custom-alerts.php WPForms Formulários, entradas
class-wp-2fa-custom-alerts.php WP 2FA (Melapress) Activação/desactivação de 2FA por utilizador
class-memberpress-custom-alerts.php MemberPress Subscrições, membros
class-paid-memberships-pro-custom-alerts.php Paid Memberships Pro Níveis, membros
class-learndash-custom-alerts.php LearnDash Cursos, inscrições
class-bbpress-custom-alerts.php bbPress Fóruns, tópicos
class-tablepress-custom-alerts.php TablePress Tabelas
class-redirection-custom-alerts.php Redirection Regras de redirect
class-termly-custom-alerts.php Termly Consentimento de cookies
class-ai-wp-plugin-alerts.php AI (Melapress AI features) Uso de funcionalidades AI do próprio WSAL
class-multisite-custom-alerts.php WordPress Multisite Criação/eliminação de sites na rede
class-mainwp-server-custom-alerts.php MainWP (servidor gerido) Propagação de definições via dashboard MainWP — ver aviso em defaults.php:2593 ("definições do WSAL foram sobrepostas a partir do MainWP")

Confirmar quais estão activos num site: wp plugin list --status=active --allow-root --path=$PATH e cruzar com a tabela acima — só os que correspondem a um plugin activo geram eventos.


4. Replicar o padrão de segurança num site novo (checklist)

Baseado na configuração real confirmada em emanuelalmeida.pt (avaliada como "acima da média"):

PATH=/home/USER/public_html

# 1. Instalar/activar (slug correcto — nome comercial mudou, slug não)
wp plugin install wp-security-audit-log --activate --allow-root --path=$PATH

# 2. Identificar o ID do utilizador de IT/admin de confiança (NÃO um admin genérico partilhado)
wp user list --role=administrator --fields=ID,user_login,user_email --allow-root --path=$PATH

# 3. Restringir visualização do log e config a esse utilizador
wp option update wsal_restrict-log-viewer only_me --allow-root --path=$PATH
wp option update wsal_restrict-plugin-settings only_me --allow-root --path=$PATH
wp option update wsal_only-me-user-id <ID_do_utilizador_IT> --allow-root --path=$PATH

# 4. Activar stealth mode — esconder o plugin da lista wp-admin
wp option update wsal_hide-plugin yes --allow-root --path=$PATH
wp option update wsal_mwp-child-stealth-mode yes --allow-root --path=$PATH

# 5. Confirmar (ler de volta, nunca confiar só no exit code)
wp option get wsal_restrict-log-viewer --allow-root --path=$PATH
wp option get wsal_only-me-user-id --allow-root --path=$PATH
wp user get <ID_do_utilizador_IT> --field=user_login --allow-root --path=$PATH

Não mexer em wsal_disabled-alerts por defeito — deixar todos os ~900+ tipos de evento activos (contando módulos de terceiros — ver §3.1). O padrão observado de apenas 13 IDs desligados, todos de baixo valor informativo, é a postura recomendada; desligar mais do que isso reduz cobertura de auditoria sem ganho real.


5. GOTCHA CRÍTICO — stealth mode e "only_me" não protegem contra WP-CLI/SQL

Confirmado nesta sessão por teste directo: apesar de hide-plugin=yes esconder o plugin da lista em wp-admin/plugins.php (via hook PHP no ecrã de admin), o plugin continua totalmente visível e operável via WP-CLI:

wp plugin list --allow-root --path=$PATH | grep security-audit
# → wp-security-audit-log,active,none,5.6.5,,on   (aparece normalmente)

wp plugin status wp-security-audit-log --allow-root --path=$PATH
# → Status: Active   (nenhuma restrição aplicada)

Implicação de segurança real: o padrão "esconder + restringir a only_me" protege apenas contra um atacante que compromete uma sessão de browser wp-admin de um utilizador administrador genérico (não vê o plugin na UI, não consegue desactivá-lo nem ler o log pela interface). Não protege contra:

  • Acesso SSH/WP-CLI ao servidor (qualquer comando wp plugin deactivate, wp option update wsal_hide-plugin no, ou wp db query "DELETE FROM wsal_occurrences" funciona sem qualquer verificação de only-me-user-id);
  • Acesso directo à base de dados (phpMyAdmin, mysql CLI);
  • Um plugin malicioso que corra update_option()/deactivate_plugins() em PHP no mesmo processo WordPress (o hook de stealth só filtra a renderização da lista, não a capability real).

Estas restrições são apenas de UI, implementadas por filtros como all_plugins/menu — não são um controlo de acesso ao nível dos dados. Ao avaliar a robustez do log de auditoria de um site, tratar sempre acesso SSH/WP-CLI e acesso à BD como "full trust" que ignora completamente esta protecção — a defesa real contra esses vectores é a segurança do próprio servidor (SSH keys, mysql sem exposição externa), não a config do plugin.


6. Retenção, arquivo e volume do log

O plugin não faz purga agressiva por defeito — confirmado: emanuelalmeida.pt tinha 60.337 eventos cobrindo Mar/2025 a Ago/2026 (~1,5 anos) sem gaps aparentes, ocupando ~13 MB (wsal_occurrences) + ~50 MB (wsal_metadata, guarda os detalhes de cada evento — cresce mais rápido que a tabela principal).

# Verificar tamanho actual antes de decidir sobre arquivo/purga
wp db query "SELECT table_name, ROUND(((data_length+index_length)/1024/1024),2) size_mb, table_rows FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name LIKE '%wsal%';" --allow-root --path=$PATH

6.1 Purga automática (pruning) — wsal_pruning-*, classe Plugin_Settings_Helper/Settings_Helper

Ao contrário do que a auditoria pontual anterior sugeria, a purga automática não é exclusiva da versão paga — a lógica e as opções vivem no core (classes/Helpers/class-plugin-settings-helper.php + class-settings-helper.php) e há um comando WP-CLI dedicado (set_retention, ver §1.1). Confirmado nesta expansão: nenhuma destas opções está definida em emanuelalmeida.pt (usa os defaults do código, purga desligada).

Opção Default no código O que faz
wsal_pruning-date-e false (desligado) Activa/desactiva a purga automática por data
wsal_pruning-date calculado por get_default_pruning_date() Data-limite (strtotime-compatible, ex. "6 months") — eventos mais antigos são apagados no próximo cron
wsal_pruning-unit months Unidade usada no picker da UI (days/months/years)
wsal_pruning-limit-e não confirmado Activa purga por limite de contagem (em vez de por data)
wsal_pruning-limit 1 (mínimo) Nº máximo de eventos a manter, quando pruning-limit-e=true
wsal_delete-data false Se true, ao desinstalar o plugin todos os dados (wsal_occurrences/wsal_metadata/opções) são apagados; se false, ficam órfãos na BD
# Ler estado actual de purga
wp option list --search='wsal_pruning*' --format=table --allow-root --path=$PATH

# Activar purga a 6 meses via WP-CLI (equivalente ao form da UI)
wp wsal_cli_commands set_retention --enabled=true --pruning-value=6 --pruning-unit=months --allow-root --path=$PATH
wp option get wsal_pruning-date-e --allow-root --path=$PATH
wp option get wsal_pruning-date --allow-root --path=$PATH

6.2 Arquivo (archiving) para BD externa — wsal_archiving-*

Funcionalidade distinta da purga: em vez de apagar, move eventos antigos para uma segunda ligação de base de dados (Archive_Records::archive() em classes/Entities/Archive/class-archive-records.php) via cron. Requer configurar previamente uma "connection" de arquivo (ver §6.3) — sem connection definida, is_archiving_set_and_enabled() devolve false e o cron não corre, mesmo com archiving-e=yes.

Opção O que faz
wsal_archiving-e Liga/desliga o arquivo automático
wsal_archiving-date + wsal_archiving-date-type (days/months/years, default 1/months) Antiguidade a partir da qual um evento é arquivado
wsal_archiving-run-every Frequência do cron de arquivo (default hourly)
wsal_archiving-stop Pausa temporária do arquivo sem desligar a config
wsal_archiving-cron-started Flag interna — cron já agendado
wp option list --search='wsal_archiving*' --format=table --allow-root --path=$PATH

Não confirmado activo em nenhum site auditado (emanuelalmeida.pt não tem nenhuma destas opções definidas).

6.3 Espelhamento (mirroring) para BD/serviço externo — wsal_wsal-mirror-*

Envia uma cópia em tempo real de cada evento para uma ligação externa (outra tabela MySQL, ou syslog/SIEM de terceiros via plugin de mirror dedicado — o WSAL não tem integração nativa de syslog/SIEM no core, só o mecanismo genérico de "connections" reutilizado por mirror e archiving). Settings_Helper::get_all_mirrors() lê todas as opções com prefixo WSAL_MIRROR_PREFIX (wsal-mirror-); cada uma é um array serializado (connection, filtros de alert_id, etc.).

wp option list --search='wsal-mirror-*' --format=table --allow-root --path=$PATH
wp option list --search='wsal_connection-*' --format=table --allow-root --path=$PATH

Se database_logging_enabled for false E existir pelo menos um mirror configurado, o WSAL passa a não gravar mais em wsal_occurrences local — todo o log vai só para o(s) destino(s) espelhados. Confirmar sempre Settings_Helper::is_database_logging_enabled() (via wp eval) antes de assumir que as queries SQL do §2 devolvem o histórico completo num site com mirror activo.

Nota operacional (aplica-se a §6.1–§6.3): a ausência de purga é boa para auditoria (histórico completo disponível), mas em sites com muita actividade o crescimento é linear e sem limite. Se wsal_metadata ultrapassar dimensões incómodas (centenas de MB), considerar:

  • Activar wsal_pruning-date-e com uma janela realista (6–12 meses) via set_retention;
  • Arquivar eventos antigos para uma tabela _archive antes de apagar (nunca DELETE directo sem backup — perde-se rasto de auditoria);
  • Configurar uma connection de arquivo (§6.2) se o volume justificar automação em vez de purga manual.

Não foi necessário agir em emanuelalmeida.pt nesta sessão — volume actual (~63 MB total) é irrelevante para performance.


7. Notificações, relatórios e integrações

7.1 Notificações incorporadas (resumo diário/semanal por e-mail — gratuito)

Opção wsal_built-in-notifications (array serializado, constante Notifications::BUILT_IN_NOTIFICATIONS_SETTINGS_NAME). Confirmado em emanuelalmeida.pt: só contém config de resumo diário (daily_summary_notification, daily_email_address); a v5.3+ acrescentou resumo semanal (weekly_summary_notification, evento 6319 ao desactivar — ver §1.1 remove_weekly_notification).

wp option get wsal_built-in-notifications --format=json --allow-root --path=$PATH

7.2 Notificações customizadas (regra "se alert_id X ocorrer, notifica Y") — Premium

Opção wsal_custom-notifications (constante CUSTOM_NOTIFICATIONS_SETTINGS_NAME) — permite regras condicionais por utilizador/IP/tipo de evento, com entrega por e-mail, Slack (classes/Controllers/slack/) ou SMS via Twilio (classes/Controllers/twilio/). Não confirmado activo em nenhum site auditado; wsal_notifications (nota: nome sem custom-, é outra opção) só guarda config global de encurtamento de URLs (shorten_notification_urls, notification_bitly_shorten_key) — confirmado vazio/desligado em emanuelalmeida.pt.

wp option get wsal_custom-notifications --format=json --allow-root --path=$PATH
wp option get wsal_notifications --format=json --allow-root --path=$PATH

7.3 Exportação e relatórios

  • CSV — gratuito, core. Acção AJAX wsal_export_csv_results (classes/Writers/class-csv-writer.php), disponível no ecrã do log em wp-admin (botão "Export"). Não há comando WP-CLI dedicado — a exportação é sempre via browser/AJAX; para extrair dados por CLI usar as queries SQL do §2 e wp db query ... --format=csv como alternativa equivalente.
  • Relatórios agendados (geração automática + entrega por e-mail, white-label) — feature Premium (classes/Views/class-premium-features.php, AuditLog.php:470 mostra link de upsell "Get scheduled reports... with Premium" nos eventos de tipo 2000/2001/2100/4000). Não existe em wp-options nem endpoint WP-CLI na versão gratuita.

7.4 SIEM/Syslog externo

Não existe integração nativa de Syslog/SIEM no core do plugin — confirmado por ausência de qualquer classe/ficheiro com syslog/SIEM no código-fonte (grep -rl devolveu zero resultados). A única via de exportar eventos em tempo real para um sistema externo é o mecanismo de espelhamento (mirroring) descrito em §6.3, que só suporta ligações configuradas como "connections" do próprio plugin (outra BD MySQL) — não um protocolo Syslog/CEF nativo. Para integração SIEM real, a Melapress documenta um add-on comercial separado; confirmar sempre no site do fornecedor antes de assumir que existe suporte nativo.


8. Erros comuns

Sintoma Causa Solução
wp plugin activate wp-activity-log falha ("plugin not found") Usou o nome comercial em vez do slug Slug é sempre wp-security-audit-log, independentemente do rebranding
Query em wsal_occurrences devolve datas erradas created_on é Unix timestamp double (com microssegundos), não DATETIME Usar sempre FROM_UNIXTIME(created_on)
Achar que o plugin "não está lá" num site com hide-plugin=yes Confundir stealth mode de UI com ausência real Confirmar sempre via wp plugin list/wp plugin status — o WP-CLI nunca respeita esta flag (ver §5)
only-me-user-id aponta para um ID que já não existe/foi desactivado Utilizador de IT mudou de conta e a opção não foi actualizada Confirmar sempre com wp user get <ID> antes de assumir que a restrição é válida — um ID órfão equivale a log inacessível a todos via UI
Achar wsal_disabled-alerts vazio = tudo activo O array serializado inclui sempre um s:0:"" inicial (artefacto de serialização PHP), não é um alerta desligado real Ignorar a primeira entrada vazia ao contar IDs desligados
Achar que "não há WP-CLI para este plugin" Confusão histórica — o WSAL regista wp wsal_cli_commands desde a v4.6 Usar wp cli cmd-dump | grep wsal para confirmar; ver §1.1
Achar que purga automática (pruning) é só Premium set_retention/wsal_pruning-* são core, disponíveis na versão gratuita Confirmar sempre no código (class-plugin-settings-helper.php) antes de recomendar upgrade pago só para ligar retenção
Confundir wsal_notifications com wsal_custom-notifications Nomes parecidos, funções diferentes — a primeira é só config de encurtamento de URL, a segunda são as regras de alerta customizado (Premium) Ler sempre as duas e não assumir que uma vazia implica a outra desligada
Assumir que o log SQL (§2) tem o histórico completo num site com mirroring activo Se database_logging_enabled=false com mirror configurado, o WSAL deixa de escrever localmente Confirmar Settings_Helper::is_database_logging_enabled() via wp eval antes de tirar conclusões de volume/gaps

Fonte: CONFIG-Plugins-Referencia.md §9 (WP Security Audit Log / WP Activity Log) + verificação SSH ao vivo nesta sessão (emanuelalmeida.pt, opções wsal_*, estrutura e contagem de wsal_occurrences/wsal_metadata, teste de bypass wp plugin list) + leitura completa do código-fonte do plugin nesta expansão (wp-content/plugins/wp-security-audit-log/, versão 5.6.5, ~99.000 linhas PHP): defaults.php (definições de todos os eventos core, função set_wsal_alerts()), classes/WPSensors/Alerts/* (18 integrações de terceiros), classes/Controllers/WP_CLI/class-wp-cli-commands.php (comandos WP-CLI nativos), classes/Helpers/class-settings-helper.php + class-plugin-settings-helper.php (todas as opções wsal_* — pruning, archiving, mirroring, notificações), classes/Entities/Archive/class-archive-records.php (mecanismo de arquivo), classes/notification/* (notificações incorporadas e customizadas, Slack/Twilio), classes/Views/class-premium-features.php e AuditLog.php (features gated como Premium: relatórios agendados, notificações custom, mirroring/archiving).