Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Monolog Bugsnag Bundle Laravel Package

mrandmrssmith/monolog-bugsnag-bundle

Symfony bundle for integrating Monolog with Bugsnag. It wires a Bugsnag handler into Symfony's logging stack so application log records can be forwarded to Bugsnag for error tracking, alerting, and centralized visibility.

View on GitHub
Deep Wiki
Context7

Getting Started

v3.0.0 shipped with no release notes and no package metadata, so this is a major-version bump you have to reverse-engineer. Treat everything in the previous assessment as unverified until you've diffed the tag. Start by reading the diff, not the changelog.

1. Install pinned, then diff the major bump

composer require mrandmrssmith/monolog-bugsnag-bundle:^3.0 --prefer-dist

Before configuring anything, diff v3.0.0 against the last 2.x tag — with an empty changelog this is the only source of truth for what broke:

git clone https://github.com/mrandmrssmith/monolog-bugsnag-bundle && cd monolog-bugsnag-bundle
git diff <last-2.x-tag> v3.0.0 -- src/ config/ composer.json

You are looking for four things: the PHP namespace/FQCN of the handler, the DI service ID, the config key namespace, and the composer.json constraints (monolog/monolog, bugsnag/bugsnag, PHP version). A major bump with no notes usually means at least one of those changed.

2. Know what you actually installed: it's a Symfony bundle, not a Laravel package

mrandmrssmith/monolog-bugsnag-bundle registers a Symfony Bundle and a container service. Laravel will not auto-discover or auto-configure it — there's no service provider and no config/logging.php integration. In Laravel you consume the handler class directly in your logging config and ignore the bundle half:

// config/logging.php
'channels' => [
    'bugsnag' => [
        'driver'  => 'monolog',
        'handler' => \MrAndMrsSmith\MonologBugsnagBundle\Handler\BugsnagHandler::class, // confirm FQCN from src/
        'handler_with' => [
            'apiKey' => env('BUGSNAG_API_KEY'),
        ],
        'level' => 'error',
        ' bubble' => true,
    ],
],

If that constructor signature doesn't line up (the v3 handler may now take a client/builder instead of a raw key), fall back to instantiating it in a small custom channel or a service provider — but confirm from the source first.

3. Provide the API key

BUGSNAG_API_KEY=your-key-here
APP_VERSION=2024.11.0

Nothing in this package sets releaseStage, appVersion, or notifyReleaseStages for you — and a v3 major is a good moment to assume those defaults changed too.

4. First use case: route errors to Bugsnag without swallowing them

In Laravel, the idiomatic move is a stack channel so the file log survives when Bugsnag is unreachable:

'stack' => [
    'driver'   => 'stack',
    'channels' => ['single', 'bugsnag'],
],

Then throw from a route and confirm the event lands in Bugsnag with a stack trace and that it still appears in storage/logs/laravel.log.

5. Verify end-to-end

php artisan tinker → logger()->error('v3 smoke test'), then check the dashboard. Silence is the default failure mode: missing key, wrong level, or a handler on a channel that never receives records all look identical from the outside.

Implementation Patterns

Pin the major, then verify the Monolog contract. The likely reason for a 3.0.0 is alignment with Monolog 3, where handlers receive Monolog\LogRecord instead of array and HandlerInterface gained flush(). If you're on Laravel 10 with Monolog 3, check the handler's handle() signature matches; if you're on a Laravel still on Monolog 2, v3.0.0 of this package is probably not installable or not compatible. Lock monolog/monolog explicitly rather than letting the resolver pick.

Use a dedicated channel, not the whole stack. Keep bugsnag as a named channel and add it to stack only where you want alerting. Noisy debug/info traffic inflates your error budget and destroys grouping:

'bugsnag_worker' => [
    'driver'   => 'monolog',
    'handler'  => BugsnagHandler::class,
    'handler_with' => ['apiKey' => env('BUGSNAG_API_KEY')],
    'level'    => 'error',
    'tap'      => [App\Logging\JobContextProcessor::class],
],

Buffer context before the error, not just the error. Monolog's FingersCrossedHandler is where the value is — it flushes the preceding N records into the alert. Wire it as the channel's handler wrapping the Bugsnag handler so you get the "why", not just the exception:

'handler' => \Monolog\Handler\FingersCrossedHandler::class,
'handler_with' => [
    'handler' => new BugsnagHandler(env('BUGSNAG_API_KEY')),
    'activationStrategy' => new \Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy('error'),
    'bufferSize' => 50,
],

Get the context into Bugsnag metadata. Laravel's tap array is the cheap extension point — attach user/tenant/request-id processors to the same channel so events are searchable and groupable in the dashboard:

'tap' => [App\Logging\TenantProcessor::class, App\Logging\RequestIdProcessor::class],

Split web and queue traffic. Two channels (bugsnag and bugsnag_worker) with a job-name processor means Bugsnag groups by job class instead of lumping every failed SendInvoice into "RuntimeException".

Gate by environment. Only include the channel in the stack for production/staging. During local development a handler that fires on every 500 pollutes your trends and burns quota — config/logging.php is evaluated per-environment, so branch the channel list on app()->environment().

Keep the file handler in the stack, always. Bugsnag is an alerting sink, not a log store. If the SDK times out or the key rotates, the file channel is your only record of the incident.

Catch at the boundaries. Laravel's exception handler covers HTTP, but queued jobs and scheduled commands benefit from an explicit report()/logger()->error() at the job boundary — CLI failures are the number one reason "Bugsnag shows nothing from cron".

Gotchas and Tips

v3.0.0 has no release notes — assume everything is breaking. Namespace, service ID, config key namespace, and constructor signature are all fair game in a major bump. Read the source before you write a single line of config; do not copy 2.x snippets from a blog post (including the ones above) without confirming FQCNs.

The bundle half is dead weight in Laravel. You're paying for Symfony DI config you can't use. If the diff shows the handler is still a few dozen lines around the Bugsnag SDK, the rational long-term move is to copy that class into app/Logging/ under your own namespace and drop the dependency — you'll be reading it on every upgrade anyway, and it removes the maintenance risk entirely.

Confirm the service ID / handler FQCN empirically. In Symfony: bin/console debug:container | grep -i bugsnag. In Laravel, reflection on the installed class is faster than guessing:

php -r "require 'vendor/autoload.php'; print_r((new ReflectionClass('MrAndMrsSmith\MonologBugsnagBundle\Handler\BugsnagHandler'))->getConstructor()->getParameters());"

Silent failures are still the default. If the API key is empty or the release stage is filtered out, these handlers typically swallow the record and return true. Add a boot-time assertion — a service provider boot() that throws in production when BUGSNAG_API_KEY is missing, or a health-check route hit by your uptime monitor.

Mind bubble and FingersCrossedHandler. bubble: false stops records dead and your file log goes quiet — the exact opposite of what an alerting sink should do. Note the stray-space typo hazard in config arrays (' bubble') silently doing nothing; Laravel won't warn you about an unknown key in handler_with.

Buffered handlers need flush(). If v3 moved to Monolog 3, HandlerInterface::flush() is mandatory — a v3 handler missing it will fatal on class_implements. Conversely, if you wrap it in BufferHandler, confirm close()/flush() is actually invoked on queue-worker shutdown, or the last batch of errors dies with the worker.

404s and validation errors will burn quota. In Laravel, ValidationException and AuthenticationException are reported by the framework differently — make sure your level and channel scoping excludes them, or add an exception filter in bootstrap/app.php ($exceptions->dontReport(...)) rather than muting them in the dashboard after the fact.

No release tracking by default. Set APP_VERSION from CI and pass it into the handler/bugsnag client explicitly. Unattributed events make "which deploy introduced this regression" unanswerable, especially right after a major bump when you're actively watching for breakage.

Upgrade discipline for an abandoned-looking package. 1 star, 0 dependents, NOASSERTION license, and now a silent major release. Pin to an exact version (3.0.0, not ^3.0), review diffs on every update, and keep a one-file fallback: swap the channel's handler to your inlined class if upstream goes dark. The channel-based integration above makes that swap a one-line change — which is the strongest argument for configuring it as a custom handler rather than relying on any bundle wiring.

Extension point: subclass the handler, never patch vendor/. Need userId, custom severity mapping, or metadata shaping? Extend the handler, register your subclass as the channel's handler, and your customization survives whatever v3.1 breaks.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager