hyperf: 记录访问日志

一,创建middleware

$ php bin/hyperf.php gen:middleware AccesslogMiddleware
App\Middleware\AccesslogMiddleware created successfully.

二,配置一个日志

config/autoload/logger.php

    'access' => [
        'handler' => [
            'class' => Monolog\Handler\RotatingFileHandler::class,
            'constructor' => [
                'filename' => BASE_PATH . '/runtime/logs/access.log',
                'level' => Monolog\Logger::INFO,
            ],
        ],
        'formatter' => [
            'class' => Monolog\Formatter\LineFormatter::class,
            'constructor' => [
                'format' => "[%datetime%] %channel% %level_name%:%message%\n",
                'dateFormat' => 'Y-m-d H:i:s',
                'allowInlineLineBreaks' => true,
            ],
        ],
    ],

三,日志类代码

app/Log/AccessLog.php

<?php
namespace App\Log;

use Hyperf\Context\ApplicationContext;
use Hyperf\Logger\LoggerFactory;

class AccessLog
{
    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    public function __construct()
    {
        $this->logger = ApplicationContext::getContainer()->get(LoggerFactory::class)->get("access","access");
    }

    public function info($content){
        $this->logger->info($content);
    }
}

四,中间件代码:

<?php

declare(strict_types=1);

namespace App\Middleware;

use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

use App\Log\AccessLog;

class AccesslogMiddleware implements MiddlewareInterface
{
    protected AccessLog $loggerFile;
    public function __construct(protected ContainerInterface $container)
    {
           $this->loggerFile = new AccessLog();
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {


        echo '这里是请求穿越阶段,也就是请求处理前';
        //开始时间
        $startTime = microtime(true);

        $response = $handler->handle($request); // 继续向洋葱芯穿越,直至执行控制器得到响应

        echo '这里是响应穿出阶段,也就是请求处理后';
        //响应时间
        $endTime = microtime(true);
        //共计用时
        $costTime = $endTime - $startTime;

        //$ip = get_client_ip();
        $ip = $request->getServerParams()['remote_addr'];
        $time = date("Y-m-d H:i:s");     //访问时间
        $method = $request->getMethod();
        $url = $request->fullUrl();
        $status = $response->getStatusCode();    //返回时的状态码
        $size = $response->getBody()->getSize();    //内容大小
        $protocol = $request->getProtocolVersion();
        $agent = $request->getHeader('user-agent');
        $agentStr = implode(",",$agent);

        $responseBody = $response->getBody()->getContents();
        //写日志
        $content = $ip." ".$time." ".$method." ".$url." ".$protocol." ".$status." ".$size." ".$costTime." ".$agentStr;
        $content .= "\nresponse:".$responseBody;
        $this->loggerFile->info($content);

        return $response;
    }
}

 

五,日志的实际效果:

[2025-02-08 10:42:51] access INFO:192.168.219.1 2025-02-08 10:42:51 GET http://192.168.219.6:9501/image/detail?id=1 1.1 200 15 0.0034439563751221 
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36
response:{"key":"value"}

 

posted @ 2025-02-09 19:16  刘宏缔的架构森林  阅读(130)  评论(0)    收藏  举报