14、Hyperf 3 快速使用 - 多种方式使用日志
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';
}
请登录后再评论