rollbar/rollbar-laravel
Official Rollbar integration for Laravel: automatically reports exceptions, errors, and logs to Rollbar via the exception handler, a dedicated logging channel, and artisan commands. Includes config publishing, queue support, and person/context enrichment for faster debugging in production.
Install the package and publish its config:
composer require rollbar/rollbar-laravel
php artisan vendor:publish --provider="Rollbar\Laravel\RollbarServiceProvider" --tag=config
The service provider is auto-discovered on Laravel 11/12, so basic exception reporting works with no edits to bootstrap/app.php. On older Laravel, register the provider and the Rollbar facade alias in config/app.php.
Then set the essentials in .env:
ROLLBAR_TOKEN= # server/post-item token — NOT a client token
ROLLBAR_ENVIRONMENT=production
ROLLBAR_LEVEL=error
ROLLBAR_ENABLED=true
ROLLBAR_CODE_VERSION=${GIT_SHA}
ROLLBAR_PII=false
In local dev and CI, set ROLLBAR_ENABLED=false. There is no reason to burn quota or add HTTP latency on your machine or in the test suite.
Where to look first, in order:
config/rollbar.php — access token, environment, minimum level, PII flag, scrub_fields, enabled, transmit, timeout, and the reporting toggles (exception, error, job). This file answers most "why isn't my error showing up?" questions.bootstrap/app.php (Laravel 11+) or app/Exceptions/Handler.php (older) — where you filter noise and attach context.First use case: prove the loop end-to-end before trusting it.
php artisan tinker
>>> report(new \RuntimeException('rollbar smoke test'));
Confirm the item lands in Rollbar with the right environment, request URL, user, and code_version. Everything after this — filtering, scrubbing, job coverage — is refinement on a known-good path.
A safe starting config:
// config/rollbar.php (abridged — key names vary by major version)
return [
'access_token' => env('ROLLBAR_TOKEN'),
'environment' => env('ROLLBAR_ENVIRONMENT', env('APP_ENV')),
'level' => env('ROLLBAR_LEVEL', 'error'),
'enabled' => env('ROLLBAR_ENABLED', true),
'personally_identifiable_information' => env('ROLLBAR_PII', false),
'scrub_fields' => ['password', 'password_confirmation', 'authorization', 'cookie'],
'timeout' => 2,
'reporting' => ['exception' => true, 'error' => true, 'job' => true],
];
Let the framework handler do the work for exceptions. The package hooks into Laravel's exception reporter, so every report($e) and every unhandled exception already flows to Rollbar. Your job is filtering, not adding reporting calls:
->withExceptions(function (Exceptions $exceptions) {
$exceptions->dontReport([
\App\Exceptions\PaymentDeclinedException::class, // expected business outcome
\App\Exceptions\UpstreamTimeoutException::class, // noisy, alerting handled elsewhere
]);
})
Laravel already excludes validation failures and 404-type exceptions — don't re-implement that.
Use the log channel for handled failures. Add a rollbar channel in config/logging.php (driver rollbar; match the README for your version) and emit structured logs:
Log::channel('rollbar')->error('Payment gateway returned 502', [
'order_id' => $order->id,
'gateway' => $gateway->name,
'attempt' => $attempt,
]);
This is the cleanest way to surface "something went wrong but we recovered" without throwing an exception purely to get it reported. It also keeps the item fingerprint stable across occurrences, which matters for grouping.
Attach user/request/tenant context in one middleware. A small middleware that pushes the authenticated user id, request id, and tenant id onto every report makes items searchable and keeps payloads consistent. Use the person/context API from your installed major's README (set_person_id/set_person on older majors, a person payload/context on v8-style majors) — don't guess across versions.
Enrich specific exceptions with a report() method. Laravel calls report() on any exception defining it. Use it to attach domain context immediately before the item is sent, instead of sprinkling report() calls through controllers:
class PaymentFailedException extends RuntimeException
{
public function report(): void
{
\Rollbar::context([
'order_id' => $this->orderId,
'gateway' => $this->gateway,
'http_code' => $this->statusCode,
]);
}
}
Queue jobs need deliberate handling. Unhandled job exceptions are captured automatically, but a retrying job can flood you with near-identical items. Options:
dontReport for transient exceptions (timeouts, deadlocks) that resolve themselves.fingerprint or extra in the job's failed() method so Rollbar collapses retries into one item.report($e) inside a job, the global handler will also report the same exception when it bubbles out.Correlate deploys with code_version. Push the git SHA at deploy time (ROLLBAR_CODE_VERSION=${GIT_SHA}). Daily payoff: "did this start with the last release?" becomes a filter instead of an investigation, and it powers Rollbar's deploy tracking.
Test without shipping. Set ROLLBAR_ENABLED=false in phpunit.xml, or flip transmit => false so the SDK builds a full payload you can assert on without HTTP. For integration tests, bind a fake RollbarLogger into the container and assert on calls — never let CI touch Rollbar.
One token per service per environment. Prefer distinct tokens for staging and production over a shared token with different ROLLBAR_ENVIRONMENT values. It makes a misconfigured env var structurally unable to push staging noise into the production dashboard.
Day-to-day triage loop this enables:
environment=production, code_version=current, person.id for a specific customer, or job for worker-only issues.Bind custom scrubbers or loggers in a service provider. If scrub_fields isn't enough (nested keys, JSON blobs, third-party payloads), bind a custom scrubber implementation through the container rather than forking the package. Same for a custom logger/transport.
ROLLBAR_TOKEN, a client token where a server token is required, or enabled => false all produce silence, not an error. If nothing appears in Rollbar, dump config('rollbar.access_token') after config:cache.php artisan config:cache is the classic trap. Changing .env on a cached config does nothing. Always config:clear (or re-run config:cache during deploy) after env changes.personally_identifiable_information gates user data. With it off, person/email fields are dropped or scrubbed even when you explicitly pass them. Turn it on only with a privacy basis, and then audit scrub_fields — scrubbing matches on field names, so deeply nested or oddly named keys slip through. Test with a representative payload.capture_message controls plain-string logs. If it's off, Log::error('plain text') may not be captured even though exceptions still are. Decide explicitly.level is a blunt instrument. ROLLBAR_LEVEL=error drops warning and below; dropping it to warning/info can multiply volume dramatically. Exceptions usually report at error, so raising the threshold quiets the noise but also trims real signal.timeout (1–2s); disable transmission locally and in tests; consider async delivery for high-traffic paths.report() on the exception all firing yields duplicate items. Trace one exception end-to-end after wiring anything new.App\Exceptions\Handler. Older posts tell you to override report() there; on modern Laravel use bootstrap/app.php (->withExceptions(...)) plus the package's auto-registration.ROLLBAR_ENVIRONMENT creates a new environment in Rollbar — history appears to reset and deploy tracking breaks. Keep names stable and matching the dashboard.agent_log_location) or set transmit => false to see whether payloads are built at all. The overwhelming majority of "it doesn't work" cases are token, environment, or config-cache problems — not the SDK.rollbar/rollbar-laravel and its rollbar/rollbar-php dependency. On a Laravel upgrade, re-read the README rather than assuming keys survived.How can I help you explore Laravel packages today?