如何使用ThinkPHP6进行异步日志记录操作?

2023年 8月 6日 97.9k 0

随着互联网的高速发展,日志记录服务成为了每个大型 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;
}
}
}

登录后复制

上面这段代码中定义了队列连接的 host、port 等,通过 $client->channel() 创建了一个 channel 对象,通过 $channel->exchangeDeclare()$channel->queueDeclare() 创建了 exchange 和 queue,并将它们进行了绑定。最后,使用 $channel->consume() 异步消费队列的消息,并将消息发送到消息处理类中。

3. 总结

本文介绍了如何使用 ThinkPHP6 框架进行异步日志记录操作,使日志记录不再影响应用的响应速度。总体来说,以下是操作步骤:

  • 开发自己的异步日志记录器
  • 使用 RabbitMQ 进行消息队列处理
  • 编写消息处理程序
  • 在实际项目中,我们需要根据具体的需求来优化代码和调整队列的配置。通过异步记录日志,可以有效提高 web 应用的运行效率,并提高系统的稳定性与可靠性。

    以上就是如何使用ThinkPHP6进行异步日志记录操作?的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论