Files
tianxuan/.omo/plans/tianxiu-v5.md
T

13 KiB
Raw Blame History

天璇 v5 — 18 Issues Full Fix Plan

TL;DR (For humans)

修复上传管理、列检测、大规模数据处理、Globe可视化、聚类可视化等18个问题。


Workstream A: 上传管理修复 (Issues 1, 2, 3, 10, 11)

A1 重启后端后旧数据可分析

Files: analysis/views.py, analysis/session_store.py Root Cause: 旧分析的 AnalysisRun 记录在 DB 中,但 csv_glob 指向的目录是 %APPDATA%/TianXuan/data/uploads/{timestamp}/。重启后 session_store 内存清空,但上传文件仍在磁盘。globe_viewrun_detail 尝试加载旧运行时会调用 load_csv_directory(run.csv_glob) 重新读取 CSV。 Fix: 确保 load_csv_directory 能处理已删除的上传目录 → 优雅降级。在 globe_view_background_process 中添加 os.path.isdir() 检查,目录不存在时将 run 标记为 failed 并设置友好的错误消息。

A2 Web图标在所有页面显示

Files: templates/base.html, static/tianxuan/ Root Cause: base.html 没有 <link rel="icon">。浏览器自动请求 /favicon.ico 但项目无此文件。 Fix:

  1. 创建 static/tianxuan/favicon.svg 或使用基于主题的 HTML favicon
  2. base.html<head> 中添加 <link rel="icon" href="{% static 'tianxuan/favicon.ico' %}">

A3 上传按钮在页面顶部

File: templates/tianxuan/upload.html Root Cause: 上传 <form> 在 "已上传数据集" 表格之前,但上传按钮 (#submitBtn) 初始 display:none,只有在选择文件后才显示。 Fix: 将上传按钮移到 dropZone 下方、紧跟在选择文件后显示。或者将上传区域移到页面顶部的固定/粘性位置。

A10 Django文件上传无限制

Files: tianxuan/settings.py, analysis/views.py Root Cause: 当前限制:DATA_UPLOAD_MAX_NUMBER_FIELDS=10000DATA_UPLOAD_MAX_MEMORY_SIZE=50MBviews.py 中硬编码 2000 文件/10GB 总大小限制。用户说"只能上传100文件"可能是由于 FILE_UPLOAD_MAX_MEMORY_SIZE=10MB 导致大文件被写入临时文件时出现问题。 Fix:

  • 移除 DATA_UPLOAD_MAX_NUMBER_FIELDS 限制(设为 0 或大幅增加)
  • 增大 DATA_UPLOAD_MAX_MEMORY_SIZE 到 256MB
  • 移除 views.py 中的 2000 文件限制(改为仅警告)

A11 上传页删除功能完善

Files: templates/tianxuan/upload.html, analysis/views.py Root Cause: 删除按钮只显示在 statusready/completed/failed 的运行上。loading/profiling/aggregating 状态的运行没有删除按钮(可能是为了安全)。 Fix:

  • 修改模板,在所有状态下显示删除按钮(loading 状态时弹出确认:"后台处理中,删除将中断分析")
  • 确保 delete_upload 视图能安全处理正在处理的运行(shutil.rmtree + ORM delete

Workstream B: 列检测与类型分类修复 (Issues 7, 15, 18)

B7 TLS 0ver hex格式识别

Files: analysis/type_classifier.py, analysis/views.py, templates/tianxuan/globe.html Root Cause: 0ver 列名不在名称启发式规则中(需要 ^ver_ 前缀)。TLS版本检测在 views.py 中硬编码为 '1.3' in tls / '1.2' in tls,不知道 hex 格式如 03 03 (TLS 1.2) / 03 04 (TLS 1.3)。 Fix:

  1. type_classifier.py_NAME_TYPE_MAP 添加 0ver → ENUM 映射
  2. views.pyglobe_view 中添加 hex→TLS版本映射:
    TLS_HEX_MAP = {'0303': 'TLSv1.2', '0304': 'TLSv1.3', '0302': 'TLSv1.1', '0301': 'TLSv1.0'}
    hex_val = tls.replace(' ', '')  # "03 03" → "0303"
    tls_label = TLS_HEX_MAP.get(hex_val, 'other')
    
  3. Globe legend 添加对 hex 版本的说明

B15 "+"字符串被识别为数字

Files: analysis/type_classifier.py, analysis/data_loader.py Root Cause: 独立 +_coerce_to_float 中被列为 artifact(正常),但值如 +5+0.5 等前导加号的值会通过 float("+5") 解析。在 _values_to_type 中,LAT_LON 检测会过滤独立 +,但列中混有 + 和数字的列可能被分类为 FLOAT。 Fix:

  1. _values_to_type 的 FLOAT 检测步骤中,检查采样中是否有 +- 开头的字符串值
  2. 如果存在前导 +/- 且并非所有值都是有效数字,降级为 STRING
  3. _coerce_to_float 中添加对 + 前缀值的更严格检查

B18 根据真实列名配置实体检测

Files: analysis/entity_detector.py, analysis/entity_aggregator.py, config/config.yaml Changes:

  1. entity_detector.pyENTITY_KEYWORDS 添加用户全部列名
  2. entity_aggregator.py 的关键词集合添加用户列名
  3. config.yaml 更新 entity.ip_columns 和 column 覆盖
  4. type_classifier.py_NAME_TYPE_MAP 添加全部列名映射

用户列名映射表:

列名 类型 聚合用途 检测关键词
:ips IPv4 (已存在) src IP :ips
:ipd IPv4 (已存在) dst IP :ipd
:prs ENUM/端口 src port :prs
:prd ENUM/端口 dst port :prd
scnt STRING/ENUM source country scnt
dcnt STRING/ENUM dest country dcnt
server-ip IPv4 server IP server_ip
client-ip IPv4 client IP client_ip
0ver ENUM TLS version 0ver
cnam STRING cert common name cnam
snam STRING server name snam
4dur FLOAT duration 4dur
8ses FLOAT session offset 8ses
2tmo FLOAT timeout offset 2tmo
4ksz INT key size 4ksz
cnrs BOOL_ENUM recoverable cnrs
isrs BOOL_ENUM is recovered isrs
8ack INT backward bytes 8ack
8ppk INT payload packets 8ppk
8dbd TIMESTAMP db timestamp 8dbd
1ipp ENUM IP protocol 1ipp
4dbn ENUM database number 4dbn
tabl STRING table name tabl
name STRING link name name
source-node STRING source node source_node
cipher-suite HEX TLS cipher cipher_suite
ecdhe-named-curve STRING ECDHE curve ecdhe_named_curve
0cph HEX TLS cipher hex 0cph
0crv HEX TLS curve hex 0crv
0rnd STRING TLS random 0rnd
0rnt FLOAT/TIMESTAMP TLS random time 0rnt
4dbn STRING db number 4dbn
time TIMESTAMP time time
timestamp TIMESTAMP timestamp timestamp
row INT row number row
+.latd LAT_LON latitude (entity_aggregator 子串匹配) latd
+.lond LAT_LON longitude lond
+.ispn STRING ISP name ispn
+.orgn STRING org name orgn
+.city STRING city city

关键的 _find_column 改进 entity_aggregator.py 中的 _find_column 使用严格匹配。对于 :prs 需要匹配 dst_port keywords → 不匹配。需要在 _find_column 中添加 +: 前缀剥离:

normalised = name.lower().lstrip(':+').replace('-', '_').replace(' ', '_')

Lat/Lon 列检测修复 +.latd / +.lond 列:

  • type_classifier._values_to_type 中如果值 max_abs ≤ 10 则 LAT_LON 检测失败
  • 需要在 _NAME_TYPE_MAP 中添加 latd|lond 模式 → LAT_LON
  • 或在 _name_to_type 中添加对 +. 前缀的感知

Workstream C: Traceback截断修复 (Issue 4)

C4 清理所有 traceback 截断

File: analysis/tool_registry.py line 1138 Current: traceback.format_exc()[:200] 截断 PCA 错误到 200 字符 Fix: 改为完整 traceback。同时审计整个项目:

  • tianxuan/llm_orchestrator.py line 71: json.dumps(...)[:1200] — 这是工具结果截断,合理,保留
  • analysis/tool_registry.py line 43: _truncate_response() — 工具响应截断,合理,保留
  • 只修复 line 1138 的 [:200]

Workstream D: 大规模数据处理 (Issues 5, 6, 14, 16)

D5 大数据量卡顿优化 (1M-20M行)

Root Cause: 当前 MAX_ROWS_PER_RUN = 300 但分析流水线是一次性 collect 所有数据到内存。 Fix:

  1. data_loader.pyload_csv_directory 添加 head=N 参数用于预览场景
  2. 聚类分析使用 Polars streaming (engine='streaming')
  3. tool_registry.py_cluster_sync 中添加数据降采样:>50K 行时随机采样
  4. views.py 中 globe_view 的 MAX_ROWS_PER_RUN 从 300 改为 500(对于 20M 数据来说 300 行太稀疏了)

D6 进度条 + 静默处理

Root Cause: 当前状态机只有 loading→profiling→aggregating→ready→clustering→extracting→completed/failed,无百分比。 Fix:

  1. AnalysisRun model 添加 progress_pct (IntegerField, default=0) 和 progress_msg (CharField)
  2. 后台线程在每一步更新 progress_pctloading=10, profiling=30, aggregating=50, clustering=70, extracting=90, completed=100
  3. run_status_api 返回 progress_pctprogress_msg
  4. upload.html 中的进度条显示实际百分比
  5. 无前端静默处理:添加 ?background=true 参数,后端仍全速分析但前端不轮询

D14 低内存设备聚类崩溃

Root Cause: 8GB 设备上,20M 行 × 30 列的数据在聚类时会产生巨大 float64 ndarray。 Fix:

  1. _cluster_sync 中添加内存检查:psutil.virtual_memory().available < 2GB 时自动启用流式模式
  2. 自动降采样:>100K 行时使用 sklearn.utils.resample 采样到 50K 行
  3. 使用 MiniBatchKMeans 替代 KMeans(内存效率更高)
  4. 在聚类前使用 sklearn.decomposition.PCA(n_components=min(50, n_features)) 降维

D16 空闲时高磁盘IO

Root Cause: session_store.py 是纯内存的,不应有磁盘 IO。但 Django 日志 RotatingFileHandler 可能在后台写入。另外 SQLite 使用 DELETE 模式(非 WAL)可能导致写入阻塞。 Fix:

  1. 审计后台线程是否有不必要的 ORM 轮询
  2. 如果 settings.py 中的 LOGGING 配置了低级别(如 DEBUG),改为 INFO+
  3. 检查是否有任何定时任务或 watchdog

Workstream E: Globe可视化修复 (Issues 8, 9)

E8 Globe响应式缩放

File: templates/tianxuan/globe.html Root Cause: 当前高度固定为 700pxH = 700),resize 只更新宽度和 aspect。缩放(wheel)只移动 camera.position.z(zoom),不按比例调整数据点大小。 Fix:

  1. resize handler 中根据容器尺寸动态计算高度:H = container.clientHeight || window.innerHeight * 0.8
  2. 添加设备像素比处理:renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
  3. 弧线粗细使用相对比例(根据 zoom level 调整 TubeGeometry.radiusLineBasicMaterial.linewidth

E9 ?data= 访问拒绝支持

File: analysis/views.py (globe_view), templates/tianxuan/globe.html Root Cause: globe_view 只识别 ?runs=1&runs=2 格式,没有 ?data= 参数的处理逻辑。 Fix:

  1. globe_view 添加 ?data=dataset_id 参数支持
  2. 当提供 data= 时,直接从 SessionStore 按 dataset_id 读取数据
  3. Globe 模板更新 JavaScript 以支持 dataset 模式

Workstream F: LLM日志 (Issue 12)

F12 LLM运行过程打印到前端

Files: tianxuan/llm_orchestrator.py, analysis/views.py, templates/tianxuan/auto.html Root Cause: LLM 在 thread 中运行,logger.info 写入日志文件,但前端 auto.html 通过轮询 /logs/?pos=N 显示日志。问题是日志缓冲可能延迟写入。 Fix:

  1. 添加 llm_status_api 视图返回当前 LLM 运行状态
  2. llm_orchestrator 使用回调函数报告进度(步骤/工具调用/中间结果)
  3. _run_llm_analysis worker 写入 AnalysisRun.run_log 字段

Workstream G: 聚类可视化修复 (Issue 13)

G13 聚类图表完善

Files: templates/analysis/cluster_overview.html, analysis/views.py Root Cause: 当前只有 PCA 散点图 + 地理散点图(两个 Canvas)。用户要求更丰富的图表。 Fix:

  1. 添加簇大小饼图/柱状图(Canvas
  2. 添加 Silhouette 得分的簇间对比图
  3. 添加特征重要性水平条形图(top 10 features per cluster
  4. 确保 PCA 坐标在 web 分析流程中正确保存(当前 _handle_extract_features 在 tool_registry.py 中保存,但异常被 [:200] 截断 → 先修 C4

Workstream H: 聚类质量改进 (Issue 17)

H17 预处理降维+特征工程后聚类

Files: analysis/tool_registry.py, analysis/entity_aggregator.py Root Cause: 当前聚类直接对原始聚合特征(flow_count, total_bytes, unique_dst_ips 等)做 StandardScaler + HDBSCAN。没有特征选择、PCA/UMAP 预处理。 Fix:

  1. _cluster_sync 中添加可选的 PCA 预处理步骤
  2. 添加方差过滤:去除方差为 0 或接近 0 的特征
  3. 添加相关性过滤:去除相关性 >0.95 的特征对中的冗余特征
  4. HDBSCAN 超参数根据数据规模自动调整

Dependencies

  • C4 (traceback fix) is prerequisite for G13 (PCA fix won't be debuggable without full traceback)
  • B18 (column mapping) is prerequisite for B7 (0ver hex detection needs 0ver in column map) and G17 (proper features need proper column detection)
  • D5 (optimization) is partially prerequisite for D14 (memory handling both affect clustering path)

Must-Not-Have

  • 不修改 runtime/ 目录下的任何文件
  • 不删除或重命名现有数据库表
  • 不添加新的 Python 包依赖(除非绝对必要且用户批准)
  • 不修改 Polars 版本锁定