feat(admin): XHProf 性能日志五张表 Scheme 迁移与模型

This commit is contained in:
augushong
2026-08-14 22:04:52 +08:00
parent da388a8c4f
commit 7e73902325
15 changed files with 478 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
<?php
use think\migration\Migrator;
/**
* XHProf 性能日志 - 采样记录表
*
* 每次被采样的请求一条记录。耗时字段库内统一微秒、内存统一字节,展示层换算。
*/
class XhprofRun extends Migrator
{
public function change()
{
$table = $this->table('xhprof_run', ['id' => false, 'primary_key' => ['id']])
->setComment('XHProf 性能采样记录(每次请求一条)')
->addColumn('id', 'integer', ['limit' => 11, 'null' => false, 'signed' => false, 'identity' => true, 'comment' => '主键ID'])
->addColumn('node_id', 'string', ['limit' => 64, 'null' => false, 'default' => 'default', 'comment' => '节点ID区分不同采集节点'])
->addColumn('url', 'string', ['limit' => 500, 'null' => false, 'comment' => '请求完整 URL超长截断'])
->addColumn('simple_url', 'string', ['limit' => 255, 'null' => false, 'default' => '', 'comment' => '规范化 URL去 query、数字段替换聚合用'])
->addColumn('method', 'string', ['limit' => 10, 'null' => false, 'default' => '', 'comment' => 'HTTP 方法'])
->addColumn('wall_time', 'biginteger', ['default' => 0, 'comment' => '总耗时微秒main() 的 wt'])
->addColumn('cpu_time', 'biginteger', ['default' => 0, 'comment' => 'CPU 耗时微秒main() 的 cpu'])
->addColumn('memory_peak', 'biginteger', ['default' => 0, 'comment' => '内存峰值字节main() 的 pmu'])
->addColumn('request_time', 'decimal', ['precision' => 12, 'scale' => 3, 'default' => 0, 'comment' => '请求开始时间REQUEST_TIME_FLOAT 浮点秒)'])
->addColumn('create_time', 'integer', ['limit' => 11, 'comment' => '入库时间戳', 'signed' => false])
->addIndex(['simple_url', 'request_time'], ['name' => 'idx_simple_url_time'])
->addIndex(['request_time'], ['name' => 'idx_request_time'])
->addIndex(['wall_time'], ['name' => 'idx_wall_time'])
->create();
}
}

View File

@@ -0,0 +1,22 @@
<?php
use think\migration\Migrator;
use Phinx\Db\Adapter\MysqlAdapter;
/**
* XHProf 性能日志 - 采样原始 profile 数据表
*
* 显式豁免表:不进后台(无 CURD 页面)、无 create_time 等约定字段、无额外索引。
* id 与 ul_xhprof_run.id 一一对应(非自增),查询入口即主键。
*/
class XhprofRunDetail extends Migrator
{
public function change()
{
$table = $this->table('xhprof_run_detail', ['id' => false, 'primary_key' => ['id']])
->setComment('XHProf 采样原始 profile 数据(按 run 1:1不进后台')
->addColumn('id', 'integer', ['limit' => 11, 'null' => false, 'signed' => false, 'comment' => '主键,值=ul_xhprof_run.id不自增'])
->addColumn('profile_data', 'text', ['length' => MysqlAdapter::TEXT_LONG, 'null' => true, 'comment' => '原始 profile JSON'])
->create();
}
}

View File

@@ -0,0 +1,27 @@
<?php
use think\migration\Migrator;
/**
* XHProf 性能日志 - 函数监控规则表
*
* regex 为 PCRE 正则导入任务按被调用callee函数名匹配命中边聚合到 run_watch 表。
*/
class XhprofWatch extends Migrator
{
public function change()
{
$table = $this->table('xhprof_watch', ['id' => false, 'primary_key' => ['id']])
->setComment('XHProf 函数监控规则')
->addColumn('id', 'integer', ['limit' => 11, 'null' => false, 'signed' => false, 'identity' => true, 'comment' => '主键ID'])
->addColumn('name', 'string', ['limit' => 100, 'null' => false, 'comment' => '规则名称(人读)'])
->addColumn('regex', 'string', ['limit' => 255, 'null' => false, 'comment' => 'PCRE 正则(对被调用函数名匹配)'])
->addColumn('note', 'string', ['limit' => 255, 'null' => false, 'default' => '', 'comment' => '备注'])
->addColumn('threshold_ms', 'integer', ['limit' => 11, 'default' => 0, 'comment' => '比对阈值毫秒0=不比对'])
->addColumn('status', 'tinyinteger', ['limit' => 4, 'default' => 1, 'comment' => '状态:1=启用,0=禁用'])
->addColumn('create_time', 'integer', ['limit' => 11, 'comment' => '创建时间戳', 'signed' => false])
->addColumn('update_time', 'integer', ['limit' => 11, 'comment' => '更新时间戳', 'signed' => false])
->addIndex(['regex'], ['unique' => true, 'name' => 'uniq_regex'])
->create();
}
}

View File

@@ -0,0 +1,27 @@
<?php
use think\migration\Migrator;
/**
* XHProf 性能日志 - 采样与监控规则命中聚合表
*
* 导入任务解析 profile 时按启用规则物化(每 run × 每命中规则一条),页面零计算。
*/
class XhprofRunWatch extends Migrator
{
public function change()
{
$table = $this->table('xhprof_run_watch', ['id' => false, 'primary_key' => ['id']])
->setComment('XHProf 采样与监控规则命中聚合(导入时物化)')
->addColumn('id', 'integer', ['limit' => 11, 'null' => false, 'signed' => false, 'identity' => true, 'comment' => '主键ID'])
->addColumn('run_id', 'integer', ['limit' => 11, 'default' => 0, 'comment' => '采样记录IDul_xhprof_run.id', 'signed' => false])
->addColumn('watch_id', 'integer', ['limit' => 11, 'default' => 0, 'comment' => '监控规则IDul_xhprof_watch.id', 'signed' => false])
->addColumn('ct', 'integer', ['limit' => 11, 'default' => 0, 'comment' => '命中边次数和'])
->addColumn('wt_sum', 'biginteger', ['default' => 0, 'comment' => '命中耗时合计(微秒)'])
->addColumn('wt_max', 'biginteger', ['default' => 0, 'comment' => '命中单次最大耗时(微秒)'])
->addColumn('create_time', 'integer', ['limit' => 11, 'comment' => '入库时间戳', 'signed' => false])
->addIndex(['watch_id', 'create_time'], ['name' => 'idx_watch_time'])
->addIndex(['run_id'], ['name' => 'idx_run_id'])
->create();
}
}

View File

@@ -0,0 +1,31 @@
<?php
use think\migration\Migrator;
/**
* XHProf 性能日志 - 文件读取位置表
*
* 记录每个 runs-*.jsonl 文件的 inode/offset/最近读取时间/失败计数等增量读取状态。
* 唯一键 uniq_node_file(node_id, file_path):多节点导各自文件互不覆盖。
*/
class XhprofLogPosition extends Migrator
{
public function change()
{
$table = $this->table('xhprof_log_position', ['id' => false, 'primary_key' => ['id']])
->setComment('XHProf 日志文件读取位置(增量读取状态)')
->addColumn('id', 'integer', ['limit' => 11, 'null' => false, 'signed' => false, 'identity' => true, 'comment' => '主键ID'])
->addColumn('node_id', 'string', ['limit' => 64, 'null' => false, 'default' => '', 'comment' => '节点ID区分不同采集节点'])
->addColumn('file_path', 'string', ['limit' => 500, 'null' => false, 'comment' => '日志文件绝对路径'])
->addColumn('inode', 'biginteger', ['default' => 0, 'comment' => '文件 inode用于检测日志轮转', 'signed' => false])
->addColumn('offset', 'biginteger', ['default' => 0, 'comment' => '上次读取到的字节偏移', 'signed' => false])
->addColumn('last_read_time', 'integer', ['limit' => 11, 'default' => 0, 'comment' => '上次读取时间戳', 'signed' => false])
->addColumn('last_line_hash', 'string', ['limit' => 32, 'default' => '', 'comment' => '上次最后一行的 md5 哈希(容错校验)'])
->addColumn('parse_fail_count', 'integer', ['limit' => 11, 'default' => 0, 'comment' => '解析失败累计次数', 'signed' => false])
->addColumn('parse_fail_samples', 'text', ['null' => true, 'comment' => '解析失败样本行(最多保留若干条)'])
->addColumn('create_time', 'integer', ['limit' => 11, 'comment' => '创建时间戳', 'signed' => false])
->addColumn('update_time', 'integer', ['limit' => 11, 'comment' => '更新时间戳', 'signed' => false])
->addIndex(['node_id', 'file_path'], ['unique' => true, 'name' => 'uniq_node_file'])
->create();
}
}