问题描述
如何将 Laravel 5 的日志记录更改为Monolog\Handler\BrowserConsoleHandler
?
How can Laravel 5's logging be changed to Monolog\Handler\BrowserConsoleHandler
?
在Laravel 5中不起作用但在独立的PHP文件中不能起作用:
What doesn't work in Laravel 5 but does work in a standalone PHP file:
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问题.
All that happens is that my logs appear in the logfile but don't find their way to the browser. If I try the code in a single PHP file without framework it works, so I assume it's a Laravel problem.
我安装了Firebug和FirePHP并使用$log->pushHandler(new FirePHPHandler());
而不是BrowserConsoleHandler
来工作,但这不是解决方案,因为它发送带有标头的日志,但是当记录器要发送标头时,我已经发送了一些debug-echos .
另一方面,BrowserConsoleHandler
在网站末尾添加了一个非常符合我需要的JavaScript代码段.
I get it working with Firebug and FirePHP installed and $log->pushHandler(new FirePHPHandler());
instead of BrowserConsoleHandler
but this is not a solution since it sends the logs with headers but I already sent some debug-echos when the logger wants to send the headers.BrowserConsoleHandler
on the other hand adds a JavaScript snippet to the end of the site that perfectly fits my needs.
那么,有没有人成功地将BrowserConsoleHandler
添加到Laravel的日志记录中?怎么样?
So, did anyone succeed in adding BrowserConsoleHandler
to Laravel's logging? How?
推荐答案
在阅读了大量源代码并使xdebug正常工作之后,我终于弄清了它:
After reading plenty of source code and getting xdebug to work I finally figuered it out:
BrowserConsoleHandler
发送完成register_shutdown_function()
的php脚本后被截断的脚本.此时,Laravel已将完整响应发送到浏览器.因此,生成了从BrowseConsoleHandler
摘录的脚本,但从未将其发送到浏览器.
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.
作为解决方法,您可以构建自己的Middleware
( http://laravel.com/docs/5.0/中间件)手动调用代码生成并将其添加到响应中,然后再发送出去.
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.
创建 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 中的中间件调用控制器:
and invoke your Controller with the Middleware in app/Http/routes.php:
Route::get('test', ['middleware' => 'log.browserconsole', 'uses'=>'TestController@test']);
或者,如果您想为每个请求使用Middleware
,则可以将其添加到
Alternatively, if you want to use the Middleware
for every request you can add it to
protected $middleware = [
'App\Http\Middleware\LogBrowserConsole'
];
在 app/Http/Kernel.php 中.
您的路线看起来像Route::get('test', 'TestController@test');
现在,您的Log::debug()
等消息将发送到日志文件(默认LogHandler仍然可用,您刚刚添加了另一个),并且构建了从BrowserConsoleHandler
摘录的脚本并将其与所有日志项一起发送到浏览器
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.
请紧记最终更改 app/Http/Middleware/LogBrowserConsole 中的日志级别\Psr\LogLevel::INFO
以适应您的需求.
Keep in mind to eventually change the log level \Psr\LogLevel::INFO
in app/Http/Middleware/LogBrowserConsole to fit your needs.
这篇关于Laravel使用Monolog \ Handler \ BrowserConsoleHandler进行日志记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!