ホームページ  >  記事  >  PHPフレームワーク  >  非同期ログ操作に ThinkPHP6 を使用するにはどうすればよいですか?

非同期ログ操作に ThinkPHP6 を使用するにはどうすればよいですか?

WBOY
WBOYオリジナル
2023-06-12 09:57:112106ブラウズ

インターネットの急速な発展に伴い、ログ サービスはあらゆる大規模な Web アプリケーションにとって不可欠なモジュールになりました。エラーのトラブルシューティングやパフォーマンスの監視などのさまざまなニーズに対応するために、この記事では、ThinkPHP6 フレームワークを使用して非同期ログ操作を実行する方法を紹介します。

1. ロギングとは

コンピュータ サイエンスの分野では、ロギングとは、コンピュータ システム内で発生するイベントや情報を記録することを指します。通常、これらのレコードはファイルまたはデータベースに保存されます。ロギングは、システムの動作状況を理解し、問題をタイムリーに発見して解決することで、システムの信頼性と安定性を向上させるのに役立ちます。

Web アプリケーションでは、ログ記録は、開発者がシステムで発生した問題やエラーをより深く理解するのに役立ちます。開発者はログに基づいて、アプリケーションの動作と、エラーがいつどこで発生したかを明確に理解できます。

2. ThinkPHP6 の非同期ロギング

アプリケーション開発プロセスにおいて、ロギングは不可欠なモジュールです。さらに、ロギングは時間のかかる操作であることが多く、同期的に実行するとシステムのパフォーマンスに影響を与える可能性があります。この目的を達成するために、ThinkPHP6 では非同期ロギングの機能が導入され、ロギングがアプリケーションの応答速度に影響を与えることがなくなりました。

通常、コントローラーまたはモデルにログを記録するには、挿入された PsrLogLoggerInterface インターフェイスを使用します。

// Controller或Model中
use PsrLogLoggerInterface;

public function index(LoggerInterface $logger){
    $logger->info('hello world');
}

使いやすい。非同期ログを使用して非同期ロガーを定義します:

use MonologLogger;
use MonologHandlerStreamHandler;

$logger=new Logger("AsyncLogger");
$logger->pushHandler(new StreamHandler('runtime/log/async.log'), Logger::INFO);

ロガーを定義した後、キューを使用してログ情報を送信します。ここではキュー サービスとして RabbitMQ を使用することを選択します。

// Message类
namespace appcommon;

class Message
{
    /**
     * 记录日志
     * @param $level
     * @param $message
     * @param array $context
     * @return bool
     */
    public static function log($level,$message,array $context=[]){
        $data=[
            'level'=>$level,
            'message'=>$message,
            'context'=>$context,
            'channel'=>'AsyncLogger',
            'datetime'=>date('Y-m-d H:i:s'),
            'host'=>$_SERVER['SERVER_ADDR'] ?? '',
            'uri'=>$_SERVER['REQUEST_URI'] ?? '',
        ];

        $producer=Queue::getConnection('AsyncLogger',true);
        $producer->setExchangeOptions(['name'=>'async_logs','type'=>'topic','durable'=>true])->declareExchange();

        try{
            $producer->publish(json_encode($data),[
                'routing_key' =>'log',
                'exchange' =>'async_logs',
            ]);
            return true;
        }catch (Exception $e){
            return false;
        }
    }
}

その中で、appcommonQueue クラスを使用して、rabbitmq 接続インスタンスを提供します。data には、ログ情報の記録に加えて、時間などの環境情報も含まれます。 、IP アドレス、要求された URI アドレスなど。

キュー ハンドラー:

// Consumer类
use BunnyMessage;
use PsrLogLoggerInterface;

class Consumer
{
    /**
     * @param Message $message
     * @param LoggerInterface $logger
     */
    public function process(Message $message,LoggerInterface $logger){
        $body=$message->content;
        $data= json_decode($body,true);
        $channel=$data['channel'] ?? 'default_logger';

        $logger->notice($data['message'], $data);
    }
}

もちろん、ログの処理を支援するクラスも必要です。

// Queue类
namespace appcommon;

use BunnyAsyncClient;
use BunnyChannel;
use BunnyMessage;
use BunnyProtocolMethodBasicConsumeOkFrame;
use BunnyProtocolMethodChannelCloseFrame;
use BunnyProtocolMethodChannelCloseOkFrame;
use BunnyProtocolMethodConnectionCloseFrame;
use BunnyProtocolMethodConnectionCloseOkFrame;
use BunnyProtocolMethodConnectionStartFrame;
use BunnyClientStateEnum;
use BunnyMessage as BunnyMessage;

class Queue
{
    /**
     * @param string $queueName
     * @return Client|null
     */
    public static function getConnection(string $routingKey, bool $persistent=false):?Client
    {
        $config=config('rabbitmq.async_log');
        $client=new Client([
            'host' => $config['host'],
            'port' => $config['port'],
            'user' => $config['user'],
            'password' => $config['password'],
            'vhost' => $config['vhost'],//注意此处改为需要的 VHOST
            'concurrency' => 2,
        ]);

        try{
            $client->connect();
            $client->channel()
                ->then(function (Channel $channel) use($client,$routingKey,$persistent){
                    $channel->exchangeDeclare('async_logs','topic',true,true);
                    $channel->queueDeclare($routingKey, $passive=false,$durable=true,$exclusive=false,$autoDelete=false,$nowait=false);
                    $channel->queueBind($routingKey, 'async_logs', $routingKey);

                    $channel->consume(
                        function ($msg, Channel $channel, BunnyMessage $message) use($client,$routingKey){
                            $className=config('rabbitmq.async_log.consumer');
                            $consumer=new $className($client,$routingKey);
                            $consumer->process($message,app('log.async_logger'));
                            $channel->ack($msg);//处理消息
                        },
                        $routingKey,//队列Name
                        '',//消费Tag
                        false,//no_local
                        false,//no_ack
                        false,//exclusive
                        $persistent ? ['delivery_mode'=>2] : []
                    );
                });
        }catch (Exception $e){
            return null;
        }finally{
            return $client;
        }
    }
}

上記のコードは、キュー接続のホスト、ポートなどを定義します。$client->channel() を通じてチャネル オブジェクトが作成され、チャネル オブジェクトが作成されます。 $channel->exchangeDeclare() および $channel->queueDeclare() を通じて Exchange とキューを作成し、それらをバインドします。最後に、$channel->consume() を使用して、キューからメッセージを非同期に消費し、メッセージ処理クラスにメッセージを送信します。

3. 概要

この記事では、ThinkPHP6 フレームワークを使用して非同期ログ操作を実行し、ログがアプリケーションの応答速度に影響を与えないようにする方法を紹介します。一般に、手順は次のとおりです。

  1. 独自の非同期ロガーを開発する
  2. メッセージ キュー処理に RabbitMQ を使用する
  3. メッセージ ハンドラーを作成する

実際のプロジェクトでは、特定のニーズに応じてコードを最適化し、キュー構成を調整する必要があります。非同期ロギングにより、Web アプリケーションの動作効率が効果的に向上し、システムの安定性と信頼性が向上します。

以上が非同期ログ操作に ThinkPHP6 を使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。