chore: 重写初始提交(清空历史,整理后全量提交)
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ywxapp\middleware;
|
||||
|
||||
use think\facade\Config;
|
||||
use ywxapp\service\AddonPerformanceMonitor;
|
||||
|
||||
/**
|
||||
* 插件性能监控中间件(全局注册于 app/middleware.php)
|
||||
*
|
||||
* 设计要点:
|
||||
* - 从请求路径首段解析插件名(插件路由统一为 /<插件名>/<group>/...),
|
||||
* 仅对「已启用插件」的请求做性能采样,核心应用(admin/index/api 等)零开销;
|
||||
* - 用 AddonPerformanceMonitor::measure() 包裹 $next($request),把每次插件
|
||||
* HTTP 请求的真实耗时/内存/成功失败写入缓存,使 addon:health 的性能项有真数据;
|
||||
* - measure() 的 finally 已防御性吞掉缓存异常,本中间件无需再包 try/catch,
|
||||
* 且绝不二次调用 $next(避免重复执行业务);
|
||||
* - 控制器抛异常时 measure() 记录为失败并原样向外抛出,框架错误处理不受影响。
|
||||
*
|
||||
* @author ywxapp <admin@ywxapp.cn>
|
||||
*/
|
||||
class AddonPerformanceMiddleware
|
||||
{
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
$addon = $this->resolveAddon($request);
|
||||
if ($addon === null) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
$action = $this->resolveAction($request);
|
||||
|
||||
return AddonPerformanceMonitor::measure($addon, $action, function () use ($next, $request) {
|
||||
return $next($request);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 从路径首段解析插件名,并确认其为已启用插件(Config::get('addon') 仅含 state=1)
|
||||
*/
|
||||
private function resolveAddon($request): ?string
|
||||
{
|
||||
$path = trim((string) $request->pathinfo(), '/');
|
||||
if ($path === '') {
|
||||
return null;
|
||||
}
|
||||
$segments = explode('/', $path);
|
||||
$maybe = $segments[0];
|
||||
|
||||
$addon = Config::get('addon', []);
|
||||
foreach ($addon as $info) {
|
||||
if (($info['name'] ?? '') === $maybe) {
|
||||
return $maybe;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 动作标签:HTTP 方法 + 插件名之后的剩余路径(如 GET backend/addonreview/index)
|
||||
*/
|
||||
private function resolveAction($request): string
|
||||
{
|
||||
$path = trim((string) $request->pathinfo(), '/');
|
||||
$segments = explode('/', $path);
|
||||
array_shift($segments); // 去掉插件名首段
|
||||
$rest = implode('/', $segments);
|
||||
return ($request->method() ?? 'GET') . ' ' . ($rest === '' ? 'index' : $rest);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user