隨著互聯(lián)網(wǎng)的高速發(fā)展,日志記錄服務成為了每個大型 web 應用必不可少的模塊。為了方便錯誤排查、性能監(jiān)控等各種需求,本文將介紹如何使用 ThinkPHP6 框架進行異步日志記錄操作。
1. 什么是日志記錄
在計算機科學領域,日志記錄是指將計算機系統(tǒng)中發(fā)生的事件和信息記錄下來。通常,這些記錄都以文件或數(shù)據(jù)庫的形式存儲。日志記錄有助于了解系統(tǒng)運行狀況,及時發(fā)現(xiàn)和解決問題,進而提高系統(tǒng)的可靠性和穩(wěn)定性。
在 web 應用中,日志記錄可以幫助開發(fā)者更好地了解系統(tǒng)的遇到的問題和錯誤。依據(jù)日志記錄,開發(fā)者可以清楚地了解應用的行為以及錯誤發(fā)生的位置和時機。
2. ThinkPHP6 異步日志記錄
在應用開發(fā)過程中,日志記錄是一個必不可少的模塊。而且,日志記錄經(jīng)常是一個耗時的操作,如果同步執(zhí)行的話會影響系統(tǒng)的性能。為此,ThinkPHP6 引入了異步日志記錄的功能,讓日志記錄不再影響應用的響應速度。
通常在控制器或模型中記錄日志,我們使用注入 PsrLogLoggerInterface 接口來實現(xiàn)。
// 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);
登錄后復制
日志記錄器定義好后,使用隊列發(fā)送日志記錄信息,這里我們選擇使用 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中除了記錄日志的信息外,還包含一些環(huán)境信息,比如時間、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;
}
}
}
登錄后復制
上面這段代碼中定義了隊列連接的 host、port 等,通過 $client->channel() 創(chuàng)建了一個 channel 對象,通過 $channel->exchangeDeclare() 和 $channel->queueDeclare() 創(chuàng)建了 exchange 和 queue,并將它們進行了綁定。最后,使用 $channel->consume() 異步消費隊列的消息,并將消息發(fā)送到消息處理類中。
3. 總結
本文介紹了如何使用 ThinkPHP6 框架進行異步日志記錄操作,使日志記錄不再影響應用的響應速度。總體來說,以下是操作步驟:
- 開發(fā)自己的異步日志記錄器使用 RabbitMQ 進行消息隊列處理編寫消息處理程序
在實際項目中,我們需要根據(jù)具體的需求來優(yōu)化代碼和調整隊列的配置。通過異步記錄日志,可以有效提高 web 應用的運行效率,并提高系統(tǒng)的穩(wěn)定性與可靠性。
以上就是如何使用ThinkPHP6進行異步日志記錄操作?的詳細內容,更多請關注www.xfxf.net其它相關文章!






