parkweb / ase-laravel
Laravel integration for All Seeing Eye.
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.0
- illuminate/contracts: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- monolog/monolog: ^3.0
- nyholm/psr7: ^1.8
- parkweb/ase-php: ^0.1.4
- php-http/discovery: ^1.20
README
Laravel integration for All Seeing Eye.
composer require parkweb/ase-laravel php-http/discovery guzzlehttp/guzzle nyholm/psr7 php artisan vendor:publish --tag=ase-config
If you installed an earlier local path version, run:
composer update parkweb/ase-php parkweb/ase-laravel guzzlehttp/guzzle nyholm/psr7 php-http/discovery php artisan optimize:clear
Configure:
ASE_TOKEN=sk_ase_full_server_token ASE_ENDPOINT=https://api-ase.parkwebit.nl/api/v1/ingest/envelope ASE_ENABLED=true ASE_RELEASE=${APP_VERSION} ASE_ENVIRONMENT=production ASE_DEPLOY_ID=${FORGE_DEPLOYMENT_ID} ASE_TRANSPORT=queue ASE_QUEUE=ase ASE_DEBUG=false
Request telemetry can be disabled completely:
ASE_TRACE_REQUESTS=false
Or keep request telemetry enabled but ignore noisy routes. Livewire update endpoints are ignored by default:
ASE_TRACE_REQUEST_IGNORED_PATHS=api/v1/ingest/*,livewire/update,livewire/message/*
Use Laravel request path patterns without a leading slash. For example admin/* or livewire/update.
Config file:
return [ 'dsn' => env('ASE_DSN'), 'token' => env('ASE_TOKEN'), 'endpoint' => env('ASE_ENDPOINT', 'https://api-ase.parkwebit.nl/api/v1/ingest/envelope'), 'enabled' => env('ASE_ENABLED', true), 'release' => env('ASE_RELEASE'), 'capture_warnings' => true, 'send_default_pii' => false, 'sample_rate' => 1.0, ];
ASE_DSN is still supported for older installs. For new Laravel installs, prefer ASE_TOKEN + ASE_ENDPOINT.
What is captured automatically:
- unhandled HTTP exceptions and fatal shutdown errors;
- exceptions reported through Laravel's exception handler;
- warnings when
capture_warningsis enabled; - authenticated user id/email;
- request URL, method and route;
- request id when present in request context;
- Laravel version, PHP version, environment, release and deploy id;
- queue failures with job metadata;
- command/scheduler failures via failed command exit codes.
Transport note:
ASE_TRANSPORT=syncsends during the request and is easiest for testing.ASE_TRANSPORT=queueonly sends when anasequeue worker is running.
Debugging delivery
Start with sync transport:
ASE_TRANSPORT=sync ASE_DEBUG=true
Clear config and send a test event:
php artisan optimize:clear php artisan ase:test php artisan ase:test --exception
If ASE rejects the event, check storage/logs/laravel.log for:
ASE transport rejected event batch
Common causes:
- DSN host points to the wrong API domain.
ASE_TOKENuses a database ULID like01...instead of the full server token.- The server key is revoked or expired.
ASE_TRANSPORT=queueis configured but no queue worker is running.- API returns
422because the installed SDK package is stale.
Safety:
- ASE failures never crash the Laravel app.
- Authorization, cookie and CSRF headers are never sent.
- Request bodies are not sent by default.
- The ASE queue job is guarded against recursive queue failure capture.
- Use
ASE_TRANSPORT=queuefor production web requests.
Laravel Forge deploy snippet:
export ASE_RELEASE="$(git rev-parse --short HEAD)" export ASE_DEPLOY_ID="${FORGE_DEPLOYMENT_ID:-$(date +%s)}" php artisan config:cache php artisan queue:restart
Queue worker:
php artisan queue:work --queue=ase,default --tries=3 --timeout=30
Scheduler/cron:
* * * * * cd /home/forge/example.com && php artisan schedule:run >> /dev/null 2>&1
Manual capture:
use ParkWeb\Ase\Ase; use ParkWeb\Ase\Level; Ase::setTag('tenant', 'acme'); Ase::captureMessage('Checkout degraded', Level::Warning); Ase::captureException($throwable);
Laravel logging channel
Add an ASE channel to config/logging.php:
'channels' => [ 'ase' => [ 'driver' => 'custom', 'via' => ParkWeb\Ase\Laravel\Logging\AseLogger::class, 'level' => env('ASE_LOG_LEVEL', 'warning'), 'bubble' => true, ], ],
Use it directly:
Log::channel('ase')->warning('Checkout latency is high', [ 'tenant' => 'acme', 'duration_ms' => 1840, ]); Log::channel('ase')->error('Payment failed', [ 'exception' => $throwable, ]);
Or add it to an existing stack:
'stack' => [ 'driver' => 'stack', 'channels' => ['single', 'ase'], 'ignore_exceptions' => false, ],
The log channel maps Laravel/Monolog levels to ASE levels and sends context as extra. Add ['ase_skip' => true] to a log context if you explicitly want to avoid ASE capture for that record.