第一章:Go doc server突然空白?揭秘GOPATH、GOBIN与gopls协同失效的7个隐藏断点
当执行 godoc -http=:6060 后浏览器打开却显示空白页,或 VS Code 中文档悬停失效、跳转中断,问题往往不在于 godoc 命令本身——而是 GOPATH、GOBIN 与语言服务器 gopls 在静默中相互错位。三者本应构成一致的模块解析链,但任一环节路径未对齐、权限异常或版本不兼容,即触发“文档黑洞”。
GOPATH 的隐式污染陷阱
go env GOPATH 返回多个路径(如 ~/go:/usr/local/go) 时,gopls 仅信任首个路径下的 src/;若你将项目克隆至第二个 GOPATH 路径下,gopls 将拒绝索引,导致 :GoDoc 和 hover 提示全空。修复方式:
# 强制统一 GOPATH(临时生效)
export GOPATH="$HOME/go"
# 清理旧缓存并重启 gopls
rm -rf "$GOPATH/pkg/mod/cache"
killall gopls
GOBIN 与 gopls 二进制签名冲突
gopls 若由 go install golang.org/x/tools/gopls@latest 安装至 $GOBIN/gopls,但 GOBIN 未加入 PATH,VS Code 将回退使用内置旧版(v0.12.x),而该版本不支持 Go 1.22+ 的 workspace module 模式。验证命令:
which gopls # 应输出 $GOBIN/gopls
gopls version # 必须显示 v0.14.0+
模块根目录缺失 go.work 或 go.mod
gopls 启动时自动向上查找最近的 go.work 或 go.mod。若当前工作区无二者(例如纯 src/ 下的 legacy 包),它将降级为 GOPATH 模式——但若 GOPATH/src 内无 go.mod,则所有文档解析失败。解决方案:
- 在项目根目录运行
go mod init example.com/foo,或 - 创建
go.work文件并包含所有子模块路径。
其他关键断点
- 文件系统权限:
$GOPATH/pkg/mod/cache目录被root占用导致gopls无法写入缓存 gopls配置覆盖:VS Code 设置中"gopls": {"build.directoryFilters": ["-node_modules"]}错误排除了src/GOROOT指向预编译二进制包(如 Homebrew 安装的 Go),缺失src/导致标准库文档不可见GO111MODULE=off环境变量全局启用,强制禁用模块感知
| 断点类型 | 快速检测命令 | 修复动作 |
|---|---|---|
| 缓存损坏 | gopls cache ls |
gopls cache delete all |
| 工作区未识别 | gopls -rpc.trace -v 启动后观察日志 |
在含 go.mod 的目录中打开 VS Code |
第二章:GOPATH环境变量的隐式依赖与显式崩塌
2.1 GOPATH路径解析机制与go doc server启动时的目录挂载逻辑
Go 1.11 之前,GOPATH 是 Go 工具链定位源码、包和文档的唯一根路径。go doc -http=:6060 启动服务时,会自动挂载以下目录:
$GOPATH/src→/pkg(标准包文档)$GOPATH/pkg→/pkg(已编译包信息)$GOROOT/src→/src(Go 标准库源码)
# 启动带自定义挂载的 doc server
go doc -http=:6060 -goroot /usr/local/go -gopath ~/go:~/work
参数说明:
-gopath支持多路径冒号分隔;-goroot显式指定标准库位置,避免GOROOT环境变量误配导致/src挂载失败。
目录挂载优先级规则
- 多
GOPATH路径按顺序扫描,首个匹配包胜出 GOROOT/src始终挂载为/src,不可覆盖/pkg下的包文档按import path映射,如github.com/user/lib→/pkg/github.com/user/lib
| 挂载源 | HTTP 路径 | 用途 |
|---|---|---|
$GOROOT/src |
/src |
浏览标准库源码 |
$GOPATH/src |
/pkg |
查看第三方包文档 |
$GOPATH/pkg |
/pkg |
提供 .a 元数据 |
graph TD
A[go doc -http] --> B{解析 GOPATH}
B --> C[按序遍历各 GOPATH/src]
B --> D[强制挂载 GOROOT/src]
C --> E[构建 import path → URL 路由]
D --> E
E --> F[/pkg/... 文档渲染]
2.2 GOPATH多工作区场景下模块路径混淆导致文档索引丢失的实证复现
当多个 GOPATH 工作区共存(如 ~/go 和 ~/projects/go),go doc 和 IDE 文档索引器可能因 GOROOT/GOPATH 路径解析歧义而跳过非首工作区中的模块。
复现场景构造
# 激活第二工作区,但未清理缓存
export GOPATH=~/projects/go:~/go
cd ~/projects/go/src/github.com/example/lib
go mod init github.com/example/lib # 模块路径与 GOPATH 内部结构不一致
此处
go mod init生成的go.mod中module github.com/example/lib与GOPATH的物理路径~/projects/go/src/...不构成标准映射,导致gopls在构建包图时忽略该路径——因其无法通过GOPATH/src→import path的默认反射规则反向定位。
关键路径冲突表
| 环境变量 | 值 | 影响 |
|---|---|---|
GOPATH |
~/projects/go:~/go |
go list -m all 仅扫描首路径 |
GOMOD |
~/projects/go/src/.../go.mod |
gopls 认为非标准布局 |
文档索引失效流程
graph TD
A[启动 gopls] --> B{解析 GOPATH 列表}
B --> C[仅加载 ~/projects/go/src 下包]
C --> D[跳过 ~/go/src/github.com/example/lib]
D --> E[VS Code 无 hover 文档提示]
2.3 go env -w GOPATH=… 与shell会话继承性冲突引发的server静默退出
Go 工具链的 go env -w 会持久化写入 $HOME/go/env,但不立即生效于当前 shell 会话——这正是静默退出的根源。
环境变量加载时序陷阱
go env -w GOPATH=/custom/path→ 写入全局配置文件- 当前 shell 的
GOPATH仍为旧值(如/home/user/go) go run main.go启动 server 时,依赖GOPATH解析vendor/或模块缓存路径- 若
/custom/path不存在或权限不足,go命令 silently fallback 并最终触发os.Exit(0)
典型复现代码
# 错误示范:写入后未重载环境
go env -w GOPATH="/tmp/invalid-gopath"
go run ./cmd/server # 无错误输出,进程秒退
🔍 分析:
go run内部调用exec.LookPath("go")时检测到GOPATH不可写,跳过 vendor 初始化,http.ListenAndServe因nilhandler 被忽略而直接返回。
推荐修复方式
- ✅
source <(go env -json | jq -r 'to_entries[] | "export \(.key)=\(.value|tostring)"') - ✅ 或重启 shell(最可靠)
- ❌ 避免
export GOPATH=... && go env -w GOPATH=...混用
| 方式 | 是否影响子进程 | 是否需重启 shell | 安全性 |
|---|---|---|---|
go env -w 单独使用 |
否 | 是 | ⚠️ 高风险 |
export + go env -w |
是 | 否 | ✅ 推荐 |
source <(go env -json) |
是 | 否 | ✅ 最佳 |
2.4 vendor目录存在时GOPATH/pkg/mod缓存优先级错位对godoc静态资源生成的影响
当项目含 vendor/ 目录时,godoc(尤其是旧版 go doc -http)在解析依赖路径时会跳过 pkg/mod 缓存,转而直接读取 vendor/ 中的源码——但其静态资源(如 CSS、JS、图标)仍尝试从 $GOROOT/src/cmd/godoc/static/ 或 $GOPATH/src/golang.org/x/tools/cmd/godoc/static/ 加载,导致资源 404。
godoc 资源加载路径冲突示意
# godoc 启动时实际行为(v1.19-)
godoc -http=:6060 -goroot=$GOROOT -path=./vendor # 错误地将 vendor 当作唯一源根
该命令使
godoc忽略pkg/mod中已缓存的模块元信息(如golang.org/x/net@v0.25.0的doc/子目录),导致static/资源查找逻辑与模块解析逻辑脱节。
优先级错位关键表现
| 场景 | 模块解析路径 | 静态资源路径 | 结果 |
|---|---|---|---|
| 无 vendor | pkg/mod/cache/download/... |
$GOROOT/src/cmd/godoc/static/ |
✅ 正常 |
| 有 vendor | ./vendor/(仅此) |
仍查 $GOROOT/.../static/ |
❌ JS/CSS 丢失 |
修复策略(推荐)
- 升级至
go install golang.org/x/tools/cmd/godoc@latest(已弃用,仅作兼容参考) - 改用
go doc -u -http=:6060(Go 1.22+):自动识别vendor+pkg/mod双源,并统一服务静态资源
graph TD
A[启动 godoc] --> B{vendor/ 存在?}
B -->|是| C[设置 -path=./vendor]
B -->|否| D[启用 pkg/mod 模块解析]
C --> E[静态资源仍从 GOROOT 加载]
D --> F[资源与模块版本对齐]
E --> G[CSS/JS 404]
2.5 跨平台(Windows/Linux/macOS)GOPATH路径分隔符未标准化引发的fs.WalkDir遍历中断
fs.WalkDir 在跨平台构建中对路径分隔符敏感:Windows 使用 \,而 Unix 系统使用 /。当 GOPATH 包含混合分隔符(如 C:\go\src;./vendor),filepath.SplitList 解析后生成不一致路径片段,导致 fs.WalkDir 在 os.Stat 阶段返回 ENOENT 并提前终止。
问题复现代码
// 示例:跨平台 GOPATH 解析异常
gopath := os.Getenv("GOPATH")
for _, p := range filepath.SplitList(gopath) {
fs.WalkDir(os.DirFS(p), ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
log.Printf("walk error at %q: %v", path, err) // ⚠️ Windows 下可能因 \ 未转义而失败
return err // 遍历中断
}
return nil
})
}
filepath.SplitList 按 os.PathListSeparator(; 或 :)切分,但不归一化内部分隔符;os.DirFS(p) 要求路径为正斜杠格式,否则在 Windows 上解析失败。
分隔符兼容性对比
| 平台 | GOPATH 示例 | SplitList 后首项 | DirFS 兼容性 |
|---|---|---|---|
| Windows | C:\go;D:\proj |
C:\go |
❌(需 /) |
| macOS | /Users/a/go:/tmp/vendor |
/Users/a/go |
✅ |
修复方案
- 统一调用
filepath.ToSlash(p)归一化路径; - 或改用
filepath.FromSlash()动态适配目标平台。
graph TD
A[读取 GOPATH] --> B[SplitList 分割]
B --> C[逐项 ToSlash 归一化]
C --> D[os.DirFS 构建]
D --> E[fs.WalkDir 安全遍历]
第三章:GOBIN路径污染与二进制链路断裂
3.1 GOBIN中混入旧版go工具链导致gopls无法正确协商LSP协议版本
当 GOBIN 目录中存在混合版本的 Go 工具链(如 go 为 1.21,而 gofmt 或 go list 为 1.19),gopls 启动时会调用 go version 和 go list -mod=mod -f '{{.GoVersion}}' . 探测环境,但部分子命令行为不一致,引发协议版本误判。
根本诱因:工具链版本碎片化
goplsv0.14+ 要求 Go 1.20+ 的 module 模式语义- 旧版
go list返回空或错误GoVersion字段,导致gopls回退至 LSP v3.16 协议 - 实际客户端(如 VS Code)已启用 v3.17 功能(如
workspace/semanticTokens/refresh)
复现验证命令
# 检查 GOBIN 中各工具版本是否对齐
ls -la $GOBIN/go* | grep -E "(go|gofmt|goimports)"
# 输出示例:
# -r-xr-xr-x 1 user user 123M Jan 10 go # 1.21.5
# -r-xr-xr-x 1 user user 12M Jan 5 gofmt # 1.19.2 ← 冲突源
该命令暴露二进制文件时间戳与版本错位;gopls 依赖 go 命令派生子进程,若 $GOBIN/gofmt 版本过低,go list 调用可能静默失败,使 gopls 误判 Go 环境能力。
版本兼容性对照表
| gopls 版本 | 最低 Go 版本 | 支持 LSP 协议 | go list 行为要求 |
|---|---|---|---|
| v0.13.4 | 1.18 | 3.16 | 可容忍空 .GoVersion |
| v0.14.2 | 1.20 | 3.17 | 必须返回有效 go1.20 字符串 |
修复流程
graph TD
A[检测 GOBIN 混合版本] --> B[清理旧二进制:rm $GOBIN/go{fmt,imports,doc}]
B --> C[重装统一工具链:go install golang.org/x/tools/cmd/...@latest]
C --> D[gopls 重启后协商 v3.17 协议成功]
3.2 GOBIN与$PATH顺序倒置引发go doc server进程被错误二进制劫持的调试追踪
当 GOBIN 目录(如 ~/go/bin)被前置添加至 $PATH 末尾,而系统中已存在同名但非 Go 官方构建的 godoc 二进制时,go doc -http=:6060 会意外执行该恶意副本。
复现关键环境配置
# 错误的 PATH 设置(倒置!)
export GOBIN="$HOME/go/bin"
export PATH="$PATH:$GOBIN" # ← 注意:GOBIN 在末尾,而非开头
此处
:$GOBIN后置导致 shell 查找godoc时优先命中/usr/local/bin/godoc(旧版/篡改版),而非GOBIN中由go install golang.org/x/tools/cmd/godoc@latest生成的可信二进制。
进程溯源验证
| 环境变量 | 值 | 影响 |
|---|---|---|
which godoc |
/usr/local/bin/godoc |
实际执行路径 |
go env GOBIN |
~/go/bin |
期望路径,但未生效 |
劫持调用链
graph TD
A[go doc -http=:6060] --> B{shell 查找 godoc}
B --> C[/usr/local/bin/godoc]
C --> D[非 go install 构建的二进制]
D --> E[监听 6060 但无 TLS/鉴权]
修复方式:export PATH="$GOBIN:$PATH" —— 确保 GOBIN 优先级最高。
3.3 go install golang.org/x/tools/cmd/godoc@latest 与GOBIN权限拒绝写入的静默失败日志分析
当执行 go install 时,若 GOBIN 目录不可写,命令会静默失败——无错误输出,仅返回非零退出码。
复现现象
$ GOBIN=/usr/local/bin go install golang.org/x/tools/cmd/godoc@latest
$ echo $? # 输出 1,但终端无任何提示
go install在目标路径写入失败时跳过错误打印,仅设置exit(1),导致 CI/CD 中难以察觉工具缺失。
权限诊断流程
- 检查
GOBIN是否存在且可写:test -w "$GOBIN" - 验证父目录继承权限(尤其 macOS
/usr/local/bin默认仅 root 可写) - 使用
strace -e trace=mkdir,openat,write捕获系统调用失败点
典型修复策略
| 方案 | 命令 | 说明 |
|---|---|---|
| 重定向到用户目录 | GOBIN=$HOME/go/bin go install ... |
避免系统路径权限问题 |
| 修复目录所有权 | sudo chown -R $(whoami) /usr/local/bin |
仅限开发机,不推荐生产环境 |
graph TD
A[go install ...] --> B{GOBIN exists?}
B -->|No| C[创建目录]
B -->|Yes| D{Writable?}
D -->|No| E[exit 1, no log]
D -->|Yes| F[写入二进制并成功]
第四章:gopls语言服务器与文档服务的耦合失效点
4.1 gopls v0.13+移除内置godoc支持后,go doc server依赖gopls元数据接口的兼容性断层
gopls v0.13 起彻底剥离 godoc 子命令与内建文档服务逻辑,导致 go doc server(如 VS Code 的 Go extension 启动的文档代理)无法再通过 gopls -rpc.trace 或 textDocument/hover 原始响应获取完整符号文档。
文档元数据获取路径变更
- 旧路径:
gopls直接解析godoc -http兼容格式并注入textDocument/hover - 新路径:仅通过
$/gopls.getDocumentation(非 LSP 标准方法)提供结构化文档对象
关键兼容性断点
// gopls v0.12 响应(hover)
{
"contents": { "kind": "markdown", "value": "```go\nfunc Foo() int\n```\n\nFoo returns 42." }
}
此响应含内联 Markdown,
go doc server可直接透传;v0.13+ 中该字段被移除,必须调用$/gopls.getDocumentation并传入uri+position,否则返回空。
接口适配差异对比
| 维度 | v0.12 及以前 | v0.13+ |
|---|---|---|
| 方法名 | textDocument/hover |
$/gopls.getDocumentation(私有协议) |
| 参数要求 | 仅 textDocument, position |
额外需 packagePath, mode: "full" |
| 文档粒度 | 符号级 | 包/符号双层级可选 |
graph TD
A[go doc server] -->|v0.12| B[textDocument/hover → markdown]
A -->|v0.13+| C[$/gopls.getDocumentation → JSON struct]
C --> D[需预加载 package metadata]
D --> E[否则 fallback 到 go/doc 构建耗时回退]
4.2 gopls配置中“build.experimentalWorkspaceModule”启用状态与go doc server模块解析器的互斥行为
当 build.experimentalWorkspaceModule = true 时,gopls 切换至基于 workspace module 的构建上下文,完全绕过 go list -m all 驱动的传统模块解析路径。
冲突根源
- go doc server 依赖
go list -m all构建模块索引树; - experimentalWorkspaceModule 启用后,gopls 使用
go mod graph+ workspace-awarego list -deps,跳过-m all调用; - 导致 doc server 无法获取完整模块元数据,返回空或陈旧文档。
配置互斥验证表
| 配置项 | go doc server 可用 | 模块解析器类型 |
|---|---|---|
experimentalWorkspaceModule: false |
✅ | go list -m all |
experimentalWorkspaceModule: true |
❌(超时/空结果) | workspace module graph |
// gopls settings.json 片段(冲突场景)
{
"build.experimentalWorkspaceModule": true,
"ui.documentation.hoverKind": "Synopsis"
}
此配置下,hover 文档始终 fallback 到
go/doc包级注释,缺失模块版本、依赖链及跨模块符号解析能力;根本原因是 doc server 与 workspace module 解析器使用两套不兼容的模块发现协议。
graph TD
A[gopls config] -->|true| B[Use workspace module resolver]
A -->|false| C[Use go list -m all]
B --> D[Skip module index for doc server]
C --> E[Full module index built]
4.3 gopls后台缓存损坏(~/.cache/gopls)导致go doc server请求返回空HTML响应体的抓包验证
抓包复现关键步骤
使用 tcpdump 捕获 gopls 与本地 go doc server 的 HTTP 通信:
# 监听 localhost:3000(gopls 默认文档服务端口)
sudo tcpdump -i lo port 3000 -w gopls_doc.pcap -s 0
此命令捕获原始 TCP 流,
-s 0确保不截断 HTTP 响应体;若响应体为空(Content-Length: 0或无body字段),即指向缓存层未触发 HTML 渲染。
缓存损坏的典型表现
~/.cache/gopls/<hash>/metadata文件缺失或mtime异常早于go.modgopls日志中出现failed to load package: no metadata found for ...
HTTP 响应对比表
| 场景 | Status Code | Content-Length | Body Present? |
|---|---|---|---|
| 正常缓存 | 200 | 12487 | ✅ |
| 缓存损坏 | 200 | 0 | ❌ |
数据同步机制
gopls 在启动时通过 cache.Load() 加载模块元数据;若 filecache 中 .modcache 条目失效,Documentation handler 将跳过 HTML 生成逻辑,直接返回空 http.ResponseWriter。
graph TD
A[HTTP GET /pkg/fmt] --> B{Cache valid?}
B -->|Yes| C[Render HTML from ast.Package]
B -->|No| D[Return empty 200]
4.4 gopls与go doc server共用同一端口(localhost:6060)时TCP连接竞争引发的HTTP 204响应伪装
当 gopls 与 go doc server 同时监听 localhost:6060,内核 TCP 栈无法区分服务归属,导致 Accept 队列争抢。
连接竞争现象
- 内核将新连接随机分发给任一已调用
accept()的进程 - 先
accept()成功者获得 socket,另一方read()返回 EOF 或阻塞超时 go doc server对非/路径返回204 No Content,而gopls的 LSP over HTTP 探针恰匹配该路径
响应伪装示例
# curl -v http://localhost:6060/gopls/debug
> GET /gopls/debug HTTP/1.1
< HTTP/1.1 204 No Content # 实为 go doc server 错误响应,非 gopls 真实状态
该 204 是 go doc server 对未知路径的默认兜底行为,造成健康检查误判。
关键参数对照
| 组件 | SO_REUSEPORT |
默认响应路径 | 204 触发条件 |
|---|---|---|---|
go doc server |
❌ | /, /pkg/* |
任意未注册路径 |
gopls |
✅(需显式启用) | /debug/* |
仅当 handler 显式返回 |
graph TD
A[New TCP SYN] --> B{Kernel Accept Queue}
B --> C[gopls accept()]
B --> D[go doc server accept()]
C --> E[Read: expects JSON-RPC]
D --> F[Read: expects HTTP path]
F --> G[/gopls/debug → 204]
第五章:终极诊断框架与自动化修复工具链
核心设计理念:可观测性驱动闭环自治
该框架以“采集—分析—决策—执行—验证”五阶段闭环为内核,摒弃传统告警驱动的被动响应模式。在某金融支付平台灰度发布中,系统通过eBPF实时捕获TCP重传率、TLS握手延迟及gRPC状态码分布,12秒内识别出某K8s节点因内核net.ipv4.tcp_slow_start_after_idle参数异常导致连接池雪崩,触发自动隔离并回滚ConfigMap。
多源异构数据融合管道
支持从Prometheus(指标)、Loki(日志)、Jaeger(链路)、eBPF(内核态事件)、SNMP(网络设备)五类数据源统一接入,经OpenTelemetry Collector标准化后写入时序数据库VictoriaMetrics与向量数据库Weaviate。关键字段自动打标:service=payment-gateway, env=prod-blue, k8s_node=ip-10-20-3-145.us-west-2.compute.internal。
智能诊断知识图谱
构建包含1,287个故障模式的因果图谱,节点为故障现象(如5xx_rate>15%),边为根因概率权重。当检测到etcd_leader_changes_total{job="etcd"} > 3 in 5m,图谱自动关联至disk_iops_throttled{device="nvme0n1"}与kubelet_pleg_relist_duration_seconds,置信度加权排序输出TOP3根因。
自动化修复策略引擎
| 修复类型 | 触发条件示例 | 执行动作 | 验证方式 |
|---|---|---|---|
| 配置回滚 | deployment_rollout_status != "Complete" |
kubectl rollout undo deployment/payment-api --to-revision=12 |
检查deployment_status_replicas_available == deployment_spec_replicas |
| 资源扩容 | container_cpu_usage_seconds_total{container="api"} > 0.9 * container_spec_cpu_quota |
kubectl patch hpa payment-api-hpa -p '{"spec":{"minReplicas":4}}' |
确认hpa_status_current_replicas >= 4且CPU使用率回落至65%以下 |
| 节点驱逐 | node_condition{condition="MemoryPressure"} == 1 |
kubectl drain ip-10-20-3-145 --ignore-daemonsets --delete-emptydir-data |
核验node_status_phase == "SchedulingDisabled" |
安全沙箱执行环境
所有修复指令在独立容器中运行,通过Kubernetes Pod Security Admission限制权限:仅允许get/watch/list集群资源,禁止exec或portforward。修复脚本需通过OPA Gatekeeper策略校验,例如拒绝修改system:node组绑定的RBAC资源。
# 实际生产环境中执行的修复脚本片段(已脱敏)
if [[ $(curl -s http://metrics.svc.cluster.local:9090/api/v1/query?query=rate%28http_request_duration_seconds_count%7Bcode%3D%22503%22%7D%5B2m%5D%29\|jq -r '.data.result[0].value[1]') > 0.15 ]]; then
kubectl get pods -n payment --field-selector=status.phase=Running -o jsonpath='{.items[0].metadata.name}' | xargs -I{} kubectl delete pod {} -n payment --grace-period=0
fi
可视化诊断看板
采用Grafana构建动态拓扑图,节点颜色映射MTTD(平均诊断时间),连线粗细反映故障传播强度。当redis_master_failover_events_total突增时,自动高亮显示关联的spring_cache_gets_total下降曲线与jvm_memory_used_bytes{area="heap"}峰值。
修复效果持续验证机制
每次修复后启动三阶段验证:① 基础健康检查(HTTP 200 + /healthz);② 业务逻辑验证(调用支付回调模拟器发起10笔测试交易);③ 长期稳定性观测(持续监控15分钟内P99延迟标准差
运维人员协同工作流
集成Slack与Jira API,自动创建带上下文快照的工单:包含故障时间轴、eBPF抓包摘要、修复前后指标对比折线图、受影响Pod列表及执行日志。运维工程师可在Slack中直接输入/fix approve payment-api-7b8f9c4d6-xyz12确认执行。
工具链部署拓扑
graph LR
A[Prometheus Metrics] --> B[OTel Collector]
C[Loki Logs] --> B
D[Jaeger Traces] --> B
E[eBPF Probes] --> B
B --> F[VictoriaMetrics]
B --> G[Weaviate Vector DB]
F --> H[Diagnosis Engine]
G --> H
H --> I[Policy Server]
I --> J[K8s API Server]
J --> K[Production Cluster] 