sarfraznawaz2005/servermonitor
Laravel server monitoring package that tracks CPU, memory, disk, and load, checks uptime, and alerts you via email, Slack, or other channels when thresholds are exceeded. Includes a dashboard for real-time server health insights.
servermonitor is a small, single-purpose Laravel package that samples host resources (CPU load, memory, disk) on demand and notifies you when configurable thresholds are crossed. It is not a request-level APM tool — think "cron-driven smoke alarm," not Telescope.
Install and publish:
composer require sarfraznawaz2005/servermonitor
php artisan vendor:publish --tag=servermonitor # check `php artisan vendor:publish` output for the exact tag
The service provider is auto-discovered. Everything of interest lives in:
config/servermonitor.php — thresholds, notification channels/recipients, dashboard route and middleware.src/ — the check command and the notification class. It is small enough (a handful of files) to read end-to-end in ten minutes; do that before wiring it into production alerting.First use case — disk pressure on a small VPS:
php artisan servermonitor:check. Run it with -v if you need to see what it evaluated.route key, e.g. /servermonitor) and confirm the numbers match df -h / free -m on the box.Only after a manual run produces the alert you expect should you schedule it.
Scheduling (Laravel 11+/12/13 style). Put it in routes/console.php rather than the legacy Kernel::schedule:
use Illuminate\Support\Facades\Schedule;
Schedule::command('servermonitor:check')
->everyFiveMinutes()
->withoutOverlapping();
On Laravel 13 the old app/Console/Kernel.php is long gone — if your muscle memory reaches for it, you're on the wrong file.
Per-environment thresholds via config. Publish the config, then replace literals with env() calls so staging and production don't share numbers. Production boxes with 8 cores and 32 GB should not alert at the same memory percentage as a 1 GB dev droplet.
Protecting the dashboard. The route ships with web middleware and no auth. The most common real-world integration is:
'middleware' => ['web', 'auth', 'can:viewServerHealth'],
…or front it with an IP allowlist at the proxy and skip the middleware entirely. Either is fine; leaving it open is not.
Coexisting with Laravel's own health endpoint. Laravel ships /up (and the Health command in recent versions) for "is the app booting." Use servermonitor for the orthogonal question "is the host running out of runway." Don't duplicate one with the other.
Multi-host fleets. The package samples the machine it runs on. If you run three app servers, you get three independent alert streams — make sure the notification includes the hostname (check whether the published view/notification exposes gethostname(); if not, a one-line tweak to the published notification template saves you from alert emails that say "disk at 92%" with no idea which disk).
Programmatic invocation. Artisan::call('servermonitor:check') from a job or a post-deploy hook works, but prefer the scheduler — a check inside a queue worker measures the worker's container, which may not be the host you care about.
Complementary, not overlapping, tooling. Pair it with an external uptime pinger (for "the site is down") and Laravel Pulse/Telescope (for "this query is slow"). servermonitor covers the gap those two leave: slow-burn resource exhaustion.
7.0.0 is a compatibility major, not a feature release. The only change is Laravel 13 support. There are no new options, no deprecations, and no behavioral changes called out. Practical consequences:
^6.0.composer update; expect the constraint on illuminate/support (and PHP, likely 8.3+) to have moved up in lockstep.composer why-not sarfraznawaz2005/servermonitor 7.0.0 will tell you precisely which constraint is holding you back rather than making you guess from a resolver error wall.6.0.0 → 7.0.0 upgrade carries no migration risk beyond the framework upgrade itself. Verify by diffing composer.json in the tag rather than trusting the changelog — one line, total certainty.Alert spam is the number-one failure mode. The command alerts whenever a threshold is exceeded; run it every minute and a full disk generates 1,440 emails. Either schedule at everyTenMinutes()/hourly(), or wrap the check in a cache lock so a condition notifies once per cooldown window. Verify the notifier's own dedupe behavior before assuming it has any.
CPU load is a load average, not a percentage of capacity. A load of 4.0 is catastrophic on 1 vCPU and idle on 16. Any fixed default threshold is therefore wrong for most hosts — set it relative to nproc on the actual machine and revisit after any resize.
Containerized deployments lie about disks. Inside Docker the disk check reports the container's overlay filesystem, which is usually small and rarely the volume that actually fills up. If you run containers, mount the host path you care about or run the check as a sidecar against the host.
memory_limit ambiguity. Confirm whether the memory figure comes from PHP's memory_limit or from /proc/meminfo — they answer different questions and confuse people during incidents. Read the check's source once so you know which one appears in the alert.
Config cache. After editing thresholds: php artisan config:clear (or config:cache if that's your deploy step). A stale cached config silently running last week's numbers has burned many people, and it looks like "the package is broken."
Exit codes and scheduler noise. If the command returns non-zero on threshold breach (useful for && chaining), know that schedule:run will log it as a failure each time. withoutOverlapping() plus a deliberate exit-code policy keeps the logs readable.
Low-maintenance, single-maintainer project. No meaningful test suite, occasional multi-year gaps between releases (6.0.0 → 7.0.0 here). That's acceptable for a ~500-line alerting helper, but: read the source before depending on it, vendor-pin the version, and don't build anything critical that can't be replaced by a five-line disk_free_space() check if the package ever stalls. Treat it as a convenience, not infrastructure.
Extension points are just Laravel's. Publish the views to rebrand the dashboard; publish the config to change channels; if you need a custom channel (PagerDuty, Teams, Discord), bind your own notification or route the built-in one through Notification::route(). There's no plugin API — the escape hatch is always "copy the class into app/ and edit it."
How can I help you explore Laravel packages today?