php - Laravel 使用 Monolog\Handler\BrowserConsoleHandler 进行日志记录

标签 php laravel logging laravel-5 monolog

如何将 Laravel 5 的日志更改为 Monolog\Handler\BrowserConsoleHandler

什么在 Laravel 5 中有效,但在独立的 PHP 文件中有效:

use Illuminate\Support\Facades\Log;    
use Monolog\Handler\BrowserConsoleHandler;
use Monolog\Logger;

// create a log channel
$log = Log::getMonolog();
// $log = new Logger('Testlogger'); //doesn't make any difference
$log->pushHandler(new BrowserConsoleHandler(\Psr\Log\LogLevel::INFO));

// add records to the log
$log->addWarning('Foo');
$log->addError('Bar');

所发生的只是我的日志出现在日志文件中,但没有找到进入浏览器的路径。如果我在没有框架的情况下在单个 PHP 文件中尝试代码,它会工作,所以我认为这是一个 Laravel 问题。

我在安装了 Firebug 和 FirePHP 以及 $log->pushHandler(new FirePHPHandler()); 而不是 BrowserConsoleHandler 的情况下使用它,但这不是解决方案,因为它发送带有标题的日志,但当记录器想要发送标题时,我已经发送了一些调试回显。
另一方面,BrowserConsoleHandler 在网站末尾添加了一个 JavaScript 片段,这完全符合我的需要。

那么,有没有人成功地将 BrowserConsoleHandler 添加到 Laravel 的日志记录中?怎么办?

最佳答案

在阅读了大量的源代码并让 xdebug 工作后,我终于弄明白了:

BrowserConsoleHandler 发送 register_shutdown_function() 完成 php 脚本后截取的脚本。此时,Laravel 已经将完整的响应发送给了浏览器。因此,生成了从 BrowseConsoleHandler 截取的脚本,但从未发送到浏览器。

作为解决方法,您可以构建自己的中间件 ( http://laravel.com/docs/5.0/middleware ),它会手动调用代码生成并在发送响应之前将其添加到响应中。

创建app/Http/Middleware/LogBrowserConsole.php:

<?php
namespace 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;
  }
}

app/Http/Kernel.php 中注册中间件:

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

并使用 app/Http/routes.php 中的中间件调用您的 Controller :

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

或者,如果你想为每个请求使用中间件,你可以将它添加到

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

app/Http/Kernel.php 中。

你的路线看起来像 Route::get('test', 'TestController@test');


现在,您的 Log::debug() 等消息被发送到日志文件(默认的 LogHandler 仍然可用,您只是添加了另一个)和脚本从 BrowserConsoleHandler 构建并与所有日志项一起发送到浏览器。

请记住最终更改 app/Http/Middleware/LogBrowserConsole 中的日志级别 \Psr\LogLevel::INFO 以满足您的需要。

关于php - Laravel 使用 Monolog\Handler\BrowserConsoleHandler 进行日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29455996/

相关文章:

ios - 我们如何将崩溃日志存储在iOS应用程序中

java - 自定义异常。在哪里记录

php - 使用 Redis 的 Laravel 缓存 - 这个键是什么意思?

javascript - 限制用户在 PHP 中查看页面

php - PHP : Log into an “global array”

php - SSL3_GET_SERVER_CERTIFICATE :certificate verify failed using xampp on mac

php - Post 方法在 Laravel 中不起作用

java - 如何使用log4j的同一个记录器将不同的信息写入两个不同的文件?

php - HTML解析如何去除mysql数据库中的标签、属性

php - 填充和类 col-md 不起作用