Search by

devpulse / laravel

sekolahcode

DevPulse Laravel SDK — auto error capture for Laravel apps

v2.1.1 2026-08-21 01:30 UTC

This package is auto-updated.

Last update: 2026-08-21 01:31:04 UTC


README

Real-time error tracking for Laravel — self-hosted and free.

Requires a running DevPulse server v1.0+ and PHP 8.1+.

Installation

composer require devpulse/laravel

Publish the config:

php artisan vendor:publish --tag=devpulse-config

Configuration

Add to .env:

DEVPULSE_DSN=https://your-devpulse-host/api/ingest/YOUR_API_KEY
DEVPULSE_ENV=production
DEVPULSE_RELEASE=1.4.2        # or set APP_VERSION — falls back to git SHA

All options

Variable Default Description
DEVPULSE_DSN Ingest URL with API key (required)
DEVPULSE_ENABLED true Master on/off switch
DEVPULSE_ENV APP_ENV Environment name sent with events
DEVPULSE_RELEASE APP_VERSION / git SHA Release/version tag
DEVPULSE_ASYNC true Fire-and-forget HTTP (recommended)
DEVPULSE_TIMEOUT 2 HTTP timeout in seconds
DEVPULSE_SAMPLE_RATE 1.0 0.0–1.0 fraction of events to send
DEVPULSE_SLOW_QUERY_MS 1000 Slow query threshold (ms)
DEVPULSE_SLOW_REQUEST_MS 3000 Slow request threshold (ms)
DEVPULSE_MIN_LOG_LEVEL error Minimum log level to capture
DEVPULSE_USER_CONTEXT true Attach auth user to events
DEVPULSE_SLOW_REQUEST_IGNORE up,health,health*,_health* Comma-separated route names/paths to exclude from slow-request capture
DEVPULSE_ADMIN_TOKEN Only for devpulse:release — the dashboard admin token (see below)
DEVPULSE_PROJECT_ID Only for devpulse:release — this app's project UUID

Capture toggles

Variable Default Description
DEVPULSE_CAPTURE_EXCEPTIONS true Unhandled exceptions
DEVPULSE_CAPTURE_LOGS true Log::error() / Log::critical()
DEVPULSE_CAPTURE_SLOW_QUERIES true Slow DB queries
DEVPULSE_CAPTURE_SLOW_REQUESTS true Slow HTTP requests (requires middleware)
DEVPULSE_CAPTURE_QUEUE_FAILURES true Failed queue jobs
DEVPULSE_CAPTURE_COMMANDS true Artisan command failures (non-zero exit)

What's captured automatically

  • Exceptions — All unhandled exceptions (excluding ignored list)
  • Log::error / critical — Laravel log entries at error level or above
  • Slow queries — DB queries exceeding the threshold, plus all queries as breadcrumbs
  • Slow requests — HTTP requests exceeding the threshold (add middleware)
  • Queue failures — Failed jobs with queue, job class, and attempt count
  • Artisan failures — Commands that exit with a non-zero code
  • User context — Authenticated user ID, email, name (auto-detected)
  • Release — Version tag from DEVPULSE_RELEASE, APP_VERSION, or git SHA
  • Breadcrumbs — Last 20 queries and log entries attached to exceptions

Ignored exceptions

The following are never reported by default (add more in config/devpulse.php):

  • ValidationException
  • AuthenticationException
  • AuthorizationException
  • ModelNotFoundException
  • NotFoundHttpException
  • ThrottleRequestsException
  • TokenMismatchException

Slow request middleware

Register in app/Http/Kernel.php (Laravel 10) or bootstrap/app.php (Laravel 11+):

// Laravel 10 — app/Http/Kernel.php
protected $middleware = [
    \DevPulse\Laravel\Http\Middleware\DevPulseContext::class,
];

// Laravel 11 — bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    $middleware->append(\DevPulse\Laravel\Http\Middleware\DevPulseContext::class);
})

Health checks and monitoring endpoints hit on a tight interval by a load balancer don't need to show up as "slow requests." Exclude them by route name or path (wildcards supported) via DEVPULSE_SLOW_REQUEST_IGNORE or the slow_request_ignore config array — up and health* are excluded by default.

Manual capture

Every automatic capture (queries, logs, Livewire actions) is attached to the same per-request breadcrumb/context buffer these methods write to — add your own business context anywhere in your app and it rides along with whatever gets captured next, for the rest of the request:

use DevPulse\Laravel\DevPulseFacade as DevPulse;

// Breadcrumbs — recent activity leading up to an error
DevPulse::addBreadcrumb('user reached payment step', 'checkout');

// Tags — short, indexable key/value pairs
DevPulse::setTag('tenant', $tenant->slug);

// Context — a named group of structured data
DevPulse::setContext('checkout', ['cart_id' => $cart->id, 'total' => $cart->total]);
use DevPulse\Laravel\DevPulseFacade as DevPulse;

// Capture an exception manually
try {
    riskyOperation();
} catch (\Throwable $e) {
    DevPulse::capture($e, ['order_id' => $orderId]);
    throw $e;
}

// Capture a message
DevPulse::captureMessage('Payment gateway timeout', 'warning', [
    'gateway'     => 'stripe',
    'amount'      => $amount,
    'customer_id' => $customerId,
]);

Artisan commands

devpulse:test

Sends a real test event through your configured DSN, so you can confirm the connection works before waiting for a real error:

php artisan devpulse:test

devpulse:release

Registers a release with your DevPulse server so it shows up on the project's Releases timeline — run it as part of your deploy pipeline:

php artisan devpulse:release 1.4.2 --ref=$(git rev-parse HEAD) --url=https://ci.example.com/builds/123

This needs two extra values beyond the DSN: DEVPULSE_PROJECT_ID (this app's project UUID, visible in the dashboard URL) and DEVPULSE_ADMIN_TOKEN.

DEVPULSE_ADMIN_TOKEN is a more sensitive credential than your DSN. The DSN's API key can only submit events for one project; the admin token is the same one used to sign in to the DevPulse dashboard and grants access to every project on your DevPulse instance. Treat it like any other production secret — scope who can read the .env it lives in, don't commit it, rotate it like you would any other admin credential.

Testing

Use DevPulse::fake() to assert events in tests without hitting the server:

use DevPulse\Laravel\DevPulseFacade as DevPulse;

public function test_order_failure_is_tracked(): void
{
    $fake = DevPulse::fake();

    $this->post('/orders', ['invalid' => 'data']);

    $fake->assertCaptured(\App\Exceptions\PaymentFailedException::class);
}

public function test_slow_payment_is_reported(): void
{
    $fake = DevPulse::fake();

    // ... trigger slow payment ...

    $fake->assertCapturedMessage('Slow request');
}

public function test_healthy_request_sends_nothing(): void
{
    $fake = DevPulse::fake();

    $this->get('/health');

    $fake->assertNothingCaptured();
}

License

MIT