Zodiac Tech CRM Docs

Monitoring & alerts

What to watch on a live install, where each signal lives, and which signal maps to which runbook — health endpoint, Meta, WhatsApp, billing and the scheduler.

super-admin developer Easy ⏱ 15 min Updated 2026-10-05

Monitoring & alerts

Zodiac Tech CRM is deliberately pragmatic about monitoring: there is one public health endpoint you can point any uptime monitor at, plus in-app health surfaces that already do the deeper checking for you. This page is the map — every built-in signal, where it lives, and which runbook to open when it fires.

Who this is for

  • The person who owns uptime for a live install.
  • Developers wiring an external monitor or an on-call rota.

Difficulty: Easy · Time: 15 minutes to read and wire up · Prerequisites: Super Admin access; access to whatever uptime-monitoring tool you use.

The one endpoint to monitor externally

GET {your app URL}/api/v1/health is public and designed for monitors:

  • HTTP 200 with status: ok — web app up, and the db, cache and storage checks passed.
  • HTTP 503 with status: degraded — one of those checks failed; the payload's checks object shows which.

Alert on non-200 and on the literal string "status":"degraded". Also monitor the login page itself (/admin) — a monitor should prove the app renders, not just that PHP answers. Suggested cadence: every 1–5 minutes for the health URL, every 5–15 minutes for the login page.

The in-app signal table

Signal Where it lives Healthy looks like When it fires, go to
System health, disk, queue driver, debug mode Super Admin → Settings → System Health (/super-admin/settings/system-health) Queue driver not sync, debug off, disk headroom Incident response
Meta connection problems leadhub:meta-health (every 6 h) + Super Admin → Meta Ads → Needs Attention (/super-admin/meta-ads/needs-attention) All connections healthy; no open CRITICAL issues Meta won't connect
Meta connection statuses Health report + connection record healthy (or expiring as an early warning only) Meta won't connect
WhatsApp connection, templates, message volume System Health → WhatsApp card Connections connected, templates approved, queue_failures 0 WhatsApp not sending
Inbound webhook rejects Admin → Webhook Logs (/admin/webhook-logs) All rows accepted Leads not entering the CRM
Lead source health Admin → Lead Source Health Report (/admin/lead-source-health-report) Every connection healthy or explainably paused Meta won't connect
Payment failures and lifecycle states Super Admin → Billing → Commercial (/super-admin/billing/commercial) payment_failures, grace_period, restricted, suspended cards all quiet Payments failing
Provider reconciliation drift Billing overview → "Needs Attention" (BillingReconciliationAlert) No open alerts Payments failing
Failed jobs / queue health System Health + php artisan queue:failed Empty failed list, worker running Incident response
Scheduler health storage/logs/laravel.log for schedule task failed: {name} No such lines Daily checks
App errors storage/logs/laravel.log (stack → single) No repeating ERROR families Deployment & server errors

The log lines worth grepping Grep the log for these exact keys to catch the failures the app already reports: healthcheck.db.failed, healthcheck.cache.failed, healthcheck.storage.failed, schedule task failed, [leadhub:meta-health] unhealthy Meta connections detected, Webhook: unknown token.

What has no built-in alerting

Be honest about the gaps, and cover them with habit or an external probe:

  • Email/SMS delivery failures — queue failures and provider errors are logged but there is no dedicated alert. The 5-minute IMAP checks and the hourly digest exist, but a hard email outage surfaces through support tickets first.
  • Push notification (FCM) delivery — device-side states are on the phone's Device Health screen; the platform does not alert on FCM failures. Use php artisan leadhub:test-push {email} when verifying.
  • Individual scheduled task pauses — there is no per-task toggle. If you need to pause something, you stop the cron/worker (see Incident response); note it in your pager or you will forget it is off.

Suggested monitoring setup

  1. Uptime monitor → GET /api/v1/health, alert on non-200.
  2. Uptime monitor → /admin login page, alert on non-200 or missing marker text.
  3. Daily check habit or script → schedule task failed and healthcheck. greps in the log (see Daily checks).
  4. Weekly human pass → Webhook Logs, Needs Attention, billing cards (see Weekly & monthly reviews).
  5. External check → does the message queue drain? Insert a controlled test lead and watch it reach the CRM on a schedule you choose; alert if it stops.

Expected result

A monitor that would page you within minutes of the app going down, and a human process that would notice within a day if anything subtler (Meta, WhatsApp, webhooks, payments) drifted.

Common mistakes

Mistake Why it hurts Do this instead
Monitoring only the homepage The homepage may render while the DB check fails Use /api/v1/health and read status
Treating expiring as fine It silently becomes expired and leads stop Reconnect while it is still expiring
No external monitor "The team would notice" is a monitoring plan with a gap Wire the health URL today
Ignoring Needs Attention badges They exist because nav pages are rarely visited Clear them weekly, at minimum

Technical details

  • The health endpoint lives in App\Http\Controllers\Api\HealthController; failure paths log healthcheck.db.failed, healthcheck.cache.failed, healthcheck.storage.failed.
  • Scheduled failures are logged by the scheduler wrapper as Log::error("schedule task failed: {$name}").
  • leadhub:meta-health (every 6 hours) writes the warning log line quoted above; per-connection statuses come from MetaConnectionHealthService.
  • Webhook rejects are stored as WebhookLog rows and are the fastest per-lead diagnostic in the app.
  • The billing reconciliation cadence is 30 minutes; alerts appear in the billing overview's "Needs Attention" list and are not emailed.

Was this page helpful?