Looking to hire Laravel developers? Try LaraJobs

laravel maintained by stackwarden

Description
Official Laravel SDK for Stackwarden with automatic instrumentation
Author
Last update
2026/08/06 10:29 (dev-main)
License
Downloads
0

Comments
comments powered by Disqus

Stackwarden for Laravel

Official Laravel SDK for Stackwarden — self-hostable error monitoring with issues, traces, logs, and metrics.

Requires PHP 8.1+ and Laravel 10 / 11 / 12 / 13.

Features

Signal Automatic Manual
Issues / events Unhandled exceptions, failed queue jobs captureException, captureMessage
Traces HTTP requests + SQL spans (when enabled) startTransaction / finishTransaction
Logs Laravel log lines → Explore (when enabled) captureLog
Metrics http.request.duration (when enabled) captureMetric

Also: SQL / HTTP / auth / queue breadcrumbs, request + user context, deferred sending so ingest does not block the response.

Install

composer require stackwarden/laravel

Capture unhandled exceptions

Laravel 11+bootstrap/app.php:

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Stackwarden\Integration;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withExceptions(function (Exceptions $exceptions) {
        Integration::handles($exceptions);
    })->create();

Laravel 10app/Exceptions/Handler.php:

public function register(): void
{
    $this->reportable(function (Throwable $e) {
        \Stackwarden\Integration::captureUnhandledException($e);
    });
}

Configure (Docker Stackwarden)

Stackwarden is normally run with the Docker install:

curl -fsSL https://stackwarden.mysticastra.org/install.sh | bash
# optional: export WEB_PORT=8001 before running

That compose stack does not publish the API on host :3000. The web container proxies /v1/* to the API, so the SDK must use the same public URL as the dashboard.

How you installed SDK base URL (example)
WEB_PORT=8001 (common local) http://127.0.0.1:8001
Default WEB_PORT=80 http://127.0.0.1 or http://localhost
HTTPS reverse proxy https://errors.example.com
  1. Open the dashboard → your project → Settings → Keys → create/copy a project key (sw_…).
  2. Point the Laravel app at that host + key:
# WEB_PORT=8001 example
php artisan stackwarden:publish --dsn="http://sw_YOUR_PROJECT_KEY@127.0.0.1:8001"

Or in .env:

# Preferred — key + host in one value (http for local Docker, https in production)
STACKWARDEN_DSN=http://sw_YOUR_PROJECT_KEY@127.0.0.1:8001

# Equivalent split form:
# STACKWARDEN_BASE_URL=http://127.0.0.1:8001
# STACKWARDEN_PROJECT_KEY=sw_YOUR_PROJECT_KEY

The SDK posts to {base}/v1/ingest/events (and /traces, /logs, /metrics). Do not use http://localhost:3000 unless you intentionally published the API container port yourself.

Verify

php artisan stackwarden:test
php artisan stackwarden:test --all   # event + sample trace / log / metric

Then open the same host in the browser (e.g. http://127.0.0.1:8001) and check Issues / Explore.

Throw a test exception from a route:

Route::get('/debug-stackwarden', function () {
    throw new RuntimeException('My first Stackwarden error');
});

Configuration

Published file: config/stackwarden.php.

Core

Env Default Description
STACKWARDEN_DSN http(s)://sw_…@host[:port] (preferred)
STACKWARDEN_BASE_URL http://localhost Dashboard/API origin if not using DSN (Docker public URL)
STACKWARDEN_PROJECT_KEY Project key if not embedded in DSN
STACKWARDEN_ENVIRONMENT APP_ENV Event / span / log environment
STACKWARDEN_RELEASE Release label
STACKWARDEN_SAMPLE_RATE 1.0 Error event sample rate (0–1)
STACKWARDEN_TRANSPORT buffered buffered | queue | sync
STACKWARDEN_SEND_DEFAULT_PII false Include email, IP, cookies, body

Explore signals (off by default)

Env Default Description
STACKWARDEN_TRACES_SAMPLE_RATE 0 >0 enables HTTP + SQL tracing
STACKWARDEN_ENABLE_LOGS false Forward Laravel logs to Explore
STACKWARDEN_ENABLE_METRICS false Emit request duration metrics
STACKWARDEN_TRACE_SQL true SQL child spans when tracing

Example with local Docker on port 8001:

STACKWARDEN_DSN=http://sw_…@127.0.0.1:8001
STACKWARDEN_TRANSPORT=buffered
STACKWARDEN_TRACES_SAMPLE_RATE=1.0
STACKWARDEN_ENABLE_LOGS=true
STACKWARDEN_ENABLE_METRICS=true

Production behind HTTPS:

STACKWARDEN_DSN=https://sw_…@errors.example.com
STACKWARDEN_TRANSPORT=buffered
STACKWARDEN_TRACES_SAMPLE_RATE=0.2
STACKWARDEN_ENABLE_LOGS=true
STACKWARDEN_ENABLE_METRICS=true
STACKWARDEN_RELEASE=1.4.2

Transport

Mode Behavior
buffered (default) Queue in memory; flush after the HTTP response / process shutdown. Does not block the user on the ingest HTTP call.
queue Dispatch SendPayloadJob to your Laravel queue worker. Set STACKWARDEN_QUEUE / STACKWARDEN_QUEUE_CONNECTION if needed.
sync POST immediately (debug only — adds latency).

Usage

Exceptions & messages

use Stackwarden\Facade as Stackwarden;
use function Stackwarden\captureException;

try {
    risky();
} catch (Throwable $e) {
    Stackwarden::captureException($e);
    // or: captureException($e);
}

Stackwarden::captureMessage('Something noteworthy', 'warning');

Scope (tags, user, breadcrumbs)

use Stackwarden\Breadcrumb;
use Stackwarden\Facade as Stackwarden;

Stackwarden::configureScope(function ($scope) {
    $scope->setTag('tenant', 'acme');
    $scope->setUser(['id' => (string) auth()->id()]);
});

Stackwarden::addBreadcrumb(Breadcrumb::make(
    message: 'Checkout started',
    category: 'ui',
    level: 'info',
));

Traces

$tx = Stackwarden::startTransaction('POST /checkout', 'http.server');
$span = $tx?->startChild('db.query', 'load cart', 'SELECT …');
$span?->finish();
Stackwarden::finishTransaction('ok');

With STACKWARDEN_TRACES_SAMPLE_RATE > 0, each web request already starts an HTTP transaction; SQL queries become child spans when STACKWARDEN_TRACE_SQL=true.

Explore logs & metrics

Stackwarden::captureLog('Order placed', 'info', ['order_id' => '42']);
Stackwarden::captureMetric('checkout.latency', 12.5, 'ms', ['route' => 'checkout']);
Stackwarden::flush(); // push buffered logs/metrics (also runs after each request)

Log channel (issues from Monolog)

In config/logging.php:

'stackwarden' => [
    'driver' => 'monolog',
    'handler' => \Stackwarden\Logging\LogsHandler::class,
    'level' => env('STACKWARDEN_LOGS_LEVEL', 'error'),
],

Or:

'stackwarden' => [
    'driver' => 'custom',
    'via' => \Stackwarden\Logging\LogChannel::class,
    'level' => 'error',
],

This reports to issues (event ingest). Explore log shipping is controlled by STACKWARDEN_ENABLE_LOGS.

What is automated

Out of the box (once configured + Integration::handles):

  • Unhandled exceptions reported as events
  • Failed queue jobs (Queue::failing), except the SDK’s own send job
  • Request URL / method / headers attached to events
  • Authenticated user id (and email/IP only if SEND_DEFAULT_PII)
  • Breadcrumbs: queries, logs, HTTP client, queue, auth login
  • Optional: traces, Explore logs, request metrics (see env flags above)
  • Flush on middleware terminate and PHP shutdown

Development

composer dump-autoload
php tests/self_check.php

License

MIT — see LICENSE.