orchid/monitor
Monitor your Laravel application from inside the Orchid admin panel. orchid/monitor gathers health checks, server metrics, logs, and runtime performance into one dashboard, so you can spot issues early and keep your app running reliably without switching between tools or services.
Confirm you already run Orchid before you touch this. orchid/monitor is not a package you composer require on its own — it is the system-information screen bundled inside orchid/platform (the repo is the theOrchid/Platform monorepo). If Orchid is not already your admin panel, stop: adopting an admin framework to get a CPU gauge inverts the cost/benefit. Start by checking what is installed:
composer show orchid/platform # note the exact version
php artisan route:list | grep -i monitor
Read the vendor source before trusting the docs. Package-level documentation is thin because this ships as a module of a monorepo. The fastest orientation is the source itself:
grep -rn "class Monitor" vendor/orchid/platform/src/
grep -rn "function cpu\|function ram\|function disk" vendor/orchid/platform/src/
You are looking for the Monitor service (exposing cpu(), ram(), disk()) and the Orchid screen class that renders it. Read both — that is your real API contract, and its shape drifts between Orchid majors.
First use case — validate against the shell. Log in as an admin and open the monitor route (conventionally /admin/monitor, also reachable from the platform navigation). Before showing anyone, SSH into the same host and compare:
top -bn1 | head -20
free -m
df -h
If the screen diverges from the shell, you have found either a disable_functions problem or a container-view problem — both covered below. Do this on a production-like Linux box, never on your macOS laptop, where top/free flags behave differently and the readings are meaningless.
Then lock it down before the first non-you login. This endpoint fingerprints the host. Confirm the route carries your real guards, not just panel defaults, and restrict it to a trusted role through Orchid's permission system.
1. Read-only operator screen (the default, and usually enough). Do nothing. It appears in the panel menu for admins. The day-to-day value is: after a deploy or a latency complaint, glance and see whether the box is pinned. That is the whole feature. Don't build on it until you've used it for a week and know whether operators actually open it.
2. Embed the gauges on a screen operators already use. If your team lives on a custom Orchid screen, call the Monitor service from query() and render metrics via Orchid's layout, so health context sits next to the data it explains with no context switch.
// app/Orchid/Screens/OrdersScreen.php — illustrative, verify the service signature against your version
public function query(Monitor $monitor): iterable
{
return [
'cpu' => Cache::remember('monitor.cpu', 30, fn () => $monitor->cpu()),
'ram' => Cache::remember('monitor.ram', 30, fn () => $monitor->ram()),
'disk' => Cache::remember('monitor.disk', 60, fn () => $monitor->disk()),
];
}
Cache the values. Every call shells out; a screen refresh should not fork top three times.
3. JSON polling endpoint for a dashboard widget. Expose a small, guarded route and let a front-end widget poll it. Keep the interval at five seconds minimum — each poll spawns a process, and a tight interval across several open admin tabs is a self-inflicted load source.
Route::middleware(config('platform.middleware'))
->get('/admin/api/monitor', fn () => response()->json([
'cpu' => Cache::remember('monitor.cpu', 10, fn () => app(Monitor::class)->cpu()),
'disk' => Cache::remember('monitor.disk', 60, fn () => app(Monitor::class)->disk()),
]));
4. Disk assertion as a pre-flight deploy gate. The highest-value non-UI use. A scheduled command or deploy-script check that fails loudly when the volume is near full catches the class of incident where deploys fail for reasons nobody can see.
// app/Console/Commands/AssertDiskHeadroom.php
$used = app(Monitor::class)->disk(); // verify: percentage vs. bytes
if ($used > 90) {
$this->error("Disk at {$used}% — aborting deploy.");
return self::FAILURE;
}
return self::SUCCESS;
Pair it with a scheduled notification so it fires before the page is what tells you.
5. Extend with your own monitor classes, not vendor patches. For queue lag, failed-job counts, or last-migration time, write small classes in app/Support/Monitors/ returning the same shape as the core Monitor, and render them on your own screen. Leave the vendor class untouched — that keeps your fork-or-replace exit intact.
6. Override presentation only. For layout or branding changes, publish views and edit the published copy; never edit vendor/.
php artisan vendor:publish --tag=platform-views
7. Fill the gaps with the right tool, explicitly. Pair the page with Horizon for queues, Telescope in development, and Sentry or a hosted APM for anything needing retention or paging. Put that in writing next to the rollout, so nobody reads "Monitor" as "monitoring."
exec/proc_open/shell_exec are disabled (common on hardened PHP-FPM images), the screen renders 0 or an empty gauge rather than erroring. Check disable_functions, and run php -r 'var_dump(function_exists("exec"));' in the production runtime. A zero that looks like "idle" is the dangerous failure mode./proc and df report the container's view. A container with a 10 GB overlay showing "90% full" says nothing about the node, and memory figures ignore cgroup limits unless you read them yourself. Treat these numbers as container-scoped and label them that way in the UI.df can hang with no timeout knob. A stale NFS mount can block the request indefinitely, and there is no package-level timeout. Wrap any polling or auto-refresh in your own Process with an explicit timeout, and on NFS hosts know which mounts are at risk.config('platform.middleware'). Broad admin access to this page is an information-disclosure finding, not cosmetics. Restrict by Orchid role, and re-review whenever the permission model changes.orchid/platform to a tested tag, never a floating constraint, and treat every Orchid upgrade as a trigger to regression-check the monitor route, permissions, and output.php artisan route:list | grep monitor to confirm registration and middleware; (2) resolve the service in Tinker and call cpu() directly, separating service failure from view failure; (3) run the equivalent shell command on the host; (4) confirm you are on the host you think you are.How can I help you explore Laravel packages today?