14、Hyperf 3 快速使用 - 多种方式使用日志

作者: 温新

分类: 【Hyperf 3 基础系列】

阅读: 895

时间: 2023-04-25 12:31:21

hi,我是温新,一名 PHPer

Hypref 版本:Hyperf 3.0

学习目标:学习日志的使用

hyperf/logger 组件是基于 psr/logger 实现,默认使用 monolog/monolog 作为驱动,在 hyperf-skeleton 项目内默认提供了一些日志配置,默认使用 Monolog\Handler\StreamHandler, 由于 Swoole 已经对 fopen, fwrite 等函数进行了协程化处理,所以只要不将 useLocking 参数设置为 true,就是协程安全的。

安装

# 安装
composer require hyperf/logger

配置文件

<?php
// config/autoload/logger.php
return [
    'default' => [
        'handler' => [
            'class' => \Monolog\Handler\StreamHandler::class,
            'constructor' => [
                'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
                'level' => \Monolog\Logger::DEBUG,
            ],
        ],
        'formatter' => [
            'class' => \Monolog\Formatter\LineFormatter::class,
            'constructor' => [
                'format' => null,
                'dateFormat' => null,
                'allowInlineLineBreaks' => true,
            ]
        ],
    ],
];

Log 日志使用

方式一:基础使用

新键一个控制器,使用日志功能。

<?php
// App\Controller\Test\LogController.php
namespace App\Controller\Test;

use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Psr\Log\LoggerInterface;
use Hyperf\Logger\LoggerFactory;


#[Controller]
class LogController
{
    protected LoggerInterface $logger;

    public function __construct(LoggerFactory $loggerFactory)
    {
        // 第一个参数对应日志的 name, 第二个参数对应 config/autoload/logger.php 内的 key
        $this->logger = $loggerFactory->get('log', 'default');
    }

    #[GetMapping('/log/write')]
    public function logWrite()
    {
        // 写扩日志文件
        $this->logger->info('hahahaha');
        return 'succ';
    }
}

这样记录日志会有一个问题,所有的日志都记录在了一个hyperf.log 文件,导致的结果就是这个文件会越来越大。

下面修改配置文件,将日志按照天来存储。

方式二:按日期存储日志

使用 Monolog\Handler\RotatingFileHandle 可以实现按照日期存储日志,同时需要将 config/autoload/logger.php 配置文件中的 stream 修改为 filename

修改配置文件,内容如下:

<?php
// config/autoload/logger.php
return [
    'default' => [
        'handler' => [
            'class' => Monolog\Handler\RotatingFileHandler::class,
            'constructor' => [
                // filename 日志按照日期存储
                'filename' => BASE_PATH . '/runtime/logs/hyperf.log',
                'level' => Monolog\Logger::DEBUG,
            ],
        ],
        'formatter' => [
            'class' => Monolog\Formatter\LineFormatter::class,
            'constructor' => [
                'format' => null,
                'dateFormat' => null,
                'allowInlineLineBreaks' => true,
            ],
        ],
    ],
];

方式三:定义 Log 类结合多个 Handle 使用

这个案例中,将不同级别的日志写入不同的文件。

第一步:定义日志类

<?php
// App\Log\Log.php
namespace App\Log;

use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;

class Log
{
    public static function get(string $name = 'app')
    {
        // 通过容器对象实例日志对象
        return ApplicationContext::getContainer()->get(LoggerFactory::class)->get($name);
    }
}

第二步:使用自定义日志

<?php
// App\Controller\Test\LogController.php 
   
use App\Log\Log;
use Psr\Log\LoggerInterface;
use Hyperf\Logger\LoggerFactory;
    
protected LoggerInterface $logger;

public function __construct(LoggerFactory $loggerFactory)
{
    // 第一个参数对应日志的 name, 第二个参数对应 config/autoload/logger.php 内的 key
    $this->logger = $loggerFactory->get('log', 'default');
}

#[GetMapping('/log/write')]
public function logWrite()
{
    // 通过自定义日志类
    Log::get()->info('自定义日志类:PHP is very good');
    Log::get()->debug('自定义日志类:测试 debug 日志');
    Log::get('topic')->error('自定义日志类:致命错误日志');

    // 通过构造函数实例日志对象
    $this->logger->info('logger 对象:info');
    $this->logger->debug('logger 对象:debug');
    return 'succ';
}

方式四:使用 monolog 写入日志

<?php
// App\Controller\Test\LogController.php 

use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
    
#[GetMapping('/log/mon')]
public function logMon()
{
    // 定义一个 channel,monolog 为 channel 名字
    $log        = new Logger('monolog');
    $stream     = new StreamHandler(BASE_PATH . '/runtime/logs/monolog.log', Logger::INFO);
    $dateFormat = "Y-m-d H:i:s";
    $output     = "%datetime%||%channel||%level_name%||%message%||%context%||%extra%\n";
    $formatter  = new LineFormatter($output, $dateFormat);
    $stream->setFormatter($formatter);
    $log->pushHandler($stream);
    $log->info('我就是我,不一样的烟火');

    return 'succ';
}
请登录后再评论