sahlowle / larawatch
A Laravel application monitoring package β requests, exceptions, jobs, health checks, cache, mail, and scheduled tasks.
Package info
Language:Blade
pkg:composer/sahlowle/larawatch
Requires
- php: ^8.2
- dragonmantank/cron-expression: ^3.0
- illuminate/support: ^11.0|^12.0
- livewire/livewire: ^3.0|^4.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- orchestra/testbench: ^9.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
README
A beautiful, self-hosted Laravel application monitoring dashboard
Track HTTP requests, exceptions, queue jobs, health checks, cache stats, mail, and scheduled tasks β all without any external service.
β¨ Features
| Module | What it tracks |
|---|---|
| π Requests | Every HTTP request β method, path, status, duration, IP |
| π₯ Exceptions | PHP exceptions grouped by hash, with full stack traces |
| βοΈ Queue Jobs | Job processing, completion, and failures |
| β€οΈ Health Checks | Database, Redis, Queue, Storage, Mail, Scheduler |
| ποΈ Cache | Hit rate, memory usage, key count (Redis) |
| π§ Mail | Sent and failed emails with recipients and size |
| π Scheduled Tasks | Task start, finish, skip, and failure events |
π Requirements
- PHP 8.2+
- Laravel 11.x / 12.x
- Livewire 3.x / 4.x
π Installation
1. Install via Composer
composer require sahlowle/larawatch
2. Publish the config file
php artisan vendor:publish --tag="larawatch-config"
3. Run the migrations
php artisan migrate
4. Record exceptions
Add the following to your bootstrap/app.php:
->withExceptions(function (Exceptions $exceptions): void { $exceptions->reportable(function (\Throwable $e): void { if (config('larawatch.enabled') && config('larawatch.features.exceptions', true)) { try { app(\Sahlowle\Larawatch\Services\ExceptionMonitorService::class)->record($e); } catch (\Throwable $ignored) { // Never let monitoring break the app. } } }); })
β That's it! Visit
/larawatchto see your dashboard.
βοΈ Configuration
After publishing, edit config/larawatch.php:
return [ // Enable/disable Larawatch 'enabled' => env('LARAWATCH_ENABLED', true), // Dashboard theme: "dark" or "light" 'theme' => env('LARAWATCH_THEME', 'light'), // URL prefix for the dashboard (default: /larawatch) 'path' => env('LARAWATCH_PATH', 'larawatch'), // Optional database connection and table prefix 'connection' => env('LARAWATCH_DB_CONNECTION', null), 'table_prefix' => env('LARAWATCH_TABLE_PREFIX', 'larawatch_'), // Require a viewLarawatch gate in production 'require_auth_in_production' => env('LARAWATCH_REQUIRE_AUTH_IN_PRODUCTION', false), // Restrict access by email or role 'allowed_emails' => ['admin@example.com'], 'allowed_roles' => ['admin'], // Toggle individual modules 'features' => [ 'requests' => true, 'exceptions' => true, 'jobs' => true, 'health' => true, 'cache' => true, 'mail' => true, 'scheduled_tasks' => true, ], // Queue payloads may contain sensitive data, so recording is opt-in 'jobs' => [ 'record_payload' => false, ], 'exceptions' => [ 'trace_max_length' => 65535, ], // Paths that should not be recorded by request monitoring 'request' => [ 'ignore_paths' => ['larawatch*', '_debugbar*', 'telescope*', 'horizon*', 'livewire*'], 'ignore_status_codes' => [], 'slow_threshold_ms' => 1000, ], 'health' => [ 'checks' => ['database', 'redis', 'queue', 'storage', 'mail', 'scheduler'], 'scheduler_stale_after_minutes' => 5, ], // How long to keep data 'data_retention' => [ 'requests' => ['keep_hours' => 1], 'exceptions' => ['keep_days' => 30], 'jobs' => ['keep_days' => 7], 'health_checks' => ['keep_days' => 7], 'cache_stats' => ['keep_days' => 7], 'mails' => ['keep_days' => 30], 'scheduled_tasks' => ['keep_days' => 14], ], ];
Environment Variables
| Variable | Default | Description |
|---|---|---|
LARAWATCH_ENABLED |
true |
Enable or disable the entire package |
LARAWATCH_THEME |
light |
Dashboard theme (dark / light) |
LARAWATCH_PATH |
larawatch |
URL prefix for the dashboard |
LARAWATCH_DB_CONNECTION |
null |
Separate DB connection for Larawatch tables |
LARAWATCH_TABLE_PREFIX |
larawatch_ |
Prefix for all Larawatch database tables |
LARAWATCH_REQUIRE_AUTH_IN_PRODUCTION |
false |
Require the viewLarawatch gate in production |
π Authorization
Larawatch can require an authorization gate to be registered when the application is running in production:
LARAWATCH_REQUIRE_AUTH_IN_PRODUCTION=true
When enabled, LarawatchAuthMiddleware returns a 403 response in production if Laravel does not have a viewLarawatch gate:
if ( config('larawatch.require_auth_in_production', false) && App::isProduction() && ! Gate::has('viewLarawatch') ) { abort(403); }
Larawatch registers a default viewLarawatch gate using allowed_emails and allowed_roles. In any non-production environment, the default gate permits access without requiring an authenticated user. In production, access is restricted to authenticated users matching an allowed email or role. You can replace the gate in your application's AppServiceProvider:
use Illuminate\Support\Facades\Gate; Gate::define('viewLarawatch', function ($user) { return $user->is_admin; });
After confirming that the gate exists, the middleware calls Gate::allows('viewLarawatch') and returns 403 when access is denied. Larawatch does not currently provide a separate authorization-callback API.
β±οΈ Scheduled collection
Add the Larawatch collectors to routes/console.php:
use Illuminate\Support\Facades\Schedule; Schedule::command('larawatch:health-check')->everyMinute(); Schedule::command('larawatch:collect-cache-stats')->everyFiveMinutes(); Schedule::command('larawatch:prune --force')->daily();
The scheduler heartbeat is updated whenever a scheduled task starts.
ποΈ Pruning Old Data
The package provides the larawatch:prune command to clean up old records. Add it to your routes/console.php scheduler:
// Prune all types according to their configured retention Schedule::command('larawatch:prune --force')->daily(); // Or prune a specific type Schedule::command('larawatch:prune --type=requests --force')->hourly();
Available types: requests, exceptions, jobs, health_checks, cache_stats, mails, scheduled_tasks
πΊοΈ Dashboard Routes
| URL | Description |
|---|---|
/larawatch |
Main dashboard |
/larawatch/requests |
HTTP request log |
/larawatch/exceptions |
Exception tracker |
/larawatch/jobs |
Queue job history |
/larawatch/health |
Health checks |
/larawatch/cache |
Cache & memory stats |
/larawatch/mail |
Mail monitor |
/larawatch/scheduled-tasks |
Scheduled task history |
/larawatch/api/chart-data |
JSON chart data endpoint |
π¦ Publishing Assets
# Config only php artisan vendor:publish --tag="larawatch-config" # Migrations only php artisan vendor:publish --tag="larawatch-migrations" # Views (to customize the dashboard UI) php artisan vendor:publish --tag="larawatch-views"
Screenshot
π License
The MIT License (MIT). See LICENSE for details.
