5.3 KiB
Service Monitoring Patterns & Operations Notes (Jul 8 2026)
Collection of monitoring cron patterns used on Core for external services. Each pattern is a no_agent cron that checks health and alerts on failure.
Apex Mail Watchdog
Purpose: Monitor WP Mail SMTP email delivery on a remote WordPress site (wphost02).
Every: 5 min
Script: /root/.hermes/scripts/apex-mail-watchdog.sh
Deliver: origin (only messages on failure)
Actions:
- SSH to wphost02 via itpp-infra key
- Send test email via SMTP (c1113726.sgvps.net:2525)
- Check wp_wpmailsmtp_debug_events table for recent failures
- Silent on success (no output = no message), only alerts on failure
Common SMTP failure signs:
- WP Mail SMTP password PHP serialization length mismatch (
s:72vs actuals:13) - Sender address containing comma-separated emails (invalid
From:header) - SMTP server rejecting
MAIL FROMfor unowned domain
Fix pattern:
- Check
wp_wpmailsmtp_debug_eventsfor most recent error content - Test SMTP directly via Python:
smtplib.SMTP(host, 2525).starttls() - If authentication fails: the PHP serialization of the password in
wp_optionsis likely corrupted - SQL to fix:
UPDATE wp_options SET option_value = REPLACE(option_value, 's:72:\\\"pass\\\"', 's:13:\\\"pass\\\"') WHERE option_name = 'wp_mail_smtp'
Known failure mode (Jul 8 2026):
WP Mail SMTP password was stored with wrong PHP serialization length (s:72 for 13-char password apex.track!!). WPForms sender_address had comma-separated emails (invalid From: header). Both fixed via SQL.
Ops Data Collector
Purpose: Collect comprehensive infrastructure status data for the ops dashboard at ops.itpropartner.com
Every: 5 min
Script: /root/.hermes/scripts/ops-data-collector.py
Deliver: local (writes JSON file only)
Data sources:
- Hermes cron jobs (from /root/.hermes/cron/jobs.json)
- Systemd service status via systemctl
- S3 backup timestamps via AWS CLI (wasabisys endpoint)
- API health checks (admin-ai, Caddy, ports, Cloudflare)
- Hetzner server list via API
- netcup server info via SCP API
- Local disk/memory usage
- Service versions
JSON output:
/var/www/ops/data/ops-status.json -- consumed by the ops dashboard HTML page.
Build pattern (Jul 8 2026):
- Collector: self-contained Python stdlib script, no external deps
- Dashboard: single HTML page, no CDN/frameworks, dark theme (#0f172a / #1e293b), mobile-first
- Site: Caddy reverse proxy at ops.itpropartner.com with HTTP-01 ACME challenge
- DNS for itpropartner.com is at SiteGround (not Cloudflare), so Caddy handles TLS directly
- Data/ directory gets CORS headers for cross-origin access
Home Router Watchdog
Purpose: Verify home router is online.
Every: 5 min
Script: /root/.hermes/scripts/home-router-watchdog.sh
Deliver: origin
Router Backup Pipeline
Purpose: Backup MikroTik router configs to S3. Every: Daily at 6 AM Script: run-wisp-backup.sh (referenced from /root/.hermes/cron/jobs.json)
VPN dependencies for L2TP/IPsec router backup:
- xl2tpd package
- strongSwan-starter package
- IP in config must match the router's SSH bind address (often WireGuard tunnel IP, not LAN IP)
Failure mode (Jul 8 2026):
Cron was using old home-router-backup.sh instead of proper run-wisp-backup.sh. Router SSH export produced stuck .in_progress files blocking SCP. Fix: switched cron, cleaned files, installed missing paramiko/xl2tpd/strongSwan.
Warm Standby Sync
Purpose: Keep app1-bu's local state fresh for rapid failover.
Every: 10 min
Script: /root/.hermes/scripts/hermes-standby-sync.sh on app1-bu
Triggered by: System cron on app1-bu, not Hermes cron.
Netcup SCP API Notes (Discovered Jul 8 2026)
The REST API lives at https://www.servercontrolpanel.de/scp-core/api/v1/. Auth is OIDC password grant via Keycloak at https://www.servercontrolpanel.de/realms/scp/protocol/openid-connect/token using client_id=scp with username/password. The CCP API key from Master Data does NOT work with the SCP API.
Credentials stored in /root/.hermes/.env as NETCUP_CUSTOMER, NETCUP_PASSWORD, NETCUP_API_KEY.
Infrastructure Consolidation Strategy (Jul 8 2026)
Hetzner new-server pricing is significantly inflated. API returns CPX11 at ~$17.49/mo vs historical ~$4. netcup root servers (RS 1000 at 4C/8G/256GB for ~$12.24/mo) offer better value. Strategy: consolidate Hetzner workloads onto netcup rather than provisioning new Hetzner servers.
Domain/Portal Separation Rule (Established Jul 8 2026)
Service-related operational tools must be hosted on the provider's own domain, NOT a customer's/industry domain. Two-portal architecture:
- ops.itpropartner.com -- internal admin dashboard, infra monitoring, scripts, status pages (Cloudflare Access SSO protected)
- portal.itpropartner.com -- customer-facing portal
- Never put IT Pro Partner operational tools on customer/themed subdomains (e.g. debtrecoveryexperts.com)
This is a hard architectural rule. When deciding where a new dashboard, page, or tool lives, the default answer is ops.itpropartner.com unless the user explicitly says otherwise.
Log Paths
| Watchdog | Log |
|---|---|
| Apex mail | /var/log/apex-mail-watchdog.log |
| Home router | /var/log/hermes-standby-watchdog.log |
| Standby sync | /var/log/hermes-standby-sync.log |
| Ops collector | /var/log/ops-collector.log |