ahmedmerza/watchtower
Ahmed Merza's Watchtower is a Laravel/PHP package for application monitoring and observability. It gives you a lightweight way to keep an eye on key events and health signals, helping you spot issues early and stay informed with simple setup.
GET /blocks read surface, threat-feed import, and multi-node propagation — so the decision shifts from "do we build an abuse/blocklist service?" to "do we configure this one?" That is a quarter-plus of engineering avoided for most teams.WATCHTOWER_MASTER_URL, WATCHTOWER_SYNC_SECRET, watchtower:sync, watchtower:reconcile) is now cheap enough to run at scale. v1.1.0 changes reconcile from queueing one job per active global block on every run to queueing only actual drift, so the cost of a satellite fleet is proportional to divergence, not to blocklist size. Scheduling reconcile every five minutes is now a defensible default rather than a queue-flooding hazard.WATCHTOWER_SYNC_SECRET rather than silently queueing pushes that send nothing. This converts a silent misconfiguration into a loud one — a decision point for teams that had been running half-configured satellites and calling it "working."Adopt when:
Look elsewhere when:
For executives: This is infrastructure we would otherwise build. v1.1.0 makes it viable at the scale we actually operate: block list pages were doing a full-table sort on every load and now hit an index — 15–96 ms down to under 1 ms on 50k rows across SQLite, MySQL and Postgres. More importantly, the reconcile job that keeps satellites in step used to enqueue work proportional to the entire block list on every run; it now enqueues only the differences. That means a five-minute sync cadence costs roughly nothing when nothing has changed, instead of growing with the block list forever. Net effect: lower queue and database load, a usable triage UI for feed-imported blocks, and no bespoke service to staff.
For engineering: One migration (update_blacklisted_ips_table_with_list_indexes) — publish the watchtower-migrations tag and migrate. No config changes required. The indexes are (created_at, id) for the default sort, (source, created_at) for the source filter, and expires_at for the expired view; scope is left unindexed on purpose because nearly every row is global and the index would select almost everything — don't "fix" that. Reconcile now reads the master's list via the same paged, signed request watchtower:sync uses, pushes only blocks the master lacks or holds with an earlier expiry, skips the master entirely when there's nothing to repair, and reads the local block list in chunks rather than loading it whole.
The one thing to action before deploy: any satellite with WATCHTOWER_MASTER_URL set but no WATCHTOWER_SYNC_SECRET will now fail its laravel target in watchtower:reconcile with an explicit message, instead of queueing jobs that logged a warning and sent nothing. Audit those environment variables first — the new behavior is correct, but it will surface previously invisible misconfigurations as visible failures on the next scheduled run.
How can I help you explore Laravel packages today?