インターネットの急速な発展に伴い、ログ サービスはあらゆる大規模な Web アプリケーションにとって不可欠なモジュールになりました。エラーのトラブルシューティングやパフォーマンスの監視などのさまざまなニーズに対応するために、この記事では、ThinkPHP6 フレームワークを使用して非同期ログ操作を実行する方法を紹介します。
コンピュータ サイエンスの分野では、ロギングとは、コンピュータ システム内で発生するイベントや情報を記録することを指します。通常、これらのレコードはファイルまたはデータベースに保存されます。ロギングは、システムの動作状況を理解し、問題をタイムリーに発見して解決することで、システムの信頼性と安定性を向上させるのに役立ちます。
Web アプリケーションでは、ログ記録は、開発者がシステムで発生した問題やエラーをより深く理解するのに役立ちます。開発者はログに基づいて、アプリケーションの動作と、エラーがいつどこで発生したかを明確に理解できます。
アプリケーション開発プロセスにおいて、ロギングは不可欠なモジュールです。さらに、ロギングは時間のかかる操作であることが多く、同期的に実行するとシステムのパフォーマンスに影響を与える可能性があります。この目的を達成するために、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()
を使用して、キューからメッセージを非同期に消費し、メッセージ処理クラスにメッセージを送信します。
この記事では、ThinkPHP6 フレームワークを使用して非同期ログ操作を実行し、ログがアプリケーションの応答速度に影響を与えないようにする方法を紹介します。一般に、手順は次のとおりです。
実際のプロジェクトでは、特定のニーズに応じてコードを最適化し、キュー構成を調整する必要があります。非同期ロギングにより、Web アプリケーションの動作効率が効果的に向上し、システムの安定性と信頼性が向上します。
以上が非同期ログ操作に ThinkPHP6 を使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。