Laravel SDK
Server-side error tracking for Laravel with auto-discovery, middleware, query tracking, Monolog channel, and performance monitoring.
Comprehensive error monitoring for Laravel applications
Integrates with Laravel exception handler via reportable()
Built-in HTTP middleware for request/response tracking
Track events leading up to an error for better context
Automatic breadcrumbs and slow query detection via QueryExecuted
Associate errors with authenticated Laravel users automatically
Use Log::channel('abrovatrace') for structured logging
Track HTTP requests, DB queries, and custom operations
Installation#
The package comes from Abrova Center. Two steps:
1. Add the Abrova repository to your composer.json:
"repositories": [
{ "type": "composer", "url": "https://center.abrova.ir/api/packages/abrova/composer" }
]2. Install the package:
composer require abrova-trace/laravel-sdk
Publish the configuration file:
php artisan vendor:publish --tag=abrovatrace-config
Quick Start#
Add your credentials to .env:
ABROVATRACE_API_KEY=ab_live_your_api_key_here ABROVATRACE_SERVER_SECRET=ab_srv_your_server_secret_here ABROVATRACE_ENVIRONMENT=production ABROVATRACE_RELEASE=1.0.0
The SDK uses Laravel package auto-discovery. No manual registration of service providers or facades is needed. The facade is AbrovaTrace\Laravel\AbrovaTraceFacade (auto-aliased as AbrovaTrace). The SDK stays inactive until both ABROVATRACE_API_KEY and ABROVATRACE_SERVER_SECRET are set.
Capture Errors#
Automatic Capture
All unhandled exceptions are automatically captured via Laravel's exception handler. No code changes needed.
The exception is still written to your application's own log (laravel.log or your configured log channels), so you do not need to change your logging setup. Versions before 0.2.3 stopped Laravel's default logging for captured exceptions.
Manual Capture
use AbrovaTrace\Laravel\AbrovaTraceFacade as AbrovaTrace;
// Capture an exception
try {
riskyOperation();
} catch (\Throwable $e) {
AbrovaTrace::captureException($e, [
'extra' => ['userId' => 123, 'feature' => 'checkout'],
]);
}
// Capture a message
AbrovaTrace::captureMessage('User completed checkout', [
'extra' => ['orderId' => 'ORD-456'],
]);
// With a level and tags ('debug', 'info' (default), 'warning', 'error')
AbrovaTrace::captureMessage('Payment retried', [
'level' => 'warning',
'tags' => ['feature' => 'checkout'],
]);The same exception is reported once. If you capture it with captureException() and then rethrow it, the automatic capture does not send it a second time (since 0.2.3).
Messages appear in the Console under Abrova Trace → Messages, with their level, platform, extra data and breadcrumbs. They never create an issue. 'warn' is sent as warning; 'fatal', 'critical', 'alert' and 'emergency' as error; 'trace' as debug; anything else as info. Use messages for things your app reports on purpose ("checkout started", "sync finished"); for high-volume diagnostics use Logs.
Breadcrumbs#
Breadcrumbs track events leading up to an error. HTTP requests and database queries are tracked automatically.
Manual Breadcrumbs
use AbrovaTrace\Laravel\AbrovaTraceFacade as AbrovaTrace;
use AbrovaTrace\Laravel\Models\Breadcrumb;
// HTTP breadcrumb
AbrovaTrace::addBreadcrumb(Breadcrumb::http('POST', '/api/orders', 201, 150.5));
// Database breadcrumb
AbrovaTrace::addBreadcrumb(Breadcrumb::database('SELECT * FROM users WHERE id = ?', 12.5));
// User action breadcrumb
AbrovaTrace::addBreadcrumb(Breadcrumb::user('clicked_checkout', ['cartTotal' => 99.99]));
// Custom breadcrumb
AbrovaTrace::addBreadcrumb(Breadcrumb::custom('Cache cleared', 'cache', ['keys' => 15]));The SDK automatically records HTTP request/response breadcrumbs via middleware and database query breadcrumbs via the QueryExecuted event listener. No manual setup required.
User Context#
User context is automatically extracted from authenticated users via middleware. You can also set it manually:
AbrovaTrace::setUser([
'id' => 123,
'email' => 'user@example.com',
'username' => 'john_doe',
]);Scoped Context#
Use scoped context to isolate user and request context per operation. Both are automatically restored afterward (breadcrumbs added inside the closure are kept). The closure receives the SDK instance.
AbrovaTrace::withScope(function ($scope) {
$scope->setUser(['id' => 456]);
$scope->setRequestContext(['operation' => 'bulk_import']);
$scope->addBreadcrumb(Breadcrumb::custom('Starting import', 'import'));
// Errors captured here include this context
AbrovaTrace::captureException(new \RuntimeException('Import failed'));
});
// Context is restored after the closureLaravel Middleware#
The middleware is automatically registered on web and api groups. It provides:
- Request Tracking — Records the incoming request as a breadcrumb (method and path) and sets request context (method, URL, path, route, IP, user agent)
- Response Tracking — Records response breadcrumb with status code and duration
- User Extraction — Automatically sets user context (id, email, name) from the authenticated user (
middleware.track_user) - Performance Spans — Creates an HTTP performance span for every request (when
performance.enabledis true)
To customize ignored paths, edit config/abrovatrace.php:
'middleware' => [
'enabled' => true,
'ignored_paths' => [
'health',
'api/health',
'_debugbar/*',
'telescope/*',
],
],Database Query Tracking#
Database queries are automatically tracked via Laravel's QueryExecuted event (performance.track_db_queries). Every query becomes a breadcrumb; queries at or above the threshold (default 500ms) also generate performance spans.
// config/abrovatrace.php
'performance' => [
'enabled' => true,
'track_db_queries' => true,
'slow_query_threshold_ms' => 100, // Span for queries taking 100ms or more
],Monolog Log Channel#
Send logs to AbrovaTrace using Laravel's built-in logging system:
// config/logging.php
'channels' => [
'abrovatrace' => [
'driver' => 'custom',
'via' => AbrovaTrace\Laravel\Logging\AbrovaTraceLogChannel::class,
],
],use Illuminate\Support\Facades\Log;
Log::channel('abrovatrace')->info('User signed up', ['userId' => 123]);
Log::channel('abrovatrace')->error('Payment failed', ['orderId' => 'ORD-456']);
Log::channel('abrovatrace')->warning('Rate limit approaching', ['remaining' => 5]);You can add abrovatrace to a stack channel to send logs to multiple destinations simultaneously.
See Laravel SDK Logging for batching behavior, log levels, and manual flush.
Performance Tracking#
use AbrovaTrace\Laravel\AbrovaTraceFacade as AbrovaTrace;
use AbrovaTrace\Laravel\Performance\PerformanceSpan;
// Track a custom operation with automatic timing
$result = AbrovaTrace::trackOperation('cache.rebuild', function () {
return rebuildCache();
}, ['tags' => ['cache' => 'products']]);
// Manual performance span
AbrovaTrace::reportPerformanceSpan(PerformanceSpan::custom([
'operation' => 'email.send',
'durationMs' => 250.5,
'startTime' => now()->subMilliseconds(250),
'tags' => ['mailer' => 'smtp'],
]));Configuration Options#
// config/abrovatrace.php
return [
'api_key' => env('ABROVATRACE_API_KEY', ''),
'server_secret' => env('ABROVATRACE_SERVER_SECRET', ''),
'enabled' => env('ABROVATRACE_ENABLED', true),
'environment' => env('ABROVATRACE_ENVIRONMENT', env('APP_ENV', 'production')),
'release' => env('ABROVATRACE_RELEASE', '0.1.0'),
'sample_rate' => env('ABROVATRACE_SAMPLE_RATE', 1.0),
'before_send' => null, // set a closure from a service provider
'debug' => env('ABROVATRACE_DEBUG', false),
'timeout' => env('ABROVATRACE_TIMEOUT', 5),
'max_breadcrumbs' => 50,
];| Option | Type | Required | Description |
|---|---|---|---|
| api_key | string | Yes | Your project API key (ab_live_xxx) |
| server_secret | string | Yes | Your server secret (ab_srv_xxx) |
| enabled | boolean | No | Enable/disable tracking (default: true) |
| environment | string | No | Environment name (default: APP_ENV, else "production") |
| release | string | No | App version identifier (default: "0.1.0") |
| sample_rate | float | No | Sample rate for errors and messages, 0.0-1.0 (default: 1.0) |
| before_send | callable | No | Receives each error (AbrovaTraceError) or message (AbrovaTraceMessage); return it (or a modified one) to send, null to drop. Set it from a service provider, since a closure cannot live in a cached config |
| debug | boolean | No | Enable debug logging (default: false) |
| timeout | integer | No | HTTP timeout in seconds (default: 5, max: 30) |
| max_breadcrumbs | integer | No | Max breadcrumbs to keep, 0-100 (default: 50) |
Ignored Exceptions#
The SDK ships with sensible defaults for exceptions Laravel apps typically don't want as errors. By default these are not reported:
AuthenticationException— unauthenticated requestsValidationException— form validation failuresNotFoundHttpException— 404s- All 4xx HTTP exceptions
Customize via config/abrovatrace.php:
'exception_handler' => [
'ignored_exceptions' => [
\App\Exceptions\BusinessException::class,
],
'report_4xx' => true,
],The ignored_exceptions list you set replaces the default one, so keep the default entries you still want ignored.
4xx responses are client errors — duplicating them as exceptions makes the error feed noisy. Flip report_4xx to true if you genuinely want them captured (e.g. for analytics).
API Reference#
AbrovaTrace Facade
captureException($e, $options?)— Capture an exceptioncaptureMessage($msg, $options?)— Send a message to Abrova Trace → Messages ($options:level,extra,tags)addBreadcrumb($breadcrumb)— Add a breadcrumbsetUser($user)— Set user contextsetRequestContext($context)— Set request contextwithScope($callback)— Run code with isolated user/request contextlog($message, $level?, $metadata?)— Send a log entry (user id comes fromsetUser())trace(),logDebug(),info(),warn(),logError(),fatal()— Log at a level ($message, $metadata?)trackOperation($name, $callback, $options?)— Track operation with auto-timing ($options:operationType,tags)reportPerformanceSpan($span)— Report a performance spanflush()— Flush buffered logs and performance spans (also runs automatically at shutdown)isEnabled()— Check if SDK is enabledgetStats()— Get SDK statistics
Breadcrumb Helpers
Breadcrumb::http($method, $url, $status?, $duration?)— HTTP request breadcrumbBreadcrumb::database($query, $duration, $error?)— Database query breadcrumbBreadcrumb::user($action, $data?)— User action breadcrumbBreadcrumb::navigation($from, $to, $method?)— Navigation breadcrumbBreadcrumb::custom($message, $category, $data?)— Custom breadcrumb
Requirements#
- PHP — >= 8.1
- Laravel — 10.x / 11.x / 12.x
- Guzzle — >= 7.0 (ships with Laravel)
Complete Example#
// routes/api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Log;
use AbrovaTrace\Laravel\AbrovaTraceFacade as AbrovaTrace;
use AbrovaTrace\Laravel\Models\Breadcrumb;
Route::get('/users/{id}', function ($id) {
// Add a breadcrumb (DB queries are tracked automatically)
AbrovaTrace::addBreadcrumb(Breadcrumb::user('view_user', [
'userId' => $id,
]));
try {
$user = User::findOrFail($id);
return response()->json($user);
} catch (\Throwable $e) {
AbrovaTrace::captureException($e, [
'extra' => ['userId' => $id],
]);
return response()->json(['error' => 'User not found'], 404);
}
});
// Log via Monolog channel
Route::post('/orders', function (Request $request) {
$order = Order::create($request->validate([
'total' => 'required|numeric',
]));
Log::channel('abrovatrace')->info('Order created', [
'orderId' => $order->id,
'amount' => $order->total,
]);
// Track performance of external API call
$result = AbrovaTrace::trackOperation('payment.process', function () use ($order) {
return PaymentGateway::charge($order);
});
return response()->json($result);
});Best Practices#
Store API key and server secret in .env, never commit credentials
The service provider registers automatically — no manual provider registration needed
Send structured logs via Log::channel('abrovatrace') for centralized logging
User context is auto-extracted from Auth, but set it manually for API token auth
HTTP and DB breadcrumbs are automatic — add custom breadcrumbs for business logic
Exclude health checks and debug routes from middleware tracking
Set slow_query_threshold_ms to catch performance regressions early
Wrap external API calls and expensive operations for performance monitoring