You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
flowchart TD
A["GET 操作日志"] --> B["SystemLogModelViewSet.get_queryset<br/>operator_log.py"]
B --> C["filter_operator_log_queryset_for_request<br/>permission_scope.py"]
C --> D["物化全部可见 Alert ID"]
C --> E["物化全部可见 Incident ID"]
D --> F["OperatorLog target_id IN 过滤"]
E --> F
F -.-> G["最后执行分页"]
权限可见范围属于安全边界,虽然目标是等价的查询重写,仍应按迁移验证。用旧实现结果作为 oracle,覆盖超级管理员、无 current team、父子组织、数字/字符串 team ID、空范围、Alert/Incident 混合日志、详情访问和多页排序,确保既不扩大也不缩小既有合法可见集。先灰度比对新旧 ID 集合和查询计划;查询可用特性开关回退,索引可反向 migration 回滚。
严重性判断
这是操作日志每次访问都经过的权限过滤,成本在分页前按组织完整历史规模增长,且超长 IN 会同时影响应用和数据库;当前没有已测得的生产超时或权限错误,因此定为 Medium。
现象
用户只查看一页操作日志时,服务会先把其组织范围内全部告警 ID 和事故 ID 读取成两个 Python 列表,再把它们塞进日志查询。正常情况下分页查询应让数据库完成关联过滤;数据量大时,取一页日志也要搬运完整业务对象 ID 集合。
触发场景
有
operation_log-View权限的用户调用操作日志列表或详情接口时触发。只要请求带有当前团队,权限函数就会在分页之前物化该团队可见的全部历史告警和事故 ID,与本次日志页大小无关。业务影响
每次请求额外执行两次全量 ID 查询,Python 内存、数据传输和后续
IN参数数量随可见告警A与事故I以O(A+I)增长。大型组织可能遭遇超长 SQL、参数上限、计划退化或明显延迟,而最终只返回一个分页结果。根因(设计层)
权限边界本可保持为数据库子查询,却在拼接日志过滤条件前被强制物化:
随后两个列表进入
target_id__in。同时OperatorLog只有created_at单列索引,没有匹配target_type、target_id与分页排序的组合索引。涉及文件
server/apps/alerts/utils/permission_scope.py:136server/apps/alerts/utils/permission_scope.py:145server/apps/alerts/views/operator_log.py:23server/apps/alerts/models/operator_log.py:10调用链
flowchart TD A["GET 操作日志"] --> B["SystemLogModelViewSet.get_queryset<br/>operator_log.py"] B --> C["filter_operator_log_queryset_for_request<br/>permission_scope.py"] C --> D["物化全部可见 Alert ID"] C --> E["物化全部可见 Incident ID"] D --> F["OperatorLog target_id IN 过滤"] E --> F F -.-> G["最后执行分页"]证据 / 复现
weops/master第 145 至 146 行对两个values_list显式调用list,第 150 至 155 行再生成两个target_id__in条件。视图第 23 至 31 行先取得该 queryset,分页由父类后续执行。模型第 30 行仅给created_at建索引。建议分别构造 1k、10k、100k 个团队可见目标,统计查询数、生成 SQL 长度、数据库耗时和 Python 峰值内存。当前 ID 传输、内存及
IN参数为O(A+I);优化后不应出现 eager ID 查询,SQL 文本和 Python 内存应基本不随A+I增长。建议修复方向
使用
Subquery或Exists保持两类权限过滤在数据库内完成,并根据实际查询计划增加target_type、target_id、created_at的组合索引。保持当前团队解析、组织 JSON 范围、Alert/Incident 分支、空范围返回 none、distinct和默认倒序分页不变。功能影响 / 回归风险
权限可见范围属于安全边界,虽然目标是等价的查询重写,仍应按迁移验证。用旧实现结果作为 oracle,覆盖超级管理员、无 current team、父子组织、数字/字符串 team ID、空范围、Alert/Incident 混合日志、详情访问和多页排序,确保既不扩大也不缩小既有合法可见集。先灰度比对新旧 ID 集合和查询计划;查询可用特性开关回退,索引可反向 migration 回滚。
严重性判断
这是操作日志每次访问都经过的权限过滤,成本在分页前按组织完整历史规模增长,且超长
IN会同时影响应用和数据库;当前没有已测得的生产超时或权限错误,因此定为 Medium。严重度:Medium 工作量:M
负责人:@zhaojinmeng