Laravel 5.3 更改特定控制台命令的日志文件

Laravel 5.3 changing logfiles for specific console commands

我的 Laravel 5.3 应用程序中有两个嘈杂的控制台命令,我想保留它们的日志,但更希望将它们写入与系统其余部分不同的日志文件。

目前,我的应用使用 $app->configureMonologUsing(function($monolog) { ...

将日志写入 bootstrap/app.php 中配置的文件

二等奖是将所有控制台命令写入另一个日志文件,但最好只写入这两个。

我尝试按照这些说明 (https://blog.muya.co.ke/configure-custom-logging-in-laravel-5/ and https://laracasts.com/discuss/channels/general-discussion/advance-logging-with-laravel-and-monolog) 将所有控制台日志重新路由到另一个文件,但它不起作用,只是在其余代码中导致了奇怪的问题。

如果这仍然是 5.3 中的首选方法,那么我会继续尝试,但想知道是否有更新的方法或只为这两个控制台命令更改文件的方法。

这是您可以采用的两种方法

首先,您可以像建议的那样使用 Log::useFilesLog::useDailyFiles

Log::useDailyFiles(storage_path().'/logs/name-of-log.log'); 
Log::info([info to log]);

这种方法的缺点是所有内容仍将记录在您的默认日志文件中,因为默认的 Monolog 在您的代码之前执行。

其次,为了避免在默认日志中包含所有内容,您可以覆盖默认日志记录 class。 here 给出了一个例子。你可以有一个特定的日志文件,比如 Log::info(),所有其他日志都可以写在你的默认文件中。这种方法的明显缺点是它需要更多的工作和代码维护。

这是可能的,但首先您需要删除现有的处理程序。

Monolog 已经设置了一些日志处理程序,因此您需要使用 $monolog->popHandler(); 删除那些。然后使用 建议添加新日志的简单方法是使用 $log->useFiles('/var/log/nginx/ds.console.log', $level='info');.

public function fire (Writer $log)
{
    $monolog = $log->getMonolog();
    $monolog->popHandler();

    $log->useFiles('/var/log/nginx/ds.console.log', $level='info');
    $log->useFiles('/var/log/nginx/ds.console.log', $level='error');
    ...

对于多个处理程序

如果您设置了多个日志处理程序(例如,如果您正在使用 Sentry),您可能需要在清除处理程序之前弹出多个日志处理程序。如果你想保留一个处理程序,你需要遍历所有的处理程序,然后读取你想保留的处理程序。

如果您尝试弹出一个不存在的处理程序,

$monolog->popHandler() 将抛出异常,因此您必须 jump through hoops 才能使其正常工作。

public function fire (Writer $log)
{
    $monolog = $log->getMonolog();

    $handlers = $monolog->getHandlers();
    $numberOfHandlers = count($handlers);
    $saveHandlers = [];

    for ($idx=0; $idx<$numberOfHandlers; $idx++)
    {
        $handler = $monolog->popHandler();

        if (get_class($handler) !== 'Monolog\Handler\StreamHandler')
        {
            $saveHandlers[] = $handler;
        }
    }

    foreach ($saveHandlers as $handler)
    {
        $monolog->pushHandler($handler);
    }

    $log->useFiles('/var/log/nginx/ds.console.log', $level='info');
    $log->useFiles('/var/log/nginx/ds.console.log', $level='error');
    ...

为了更好地控制日志文件,您可以使用这样的东西代替 $log->useFiles()

$logStreamHandler = new \Monolog\Handler\StreamHandler('/var/log/nginx/ds.console.log');

$pid = getmypid();

$logFormat = "%datetime% $pid [%level_name%]: %message%\n";
$formatter = new \Monolog\Formatter\LineFormatter($logFormat, null, true);
$logStreamHandler->setFormatter($formatter);

$monolog->pushHandler($logStreamHandler);