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