mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-08-30 12:45:32 +08:00
feat(admin): XHProf 采样列表页
- curd -t ul_xhprof_run 生成三件套(控制器 xhprof.run 子目录形态,model docblock 随生成刷新) - 只读化:toolbar 清空 + 行内仅详情按钮(open 弹层 xhprof.run/detail?id=N,auth=detail), add/edit/delete 等 action 保留靠权限节点不分配拦截(T8 对齐) - 列渲染:wall_time/cpu_time μs→ms(>1000ms 红色)、memory_peak 字节→MB、 url 截断 title 全显、method 标签化、request_time 浮点秒→日期时间 - 四组搜索:url like / request_time range / wall_time 下限(前端 ms,后端换算 μs, withGet 全量合并写回)/ node_id 下拉(DISTINCT + data_brage 通道) - 生成前 scheme:sync 修复 request_time 的 null/comment 漂移(T3 手工 ALTER 遗留)
This commit is contained in:
81
app/admin/controller/xhprof/Run.php
Normal file
81
app/admin/controller/xhprof/Run.php
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\admin\controller\xhprof;
|
||||||
|
|
||||||
|
use app\common\controller\AdminController;
|
||||||
|
use app\admin\service\annotation\ControllerAnnotation;
|
||||||
|
use app\admin\service\annotation\NodeAnotation;
|
||||||
|
use think\App;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XHProf 性能采样记录(只读列表)
|
||||||
|
* 数据由定时任务从 jsonl 导入,后台仅查看与函数级分析,不支持手动增删改。
|
||||||
|
*
|
||||||
|
* @ControllerAnnotation(title="XHProf 性能采样记录")
|
||||||
|
*/
|
||||||
|
class Run extends AdminController
|
||||||
|
{
|
||||||
|
|
||||||
|
use \app\admin\traits\Curd;
|
||||||
|
|
||||||
|
protected $sort = [
|
||||||
|
'request_time' => 'desc',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct(App $app)
|
||||||
|
{
|
||||||
|
parent::__construct($app);
|
||||||
|
|
||||||
|
$this->model = new \app\admin\model\XhprofRun();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NodeAnotation(title="列表")
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
|
if (input('selectFields')) {
|
||||||
|
return $this->selectList();
|
||||||
|
}
|
||||||
|
// wall_time 搜索下限:前端输入毫秒,换算为微秒后再构建查询条件
|
||||||
|
// 注意:Request::withGet 是整体替换,必须先取全量 GET 再合并写回
|
||||||
|
$filter = (string) $this->request->get('filter', '');
|
||||||
|
if ($filter !== '') {
|
||||||
|
$filterArr = json_decode($filter, true) ?: [];
|
||||||
|
if (isset($filterArr['wall_time']) && $filterArr['wall_time'] !== '') {
|
||||||
|
$filterArr['wall_time'] = (string) ((float) $filterArr['wall_time'] * 1000);
|
||||||
|
$this->request->withGet(array_merge($this->request->get(), [
|
||||||
|
'filter' => json_encode($filterArr, JSON_UNESCAPED_UNICODE),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list($page, $limit, $where, $excludes, $request_options, $group) = $this->buildTableParames();
|
||||||
|
$count = $this->model
|
||||||
|
->where($where)
|
||||||
|
->group($group)
|
||||||
|
->count();
|
||||||
|
$list = $this->model
|
||||||
|
->where($where)
|
||||||
|
->page($page, $limit)
|
||||||
|
->order($this->sort)
|
||||||
|
->group($group)
|
||||||
|
->select();
|
||||||
|
$data = [
|
||||||
|
'code' => 0,
|
||||||
|
'msg' => '',
|
||||||
|
'count' => $count,
|
||||||
|
'data' => $list,
|
||||||
|
];
|
||||||
|
|
||||||
|
return json($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 节点下拉选项(多节点环境区分数据来源)
|
||||||
|
$nodeIds = $this->model->distinct(true)->column('node_id');
|
||||||
|
$nodeSelect = array_combine($nodeIds, $nodeIds) ?: [];
|
||||||
|
$this->assign('select_list_node_id', $nodeSelect, true);
|
||||||
|
|
||||||
|
return $this->fetch();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,16 +5,16 @@ namespace app\admin\model;
|
|||||||
use app\common\model\TimeModel;
|
use app\common\model\TimeModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property int $id 主键ID
|
* @property int $id
|
||||||
* @property string $node_id 节点ID(区分不同采集节点)
|
* @property string $node_id 节点ID(区分不同采集节点)
|
||||||
* @property string $url 请求完整 URL(超长截断)
|
* @property string $url 请求完整 URL(超长截断)
|
||||||
* @property string $simple_url 规范化 URL(去 query、数字段替换,聚合用)
|
* @property string $simple_url 规范化 URL(去 query、数字段替换,聚合用)
|
||||||
* @property string $method HTTP 方法
|
* @property string $method HTTP 方法
|
||||||
* @property int $wall_time 总耗时(微秒,main() 的 wt)
|
* @property int $wall_time 总耗时(微秒,main 的 wt)
|
||||||
* @property int $cpu_time CPU 耗时(微秒,main() 的 cpu)
|
* @property int $cpu_time CPU 耗时(微秒,main 的 cpu)
|
||||||
* @property int $memory_peak 内存峰值(字节,main() 的 pmu)
|
* @property int $memory_peak 内存峰值(字节,main 的 pmu)
|
||||||
* @property string $request_time 请求开始时间(REQUEST_TIME_FLOAT 浮点秒)
|
* @property float|double $request_time 请求开始时间(REQUEST_TIME_FLOAT 浮点秒)
|
||||||
* @property int $create_time 入库时间戳
|
* @property int $create_time 入库时间戳
|
||||||
*/
|
*/
|
||||||
class XhprofRun extends TimeModel
|
class XhprofRun extends TimeModel
|
||||||
{
|
{
|
||||||
@@ -23,4 +23,8 @@ class XhprofRun extends TimeModel
|
|||||||
|
|
||||||
protected $deleteTime = false;
|
protected $deleteTime = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
app/admin/view/xhprof/run/_common.js
Normal file
12
app/admin/view/xhprof/run/_common.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
var init = {
|
||||||
|
tableElem: '#currentTable',
|
||||||
|
tableRenderId: 'currentTableRenderId',
|
||||||
|
indexUrl: 'xhprof.run/index',
|
||||||
|
addUrl: '',
|
||||||
|
editUrl: '',
|
||||||
|
readUrl: '',
|
||||||
|
deleteUrl: '',
|
||||||
|
exportUrl: '',
|
||||||
|
modifyUrl: '',
|
||||||
|
detailUrl: 'xhprof.run/detail',
|
||||||
|
};
|
||||||
62
app/admin/view/xhprof/run/add.html
Normal file
62
app/admin/view/xhprof/run/add.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<div class="layuimini-container">
|
||||||
|
<form id="app-form" class="layui-form layuimini-form">
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">节点ID(区分不同采集节点)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="node_id" class="layui-input" lay-verify="required" placeholder="请输入节点ID(区分不同采集节点)" value="{$Request.param.node_id|default='default'}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">请求完整 URL(超长截断)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="url" class="layui-input" lay-verify="required" placeholder="请输入请求完整 URL(超长截断)" value="{$Request.param.url|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">规范化 URL(去 query、数字段替换,聚合用)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="simple_url" class="layui-input" lay-verify="required" placeholder="请输入规范化 URL(去 query、数字段替换,聚合用)" value="{$Request.param.simple_url|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">HTTP 方法</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="method" class="layui-input" lay-verify="required" placeholder="请输入HTTP 方法" value="{$Request.param.method|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">总耗时(微秒,main 的 wt)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="wall_time" class="layui-input" placeholder="请输入总耗时(微秒,main 的 wt)" value="{$Request.param.wall_time|default='0'}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">CPU 耗时(微秒,main 的 cpu)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="cpu_time" class="layui-input" placeholder="请输入CPU 耗时(微秒,main 的 cpu)" value="{$Request.param.cpu_time|default='0'}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">内存峰值(字节,main 的 pmu)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="memory_peak" class="layui-input" placeholder="请输入内存峰值(字节,main 的 pmu)" value="{$Request.param.memory_peak|default='0'}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">请求开始时间(REQUEST_TIME_FLOAT 浮点秒)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="request_time" class="layui-input" placeholder="请输入请求开始时间(REQUEST_TIME_FLOAT 浮点秒)" value="{$Request.param.request_time|default='0.000'}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hr-line"></div>
|
||||||
|
<div class="layui-form-item text-center">
|
||||||
|
{notempty name='$Request.param.backTagId'}
|
||||||
|
<div class="layui-btn layui-btn-sm page-back-button" layuimini-content-href="{$Request.param.backTagId}" data-back="1">返回</div>
|
||||||
|
{/notempty}
|
||||||
|
<button type="submit" class="layui-btn layui-btn-normal layui-btn-sm" lay-submit>确认</button>
|
||||||
|
<button type="reset" class="layui-btn layui-btn-primary layui-btn-sm">重置</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
3
app/admin/view/xhprof/run/add.js
Normal file
3
app/admin/view/xhprof/run/add.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
$(function(){
|
||||||
|
ua.listen();
|
||||||
|
})
|
||||||
62
app/admin/view/xhprof/run/edit.html
Normal file
62
app/admin/view/xhprof/run/edit.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<div class="layuimini-container">
|
||||||
|
<form id="app-form" class="layui-form layuimini-form">
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">节点ID(区分不同采集节点)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="node_id" class="layui-input" lay-verify="required" placeholder="请输入节点ID(区分不同采集节点)" value="{$row.node_id|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">请求完整 URL(超长截断)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="url" class="layui-input" lay-verify="required" placeholder="请输入请求完整 URL(超长截断)" value="{$row.url|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">规范化 URL(去 query、数字段替换,聚合用)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="simple_url" class="layui-input" lay-verify="required" placeholder="请输入规范化 URL(去 query、数字段替换,聚合用)" value="{$row.simple_url|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">HTTP 方法</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="method" class="layui-input" lay-verify="required" placeholder="请输入HTTP 方法" value="{$row.method|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">总耗时(微秒,main 的 wt)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="wall_time" class="layui-input" placeholder="请输入总耗时(微秒,main 的 wt)" value="{$row.wall_time|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">CPU 耗时(微秒,main 的 cpu)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="cpu_time" class="layui-input" placeholder="请输入CPU 耗时(微秒,main 的 cpu)" value="{$row.cpu_time|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">内存峰值(字节,main 的 pmu)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="memory_peak" class="layui-input" placeholder="请输入内存峰值(字节,main 的 pmu)" value="{$row.memory_peak|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">请求开始时间(REQUEST_TIME_FLOAT 浮点秒)</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="request_time" class="layui-input" placeholder="请输入请求开始时间(REQUEST_TIME_FLOAT 浮点秒)" value="{$row.request_time|default=''}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hr-line"></div>
|
||||||
|
<div class="layui-form-item text-center">
|
||||||
|
{notempty name='$Request.param.backTagId'}
|
||||||
|
<div class="layui-btn layui-btn-sm page-back-button" layuimini-content-href="{$Request.param.backTagId}" data-back="1">返回</div>
|
||||||
|
{/notempty}
|
||||||
|
<button type="submit" class="layui-btn layui-btn-normal layui-btn-sm" lay-submit>确认</button>
|
||||||
|
<button type="reset" class="layui-btn layui-btn-primary layui-btn-sm">重置</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
3
app/admin/view/xhprof/run/edit.js
Normal file
3
app/admin/view/xhprof/run/edit.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
$(function(){
|
||||||
|
ua.listen();
|
||||||
|
})
|
||||||
9
app/admin/view/xhprof/run/index.html
Normal file
9
app/admin/view/xhprof/run/index.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<div class="layuimini-container">
|
||||||
|
<div class="layuimini-main">
|
||||||
|
<table id="currentTable" class="layui-table layui-hide"
|
||||||
|
data-auth-index="{:auth('xhprof.run/index')}"
|
||||||
|
data-auth-detail="{:auth('xhprof.run/detail')}"
|
||||||
|
lay-filter="currentTable">
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
92
app/admin/view/xhprof/run/index.js
Normal file
92
app/admin/view/xhprof/run/index.js
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
$(function () {
|
||||||
|
// request_time 为浮点秒(decimal(13,3)),渲染为日期时间
|
||||||
|
var formatRequestTime = function (d) {
|
||||||
|
var t = parseFloat(d.request_time);
|
||||||
|
if (!t || isNaN(t)) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
var dt = new Date(t * 1000);
|
||||||
|
var p = function (n) {
|
||||||
|
return n < 10 ? '0' + n : '' + n;
|
||||||
|
};
|
||||||
|
return dt.getFullYear() + '-' + p(dt.getMonth() + 1) + '-' + p(dt.getDate())
|
||||||
|
+ ' ' + p(dt.getHours()) + ':' + p(dt.getMinutes()) + ':' + p(dt.getSeconds());
|
||||||
|
};
|
||||||
|
|
||||||
|
ua.table.render({
|
||||||
|
init: init,
|
||||||
|
toolbar: [],
|
||||||
|
defaultToolbar: ['filter'],
|
||||||
|
cols: [[
|
||||||
|
{field: 'request_time', title: '请求时间', width: 170, sort: true, search: 'range', templet: formatRequestTime},
|
||||||
|
{
|
||||||
|
field: 'method', title: '方法', width: 90, search: 'select', selectList: {
|
||||||
|
GET: 'GET', POST: 'POST', PUT: 'PUT', DELETE: 'DELETE', HEAD: 'HEAD', OPTIONS: 'OPTIONS', PATCH: 'PATCH'
|
||||||
|
}, templet: function (d) {
|
||||||
|
var cls = {
|
||||||
|
GET: 'layui-bg-blue',
|
||||||
|
POST: 'layui-bg-green',
|
||||||
|
PUT: 'layui-bg-orange',
|
||||||
|
DELETE: 'layui-bg-red',
|
||||||
|
HEAD: 'layui-bg-gray',
|
||||||
|
OPTIONS: 'layui-bg-gray',
|
||||||
|
PATCH: 'layui-bg-cyan'
|
||||||
|
}[d.method];
|
||||||
|
if (d.method && cls) {
|
||||||
|
return '<span class="layui-badge ' + cls + '">' + d.method + '</span>';
|
||||||
|
}
|
||||||
|
return d.method || '-';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'url', title: 'URL', minWidth: 220, searchOp: '%*%', templet: function (d) {
|
||||||
|
var u = d.url || '';
|
||||||
|
var short = u.length > 50 ? u.substring(0, 50) + '…' : u;
|
||||||
|
return '<span title="' + u.replace(/"/g, '"') + '">' + (short === '' ? '/' : short) + '</span>';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{field: 'node_id', title: '节点', width: 160, search: 'select', searchOp: '=', selectList: ua.getDataBrage('select_list_node_id') || {}},
|
||||||
|
{
|
||||||
|
field: 'wall_time', title: '总耗时', width: 110, sort: true, searchOp: 'min', searchTip: '总耗时下限(ms)', templet: function (d) {
|
||||||
|
var ms = parseInt(d.wall_time, 10) / 1000;
|
||||||
|
var txt = ms.toFixed(1) + 'ms';
|
||||||
|
if (ms > 1000) {
|
||||||
|
return '<span class="layui-badge layui-bg-red">' + txt + '</span>';
|
||||||
|
}
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'cpu_time', title: 'CPU耗时', width: 110, search: false, templet: function (d) {
|
||||||
|
var ms = parseInt(d.cpu_time, 10) / 1000;
|
||||||
|
var txt = ms.toFixed(1) + 'ms';
|
||||||
|
if (ms > 1000) {
|
||||||
|
return '<span class="layui-badge layui-bg-red">' + txt + '</span>';
|
||||||
|
}
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'memory_peak', title: '内存峰值', width: 110, sort: true, search: false, templet: function (d) {
|
||||||
|
return (parseInt(d.memory_peak, 10) / 1048576).toFixed(2) + 'MB';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 100, title: '操作', fixed: 'right', templet: ua.table.tool, operat: [
|
||||||
|
[{
|
||||||
|
class: 'layui-btn layui-btn-primary layui-btn-xs',
|
||||||
|
method: 'open',
|
||||||
|
field: 'id',
|
||||||
|
text: '详情',
|
||||||
|
title: '采样详情(函数级分析)',
|
||||||
|
auth: 'detail',
|
||||||
|
url: init.detailUrl,
|
||||||
|
extend: 'data-full="true"'
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]]
|
||||||
|
});
|
||||||
|
|
||||||
|
ua.listen();
|
||||||
|
});
|
||||||
129
app/admin/view/xhprof/run/read.html
Normal file
129
app/admin/view/xhprof/run/read.html
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<div class="layuimini-container detail-container">
|
||||||
|
<div class="layuimini-main">
|
||||||
|
<div class="layui-card detail-card">
|
||||||
|
<div class="layui-card-header detail-header">
|
||||||
|
<div class="layui-row">
|
||||||
|
<div class="layui-col-md9">
|
||||||
|
<h2 class="detail-title">#{$row.id} {$title}</h2>
|
||||||
|
<div class="detail-id">ID: {$row.id}</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-col-md3 text-right detail-actions">
|
||||||
|
<button class="layui-btn layui-btn-primary" layuimini-content-href="{$Request.param.backTagId}" data-back="1">返回</button>
|
||||||
|
<button class="layui-btn" onclick="location.href='{:url("edit", ["id" => $row.id])}'">编辑</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-card-body detail-content">
|
||||||
|
<div class="layui-row layui-col-space12">
|
||||||
|
<!-- 左侧主体内容 -->
|
||||||
|
<div class="layui-col-md8 detail-main">
|
||||||
|
<div class="detail-field-group">
|
||||||
|
<div class="detail-field-item">
|
||||||
|
<div class="detail-field-label">节点ID(区分不同采集节点)</div>
|
||||||
|
<div class="detail-field-value">
|
||||||
|
{notempty name="row.node_id"}
|
||||||
|
{$row.node_id}
|
||||||
|
{else/}
|
||||||
|
<span class="layui-text-em">暂无数据</span>
|
||||||
|
{/notempty}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-field-item">
|
||||||
|
<div class="detail-field-label">请求完整 URL(超长截断)</div>
|
||||||
|
<div class="detail-field-value">
|
||||||
|
{notempty name="row.url"}
|
||||||
|
{$row.url}
|
||||||
|
{else/}
|
||||||
|
<span class="layui-text-em">暂无数据</span>
|
||||||
|
{/notempty}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-field-item">
|
||||||
|
<div class="detail-field-label">规范化 URL(去 query、数字段替换,聚合用)</div>
|
||||||
|
<div class="detail-field-value">
|
||||||
|
{notempty name="row.simple_url"}
|
||||||
|
{$row.simple_url}
|
||||||
|
{else/}
|
||||||
|
<span class="layui-text-em">暂无数据</span>
|
||||||
|
{/notempty}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-field-item">
|
||||||
|
<div class="detail-field-label">HTTP 方法</div>
|
||||||
|
<div class="detail-field-value">
|
||||||
|
{notempty name="row.method"}
|
||||||
|
{$row.method}
|
||||||
|
{else/}
|
||||||
|
<span class="layui-text-em">暂无数据</span>
|
||||||
|
{/notempty}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-field-item">
|
||||||
|
<div class="detail-field-label">总耗时(微秒,main 的 wt)</div>
|
||||||
|
<div class="detail-field-value">
|
||||||
|
{notempty name="row.wall_time"}
|
||||||
|
{$row.wall_time}
|
||||||
|
{else/}
|
||||||
|
<span class="layui-text-em">暂无数据</span>
|
||||||
|
{/notempty}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-field-item">
|
||||||
|
<div class="detail-field-label">CPU 耗时(微秒,main 的 cpu)</div>
|
||||||
|
<div class="detail-field-value">
|
||||||
|
{notempty name="row.cpu_time"}
|
||||||
|
{$row.cpu_time}
|
||||||
|
{else/}
|
||||||
|
<span class="layui-text-em">暂无数据</span>
|
||||||
|
{/notempty}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-field-item">
|
||||||
|
<div class="detail-field-label">内存峰值(字节,main 的 pmu)</div>
|
||||||
|
<div class="detail-field-value">
|
||||||
|
{notempty name="row.memory_peak"}
|
||||||
|
{$row.memory_peak}
|
||||||
|
{else/}
|
||||||
|
<span class="layui-text-em">暂无数据</span>
|
||||||
|
{/notempty}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-field-item">
|
||||||
|
<div class="detail-field-label">请求开始时间(REQUEST_TIME_FLOAT 浮点秒)</div>
|
||||||
|
<div class="detail-field-value">
|
||||||
|
{notempty name="row.request_time"}
|
||||||
|
{$row.request_time}
|
||||||
|
{else/}
|
||||||
|
<span class="layui-text-em">暂无数据</span>
|
||||||
|
{/notempty}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 右侧基础信息 -->
|
||||||
|
<div class="layui-col-md4 detail-side">
|
||||||
|
<h3 class="detail-side-title">基础信息</h3>
|
||||||
|
<div class="detail-field-group">
|
||||||
|
<div class="detail-field-item">
|
||||||
|
<div class="detail-field-label">ID</div>
|
||||||
|
<div class="detail-field-value">{$row.id}</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-field-item">
|
||||||
|
<div class="detail-field-label">入库时间戳</div>
|
||||||
|
<div class="detail-field-value">
|
||||||
|
{notempty name="row.create_time"}
|
||||||
|
{$row.create_time|date="Y-m-d H:i:s"}
|
||||||
|
{else/}
|
||||||
|
<span class="layui-text-em">暂无数据</span>
|
||||||
|
{/notempty}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
22
app/admin/view/xhprof/run/read.js
Normal file
22
app/admin/view/xhprof/run/read.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
$(function(){
|
||||||
|
// 删除数据
|
||||||
|
window.deleteData = function(id) {
|
||||||
|
layer.confirm('确定要删除这条数据吗?', {
|
||||||
|
icon: 3,
|
||||||
|
title: '提示'
|
||||||
|
}, function(index) {
|
||||||
|
$.post('{{:url("delete")}}', {id: id}, function(res) {
|
||||||
|
if (res.code == 0) {
|
||||||
|
layer.msg('删除成功', {icon: 1}, function() {
|
||||||
|
location.href = '{{:url("index")}}';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
layer.msg(res.msg, {icon: 2});
|
||||||
|
}
|
||||||
|
}, 'json');
|
||||||
|
layer.close(index);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ua.listen();
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user