Laravel logging with Monolog\Handler\BrowserConsoleHandler Laravel logging with Monolog\Handler\BrowserConsoleHandler laravel laravel

Laravel logging with Monolog\Handler\BrowserConsoleHandler


After reading plenty of source code and getting xdebug to work I finally figuered it out:

BrowserConsoleHandler sends the script snipped after finishing the php script by register_shutdown_function(). At this time, Laravel already sent the full response to the browser. So the script snipped from BrowseConsoleHandler gets generated but never sent to the browser.

As a workaround you can build your own Middleware (http://laravel.com/docs/5.0/middleware) that invokes the code generation manually and adds it to the response before it gets sent.

Create app/Http/Middleware/LogBrowserConsole.php:

<?phpnamespace App\Http\Middleware;use Illuminate\Contracts\Routing\Middleware;use Illuminate\Support\Facades\Log;use Monolog\Handler\BrowserConsoleHandler;class LogBrowserConsole implements Middleware {  public function handle($request, \Closure $next)  {    // add BrowserConsoleHandler to Laravel's Logger    $log = Log::getMonolog();    $log->pushHandler(new BrowserConsoleHandler(\Psr\Log\LogLevel::INFO));    // invokes all your stuff like it would do without the middleware but with the new logger    $response = $next($request);    // after the request is done we care about the log entries    $handlers = $log->getHandlers();    $scriptSnippet = "";    foreach($handlers as $handler){ // only handle BrowserConsoleHandler        if($handler instanceof BrowserConsoleHandler){            ob_start(); //start output buffer so we can save echo to variable            $handler->send(); // create the scriptSnipped            $scriptSnippet .= ob_get_clean();        }    }    // write scriptSnippet to end of response content    $content = $response->getContent();    $response->setContent($content.$scriptSnippet);    return $response;  }}

Register the Middleware in app/Http/Kernel.php:

protected $routeMiddleware = [    'log.browserconsole' => 'App\Http\Middleware\LogBrowserConsole'];

and invoke your Controller with the Middleware in app/Http/routes.php:

Route::get('test', ['middleware' => 'log.browserconsole', 'uses'=>'TestController@test']);

Alternatively, if you want to use the Middleware for every request you can add it to

protected $middleware = ['App\Http\Middleware\LogBrowserConsole'];

in app/Http/Kernel.php.

Your Route would look like Route::get('test', 'TestController@test');


Now, your Log::debug() etc. messages get sent to the logfile (the default LogHandler is still available, you just added another) and the script snipped from BrowserConsoleHandler gets built and sent to the browser with all your log items.

Keep in mind to eventually change the log level \Psr\LogLevel::INFO in app/Http/Middleware/LogBrowserConsole to fit your needs.