--- created: 2026-04-07 path: Sources/Dev project: wordpress-log-monitor status: active tags: - security - docker - python - mysql - streamlit - n8n - monitoring type: Tech/Projects updated: 2026-04-07 --- # WordPress Log Monitor ## Goal Build a security monitoring pipeline that parses WordPress Docker logs, stores metrics in MySQL, and visualizes trends in Streamlit. Replaces manual log grepping with an automated dashboard and Google Chat alerts. ## Problem Being Solved - 11,000+ brute force hits on wp-login.php went undetected for days - No visibility into what traffic actually reaches the server vs what Cloudflare blocks - Memory crashes caused by Apache worker exhaustion were mysterious without log data - Manual grepping is not sustainable as site grows ## Architecture Docker WordPress Logs → Python Parser → MySQL → n8n Orchestration → Streamlit Dashboard ↓ Google Chat Alerts ## Data To Capture ### wp-login.php metrics - Timestamp, IP address, HTTP method (GET vs POST), response code - User agent string - Hourly/daily hit counts - POST attempts (actual login attempts) vs GET (page loads) ### General security metrics - 404 hit counts by IP (bot scanning indicator) - Response code distribution - Top IPs by request volume - Slowest requests (response time > 5 seconds) ### Apache health metrics - Active worker count over time (correlate with memory spikes) - Request rate per minute - Memory usage correlation ## Implementation Plan ### Phase 1: Python Log Parser - Use UV + venv, managed in PyCharm - Parse WordPress Docker logs via docker logs command or log file mount - Extract: timestamp, ip, method, uri, status, response_size, response_time, user_agent - Store raw events in MySQL pbs_security_events table - Run on schedule via n8n (every 5-15 minutes) ### Phase 2: MySQL Schema - pbs_security_events: raw parsed log entries - pbs_security_summary: hourly aggregates for dashboard performance - pbs_blocked_ips: known bad actors for reference ### Phase 3: n8n Orchestration - Schedule Python collector every 15 minutes - Alert workflow: if wp-login.php hits > threshold in last hour → Google Chat alert - Daily summary workflow → Google Chat digest with key metrics ### Phase 4: Streamlit Dashboard - wp-login.php hits over time (line chart) - Top attacking IPs (table) - Response code distribution (bar chart) - Apache worker count vs memory usage (correlation chart) - Cloudflare vs server hit comparison (manual input or CF API) ## MySQL Schema (Draft) CREATE TABLE pbs_security_events ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, logged_at DATETIME NOT NULL, ip_address VARCHAR(45) NOT NULL, method VARCHAR(10), uri TEXT, status_code SMALLINT, response_size INT, response_time_ms INT, user_agent TEXT, event_type VARCHAR(50), created_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_logged_at (logged_at), INDEX idx_ip (ip_address), INDEX idx_uri (uri(100)) ); ## Alert Thresholds (Starting Points) - wp-login.php hits > 20 in any hour → Google Chat alert - Any single IP > 50 requests in 10 minutes → Google Chat alert - WordPress response time > 10 seconds → Google Chat alert - Memory usage > 1.5GiB sustained 10 minutes → Google Chat alert ## Future Expansion - Pull Cloudflare Security Events via API for comparison - Correlate Apache worker count with memory stats - Auto-block IPs in Wordfence via API when threshold exceeded - Feed data into broader PBS Content Intelligence Platform ## Notes - Use docker logs --since flag to avoid reprocessing old entries - Store last processed timestamp in MySQL to handle restarts cleanly - Keep collector lightweight — this runs every 15 minutes - PyCharm Professional for development, UV for package management