使用 laravel5.6 自定义(动态)日志文件名

Posted

技术标签:

【中文标题】使用 laravel5.6 自定义(动态)日志文件名【英文标题】:Custom (dynamic) log file names with laravel5.6 【发布时间】:2018-10-22 15:07:36 【问题描述】:

在 laravel 5.5 中,我们可以访问 $app 中的 configureMonologUsing() 方法,这使得 bootstrap/app.php 中的类似操作成为可能:

$app->configureMonologUsing(function (Monolog\Logger $monolog) 
    $processUser = posix_getpwuid(posix_geteuid());
    $processName= $processUser['name'];

    $filename = storage_path('logs/laravel-' . php_sapi_name() . '-' . $processName . '.log');
    $handler = new Monolog\Handler\RotatingFileHandler($filename);
    $monolog->pushHandler($handler);
);

当您的应用程序可能从不同的上下文(例如 CLI/HTTP)和不同的用户(这是可取的)和文件轮换调用时,这样做很有用。这样做可以防止在 CLI 尝试在其中添加内容之前由 HTTP 用户创建日志文件时出现写入错误,反之亦然。

否则,处理此问题会很棘手或不安全,因为它涉及能够对可能尚不存在的文件设置写入权限。

此外,将日志按上下文分隔非常方便,因为它们通常没有什么共同点,而且更容易在它们之间进行搜索。

不幸的是,这种做事方式在 laravel 5.6 中不再可行,而且我(还)无法找到一种方法对所有基于文件的日志记录透明地这样做。

谢谢

【问题讨论】:

风滚草:o 【参考方案1】:

解决方案:

第一步:在 config/logging.php 文件中创建一个频道

示例:

'channels' => [
    'single' => [
    'driver' => 'single', 
    'path' => storage_path('logs/laravel.log'),
    'level' => 'debug',
],

'web' => [
      'driver' => 'single',
      'path' => storage_path('logs/web/web.log'),
   ],

]

第二步:现在像这样从控制器设置动态路径

config(['logging.channels.web.path' => storage_path('logs/web/'.time().'.log')]);

第 3 步:现在生成您的日志

  Log::channel('web')->info("your message goes here");

享受:)

【讨论】:

不是个好主意,你必须在所有控制器中设置日志。【参考方案2】:

现在通过调用 Monolog 的自定义格式化程序来完成自定义。

这是一个使用每日轮换文件名的示例(就像我一样)。

这可以在config/logging.php中设置,注意非默认的tap参数:

'channels' => [

    'daily' => [
        'driver' => 'daily',
        'tap' => [App\Logging\CustomFilenames::class],
        'path' => storage_path('logs/laravel.log'),
        'level' => 'debug',
    ],

]

在您的自定义格式化程序中,您可以随意操作 Monolog 记录器,类似于 configureMonologUsing():

app\Logging\CustomFilenames.php

<?php

namespace App\Logging;

use Monolog\Handler\RotatingFileHandler;

class CustomFilenames

    /**
     * Customize the given logger instance.
     *
     * @param  \Illuminate\Log\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    
        foreach ($logger->getHandlers() as $handler) 
            if ($handler instanceof RotatingFileHandler) 
                $sapi = php_sapi_name();
                $handler->setFilenameFormat("filename-$sapi-date", 'Y-m-d');
            
        
    

恢复原始行为的一种方法是从处理程序的filenameFormat 中删除date 组件。更好的方法可能是为single 驱动程序操作适当的处理程序。

见:https://laravel.com/docs/5.6/logging#advanced-monolog-channel-customization

【讨论】:

非常感谢,这肯定不是容器的方式,但在好的旧物理服务器中非常方便

以上是关于使用 laravel5.6 自定义(动态)日志文件名的主要内容,如果未能解决你的问题,请参考以下文章

laravel5.6 laravel 接口 接管 自定义异常类

log4j2自定义动态配置日志

如何在logback.xml中自定义动态属性

Laravel 5.6.7 和 Vue.js 中的自定义错误消息,尤其是组件

如何在 laravel 5.6 中创建自定义帮助文件?

Java自定义注解的定义与使用