sahlowle/larawatch

A Laravel application monitoring package β€” requests, exceptions, jobs, health checks, cache, mail, and scheduled tasks.

Maintainers

Package info

github.com/sahlowle/larawatch

Language:Blade

pkg:composer/sahlowle/larawatch

Transparency log

Statistics

Installs: 26

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.1.0 2026-07-23 09:24 UTC

This package is auto-updated.

Last update: 2026-07-23 09:29:14 UTC


README

Latest Version on Packagist PHP Laravel Livewire License

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 /larawatch to 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

Larawatch Dashboard

πŸ“„ License

The MIT License (MIT). See LICENSE for details.