Gustavo Straube
Gustavo Straube

Reputation: 3861

How to add a new exception handler to Laravel without disable the default one?

I'm using Sentry to keep tracking of exceptions from a Laravel application.

Sentry's docs say I should use the following code in my application bootstrap to setup the client:

$app->configureMonologUsing(function($monolog) {
    $client = new Raven_Client('your dsn');
    $handler = new Monolog\Handler\RavenHandler($client);
    $handler->setFormatter(new Monolog\Formatter\LineFormatter("%message% %context% %extra%\n"));
    $monolog->pushHandler($handler);
});

And that works fine!

The side effect is that Laravel's default exception handler, which writes the exceptions to the file at /storage/logs/laravel.log, stopped to work after adding the new exception handler.

How can I keep both handlers?

UPDATE for Laravel 5.6+

Starting on Laravel 5.6 log stacks are available. It now allows devs to set up multiple log channels with ease. Refer to the docs for more info on that.

Upvotes: 4

Views: 1001

Answers (1)

Nick
Nick

Reputation: 2214

You can look at Illuminate\Foundation\Bootstrap\ConfigureLogging to see how Laravel sets up its native logging. Then in your own bootstrap, just push another handler that does the same:

$app->configureMonologUsing(function($monolog) {

    // Keep your existing Sentry configuration
    $client = new Raven_Client('your dsn');
    $handler = new Monolog\Handler\RavenHandler($client);
    $handler->setFormatter(new Monolog\Formatter\LineFormatter("%message% %context% %extra%\n"));
    $monolog->pushHandler($handler);

    // Add another handler that writes to laravel.log
    $handler = new Monolog\Handler\StreamHandler(storage_path('logs/laravel.log'));
    $handler->setFormatter(new Monolog\Formatter\LineFormatter(null, null, true, true));
    $monolog->pushHandler($handler);

});

Edit:

If you don't need to reproduce Laravel's behaviour exactly, you could use the default formatter for a one-liner addition instead:

$monolog->pushHandler(new Monolog\Handler\StreamHandler(storage_path('logs/laravel.log')));

This differs from the native Laravel implementation in that it'll use the default constructor arguments for LineFormatter rather than those we were setting explicitly before.

A third option that reuses Laravel's logic for configuring Monolog would be the addition of this line instead:

with(new Illuminate\Log\Writer($monolog))->useFiles(storage_path('logs/laravel.log'));

Upvotes: 2

Related Questions