Files
ulthon_admin/extend/base/admin/controller/nginx/AccessLogBase.php
augushong 8faa52ce90 feat(nginx-log): 多节点适配(node_id 全链路 + 全局/按节点聚合 + 节点筛选 + v2.4.0 升级脚本)
- 6 张表加 node_id 字段 + position/stat 改复合唯一键(migration)
- 6 个 Scheme 同步 node_id 注解 + 唯一键
- Reader 带 node_id 参数 + 懒加载接管(getLastPosition 回退查 node_id='')
- Aggregator 全局行(node_id='')+ 按节点循环 insertAggregatesForScope
- Stat 所有查询方法加 where node_id 条件
- Dashboard 控制器/视图加节点筛选下拉框 + AJAX 带 node_id
- AccessLog 列表加节点列 + 采集进度卡片显示节点信息
- import 定时任务 run_type 改 all(每节点采集自己的日志)
- v2.4.0 升级脚本追加 ALTER TABLE(幂等 check-then-alter)
- 菜单调整:去掉 Nginx 顶级菜单 + 读取位置管理,改为系统管理下挂两个子菜单
- ulthon-timer 文档补充 run_type=all 多节点部署注意事项
2026-08-08 10:33:20 +08:00

125 lines
3.1 KiB
PHP

<?php
namespace base\admin\controller\nginx;
use app\common\controller\AdminController;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnotation;
use think\App;
/**
* @ControllerAnnotation(title="nginx 访问日志明细(解析入库)")
*/
class AccessLogBase extends AdminController
{
use \app\admin\traits\Curd;
protected $sort = [
'time_local' => 'desc',
];
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\admin\model\NginxAccessLog();
}
/**
* @NodeAnotation(title="列表")
*/
public function index()
{
if ($this->request->isAjax()) {
if (input('selectFields')) {
return $this->selectList();
}
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);
}
// 采集位置信息(合并自原"读取位置管理"独立页面)
$positions = \app\admin\model\NginxLogPosition::order('id', 'desc')->select()->map(function ($item) {
$bytes = (int) $item['offset'];
if ($bytes >= 1048576) {
$item['offset_human'] = number_format($bytes / 1048576, 2) . ' MB';
} elseif ($bytes >= 1024) {
$item['offset_human'] = number_format($bytes / 1024, 2) . ' KB';
} else {
$item['offset_human'] = $bytes . ' B';
}
$item['last_read_time_text'] = $item['last_read_time'] > 0
? date('Y-m-d H:i:s', (int) $item['last_read_time'])
: '-';
return $item;
});
$this->assign('positions', $positions);
return $this->fetch();
}
/**
* @NodeAnotation(title="详情")
*/
public function read($id)
{
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
$this->assign('row', $row);
return $this->fetch();
}
/**
* @NodeAnotation(title="添加")
*/
public function add()
{
$this->error('日志表不允许手动添加');
}
/**
* @NodeAnotation(title="编辑")
*/
public function edit($id)
{
$this->error('日志表不允许编辑');
}
/**
* @NodeAnotation(title="删除")
*/
public function delete($id)
{
$this->error('日志表不允许删除');
}
/**
* @NodeAnotation(title="属性修改")
*/
public function modify()
{
$this->error('日志表不允许修改');
}
}