thinkphp6 使用 monolog/monolog socket进行日志处理


场景:在负载均衡环境下,多台服务器上日志不能进行统一管理,需要对日志处理,将日志同步到远程日志服务器上,使用第三方日志服务器需要收费,成本考虑,自己配置日志服务器,进行日志统一管理。

引入monolog/monolog依赖

composer require monolog/monolog

根据官网文档 https://www.kancloud.cn/manual/thinkphp6_0/1037616 自定义驱动,新建日志启动文件 Monolog.php

这里选用的 SocketHandler 处理器

<?php


namespace common\log;

use Monolog\Handler\SocketHandler;
use Monolog\Logger;
use Ramsey\Uuid\Uuid;
use think\App;
use think\contract\LogHandlerInterface;

class Monolog implements LogHandlerInterface
{
    /**
     * 配置参数.
     *
     * @var array
     */
    protected $config = [
        'host' => '127.0.0.1',
        'port' => 2345,
        'json_options' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR,
    ];

    // 实例化并传入参数
    public function __construct(App $app, $config = [])
    {
        if (\is_array($config)) {
            $this->config = array_merge($this->config, $config);
        }
        $this->config['path'] = $app->getRuntimePath().'log';
        if (\DIRECTORY_SEPARATOR != substr($this->config['path'], -1)) {
            $this->config['path'] .= \DIRECTORY_SEPARATOR;
        }
    }

    /**
     * 日志写入接口.
     *
     * @param array $log 日志信息
     */
    public function save(array $log): bool
    {

        $uuid = str_replace('-', '', Uuid::uuid6());
        $trace = [
            'uuid' => $uuid,
            'url' => request()->url(true)
        ];

        $this->getHandler()->debug(null,$trace);

        foreach ($log as $type => $val) {
            foreach ($val as $msg) {
                if (!\is_string($msg)) {
                    $msg = var_export($msg, true);
                }
                if ('diy' == $type) {
                    $msg = json_decode($msg, true);
                }

                $trace = [
                    'uuid' => $uuid,
                    'type' => $type,
                    'msg' => $msg,
                ];

                $this->getHandler()->debug(null,$trace);
            }
        }

        return true;
    }

    /**
     * 每条记录必须单独实例化一次
     * 否则会自动把日记进行汇总
     * 接收时无法进行分割处理
     * @return Logger
     */
    protected function getHandler(): Logger
    {
        $connectionString = $this->config['host'].':'.$this->config['port'];
        $logger = new Logger('remote');
        $logger->pushHandler(new SocketHandler($connectionString, Logger::DEBUG));

        return $logger;
    }
}

 

在config/log.php 日志配置中增加remote通道,并将默认日志记录通道改成remote

 // 默认日志记录通道
    'default'      => env('log.channel', 'remote'),
 // 日志通道列表
    'channels'     => [
     
        'remote' => [
            'type'           => 'common\log\Monolog',
            'host'           => '127.0.0.1,
            'port'           => 2345,
        ],

        // 其它日志通道配置
    ],

 

 

日志服务器项目

安装thinkphp6作为日志服务器管理项目

composer create-project topthink/think log-project

这里选用workerman 作为日志接收服务

安装workerman 依赖

composer require topthink/think-worker

新增logSocket.php,注意这里protocol需要设置成tcp才可以接受,使用websocket 是接收不到的

<?php

namespace app\workerman;

use think\worker\Server;

class LogSocket extends Server
{
    protected $protocol = 'tcp';
    protected $host = '127.0.0.1';
    protected $port = 2345;

    public function onMessage($connection, $data)
    {
        $logParts = explode(' ', $data,4);
        $logParts[3] = trim($logParts[3]);
        $logParts[3] = trim($logParts[3],' []');

        $data = json_decode($logParts[3],true);
        dump($data);
    }
}

 

启动服务

php think worker:server
Starting Workerman server...
Workerman[think] start in DEBUG mode
-------------------------------------------- WORKERMAN --------------------------------------------
Workerman version:3.5.35          PHP version:7.4.33           Event-Loop:\Workerman\Events\Select
--------------------------------------------- WORKERS ---------------------------------------------
proto   user            worker          listen                  processes    status           
tcp     wang            none            tcp://127.0.0.1:2345    1             [OK]            
---------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.

 

应用服务器上请求后,在日志应用上接收到消息

 

发布时间 : 2024-05-15,阅读量:974 , 分类: PHP
本文链接:https://upwqy.com/details/947.html
mac 查看已启动的端口 Nginx负载均衡+宝塔