mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-08-30 12:45:32 +08:00
feat(admin): XHProf 函数监控规则与命中记录
This commit is contained in:
81
database/migrations/20260814110001_xhprof_watch_seed.php
Normal file
81
database/migrations/20260814110001_xhprof_watch_seed.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
|
||||
/**
|
||||
* XHProf 函数监控规则 - 预置三条规则
|
||||
*
|
||||
* regex 为 PCRE(带 ~...~ 定界符),导入任务物化时对被调用(callee)函数名匹配。
|
||||
* 反斜杠形态说明:DB 存储值形如 ~think\\db\\PDOConnection::.*~(双反斜杠字符),
|
||||
* PCRE 解析 \\ 为一个字面 \,与采样键 think\db\PDOConnection::xxx(命名空间单反斜杠)对齐。
|
||||
* 已对运行环境真实采样验证:PDOConnection::(静态形态)、::save(如 think\Cookie::save)均有命中;
|
||||
* app\admin\controller\.* 在后台页面流量下命中(控制器中心主义)。
|
||||
*
|
||||
* MySQL 字符串字面量会把 \\ 解析为单个 \,故写入前用 addcslashes 将每个字面 \ 加倍,
|
||||
* 保证落库值为双反斜杠字符。
|
||||
*
|
||||
* 幂等:regex 有 UNIQUE 键,ON DUPLICATE KEY UPDATE id=id 使重复执行不产生新行、不覆盖用户改动。
|
||||
*/
|
||||
class XhprofWatchSeed extends Migrator
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$now = time();
|
||||
$rows = [
|
||||
[
|
||||
'name' => 'SQL 执行层',
|
||||
// PHP 值:~think\\db\\PDOConnection::.*~(每个分隔位置两个反斜杠字符)
|
||||
'regex' => '~think\\\\db\\\\PDOConnection::.*~',
|
||||
'note' => 'PDO 连接层查询执行(真实形态实测)',
|
||||
'threshold_ms' => 500,
|
||||
],
|
||||
[
|
||||
'name' => '业务层控制器',
|
||||
'regex' => '~app\\\\admin\\\\controller\\\\.*~',
|
||||
'note' => '控制器中心主义,业务逻辑所在',
|
||||
'threshold_ms' => 1000,
|
||||
],
|
||||
[
|
||||
'name' => '数据保存操作',
|
||||
'regex' => '~.*::save$~',
|
||||
'note' => 'Model/log/session 的 save 调用',
|
||||
'threshold_ms' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$sql = sprintf(
|
||||
"INSERT INTO `%sxhprof_watch` (`name`, `regex`, `note`, `threshold_ms`, `status`, `create_time`, `update_time`) VALUES (%s, %s, %s, %d, 1, %d, %d) ON DUPLICATE KEY UPDATE `id` = `id`",
|
||||
$this->getAdapter()->getOption('table_prefix'),
|
||||
$this->quoteLiteral($row['name']),
|
||||
$this->quoteLiteral($row['regex']),
|
||||
$this->quoteLiteral($row['note']),
|
||||
$row['threshold_ms'],
|
||||
$now,
|
||||
$now
|
||||
);
|
||||
$this->execute($sql);
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$prefix = $this->getAdapter()->getOption('table_prefix');
|
||||
$regexes = implode(', ', array_map(function ($regex) {
|
||||
return $this->quoteLiteral($regex);
|
||||
}, [
|
||||
'~think\\\\db\\\\PDOConnection::.*~',
|
||||
'~app\\\\admin\\\\controller\\\\.*~',
|
||||
'~.*::save$~',
|
||||
]));
|
||||
$this->execute("DELETE FROM `{$prefix}xhprof_watch` WHERE `regex` IN ({$regexes})");
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQL 字面量包装:单引号包裹 + 反斜杠转义(保证落库值与 PHP 值逐字符一致).
|
||||
*/
|
||||
private function quoteLiteral(string $value): string
|
||||
{
|
||||
return "'" . addcslashes($value, "\\") . "'";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user