Files
qiming/qiming-rcoder/.qoder/repowiki/zh/content/可观测性/可观测性.md
2026-06-01 13:54:52 +08:00

426 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 可观测性
<cite>
**本文引用的文件**
- [rcoder 主程序](file://crates/rcoder/src/main.rs)
- [agent_runner 主程序](file://crates/agent_runner/src/main.rs)
- [rcoder 路由与状态](file://crates/rcoder/src/router.rs)
- [agent_runner 路由与状态](file://crates/agent_runner/src/router.rs)
- [rcoder 健康检查处理器](file://crates/rcoder/src/handler/health_handler.rs)
- [agent_runner 健康检查处理器](file://crates/agent_runner/src/handler/health_handler.rs)
- [rcoder 配置](file://crates/rcoder/src/config.rs)
- [agent_runner 配置](file://crates/agent_runner/src/config.rs)
- [rcoder 代理 API 处理器](file://crates/rcoder/src/handler/proxy_handler_api.rs)
- [agent_runner 代理 API 处理器](file://crates/agent_runner/src/handler/proxy_handler_api.rs)
- [rcoder 清理任务](file://crates/rcoder/src/proxy_agent/cleanup_task.rs)
- [agent_runner 清理任务](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs)
- [共享错误类型](file://crates/shared_types/src/model/app_error.rs)
- [服务镜像配置](file://crates/shared_types/src/service_config.rs)
- [rcoder 追踪中间件](file://crates/rcoder/src/middleware/tracing_middleware.rs)
- [agent_runner 追踪中间件](file://crates/agent_runner/src/middleware/tracing_middleware.rs)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
## 简介
本文件系统性阐述本仓库的可观测性实现,涵盖日志系统、链路追踪、性能监控与错误处理。内容基于实际代码库,提供面向初学者的易懂说明与面向资深工程师的技术深度,包括配置项、参数与返回值、组件关系、常见问题与解决方案。
## 项目结构
- 两个主要服务:
- rcoder主服务提供聊天、SSE 实时通知、代理与健康检查等能力
- agent_runner代理运行器负责代理会话、清理任务与健康检查
- 共享模块:
- shared_types共享模型与错误类型
- 配置模块:统一的配置加载与环境变量覆盖
- 追踪中间件HTTP 请求级链路追踪与日志注入
- 清理任务:闲置资源回收与孤立容器清理
- 代理 APIPingora 代理的状态、统计与配置查询
```mermaid
graph TB
subgraph "rcoder 服务"
RMain["rcoder 主程序<br/>初始化遥测/路由/代理"]
RRouter["路由与状态<br/>/health /chat /agent/* /proxy/*"]
RTracing["追踪中间件<br/>HTTP 请求追踪"]
RClean["清理任务<br/>闲置容器/会话清理"]
RProxyAPI["代理 API 处理器<br/>状态/统计/配置"]
end
subgraph "agent_runner 服务"
AMain["agent_runner 主程序<br/>初始化遥测/路由/代理"]
ARouter["路由与状态<br/>/health /chat /agent/* /proxy/*"]
ATracing["追踪中间件<br/>HTTP 请求追踪"]
AClean["清理任务<br/>闲置会话/SSE消息清理"]
AProxyAPI["代理 API 处理器<br/>状态/统计/配置"]
end
subgraph "共享"
SharedErr["共享错误类型<br/>AppError"]
SharedCfg["服务镜像配置<br/>ServiceImageConfig"]
end
RMain --> RRouter --> RTracing
RMain --> RClean
RMain --> RProxyAPI
AMain --> ARouter --> ATracing
AMain --> AClean
AMain --> AProxyAPI
RRouter --> SharedErr
ARouter --> SharedErr
RMain --> SharedCfg
AMain --> SharedCfg
```
图表来源
- [rcoder 主程序](file://crates/rcoder/src/main.rs#L1-L120)
- [agent_runner 主程序](file://crates/agent_runner/src/main.rs#L1-L120)
- [rcoder 路由与状态](file://crates/rcoder/src/router.rs#L52-L84)
- [agent_runner 路由与状态](file://crates/agent_runner/src/router.rs#L41-L70)
- [rcoder 代理 API 处理器](file://crates/rcoder/src/handler/proxy_handler_api.rs#L1-L60)
- [agent_runner 代理 API 处理器](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L1-L60)
- [rcoder 清理任务](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L1-L120)
- [agent_runner 清理任务](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L1-L120)
- [共享错误类型](file://crates/shared_types/src/model/app_error.rs#L1-L65)
- [服务镜像配置](file://crates/shared_types/src/service_config.rs#L1-L120)
章节来源
- [rcoder 主程序](file://crates/rcoder/src/main.rs#L1-L120)
- [agent_runner 主程序](file://crates/agent_runner/src/main.rs#L1-L120)
- [rcoder 路由与状态](file://crates/rcoder/src/router.rs#L52-L84)
- [agent_runner 路由与状态](file://crates/agent_runner/src/router.rs#L41-L70)
## 核心组件
- 日志系统
- 使用 tracing 与 tracing-subscriber 输出到文件与控制台按天滚动JSON 格式便于后续分析
- rcoder 与 agent_runner 分别初始化各自的遥测系统,设置 TraceContextPropagator
- 链路追踪
- HTTP 请求中间件自动生成 trace_id注入 OpenTelemetry 上下文,记录请求/响应
- 中间件将 trace_id 放入请求扩展,便于后续处理器使用
- 性能监控
- Pingora 代理内置指标:总请求数、成功/失败响应数、平均响应时间等
- 代理 API 提供 /proxy/status、/proxy/stats、/proxy/config 查询
- 错误处理
- 统一的 AppError 类型,实现 IntoResponse返回标准化错误体
- 代理 API 对未启用代理场景返回明确的错误码与消息
章节来源
- [rcoder 主程序](file://crates/rcoder/src/main.rs#L274-L320)
- [agent_runner 主程序](file://crates/agent_runner/src/main.rs#L181-L231)
- [rcoder 追踪中间件](file://crates/rcoder/src/middleware/tracing_middleware.rs#L71-L130)
- [agent_runner 追踪中间件](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L71-L130)
- [rcoder 代理 API 处理器](file://crates/rcoder/src/handler/proxy_handler_api.rs#L1-L120)
- [agent_runner 代理 API 处理器](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L1-L120)
- [共享错误类型](file://crates/shared_types/src/model/app_error.rs#L1-L65)
## 架构总览
可观测性贯穿请求生命周期:从 HTTP 入口经中间件注入 trace_id进入路由与处理器期间产生日志与指标代理服务提供运行时状态与统计清理任务定期回收闲置资源错误统一收敛。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Router as "Axum 路由"
participant Tracing as "追踪中间件"
participant Handler as "业务处理器"
participant Proxy as "Pingora 代理"
participant Cleaner as "清理任务"
Client->>Router : "HTTP 请求"
Router->>Tracing : "进入中间件"
Tracing->>Tracing : "生成/提取 trace_id<br/>记录请求开始"
Tracing->>Handler : "继续处理"
Handler->>Proxy : "代理转发/查询"
Proxy-->>Handler : "代理响应"
Handler-->>Client : "业务响应"
Tracing->>Tracing : "记录响应状态"
Note over Cleaner : "定时扫描闲置资源并清理"
```
图表来源
- [rcoder 主程序](file://crates/rcoder/src/main.rs#L220-L271)
- [agent_runner 主程序](file://crates/agent_runner/src/main.rs#L120-L178)
- [rcoder 路由与状态](file://crates/rcoder/src/router.rs#L52-L84)
- [agent_runner 路由与状态](file://crates/agent_runner/src/router.rs#L41-L70)
- [rcoder 追踪中间件](file://crates/rcoder/src/middleware/tracing_middleware.rs#L71-L130)
- [agent_runner 追踪中间件](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L71-L130)
- [rcoder 清理任务](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L278-L310)
- [agent_runner 清理任务](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L294-L310)
## 详细组件分析
### 日志系统
- 初始化
- 创建 logs 目录,按天滚动,最多保留 N 份日志文件
- 控制台输出简洁格式,文件输出 JSON 格式,包含目标、线程 ID/名称等
- 设置全局 TextMapPropagator支持 trace_id 传播
- 输出位置
- rcoder日志前缀 rcoder
- agent_runner日志前缀 agent-runner
- 使用方式
- 通过 tracing::info/warn/error/debug 等宏记录结构化日志
- 中间件在请求开始与结束处记录关键信息,便于关联 trace_id
章节来源
- [rcoder 主程序](file://crates/rcoder/src/main.rs#L274-L320)
- [agent_runner 主程序](file://crates/agent_runner/src/main.rs#L181-L231)
### 链路追踪中间件
- 功能要点
- 自动生成 trace_idUUID v4 简短格式)
- 从常见 trace 请求头提取 trace_id如 x-trace-id、traceparent 等)
- 为每次请求创建 info_span记录 method、URI、trace_id、User-Agent、Content-Type
- 将 trace_id 插入请求扩展,供后续处理器使用
- 在 span 中执行请求处理,记录响应状态
- 适用范围
- rcoder 与 agent_runner 各自提供独立的中间件实现,均注册到各自路由
```mermaid
flowchart TD
Start(["进入中间件"]) --> Extract["尝试从请求头提取 trace_id"]
Extract --> HasHeader{"是否包含有效 trace 头?"}
HasHeader --> |是| UseHeader["使用请求头中的 trace_id"]
HasHeader --> |否| GenNew["生成新的 trace_id"]
UseHeader --> CreateSpan["创建请求 span含 trace_id 等字段"]
GenNew --> CreateSpan
CreateSpan --> LogStart["记录请求开始"]
LogStart --> Inject["将 trace_id 注入请求扩展"]
Inject --> RunHandler["继续处理下游处理器"]
RunHandler --> LogEnd["记录响应状态"]
LogEnd --> End(["返回响应"])
```
图表来源
- [rcoder 追踪中间件](file://crates/rcoder/src/middleware/tracing_middleware.rs#L44-L130)
- [agent_runner 追踪中间件](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L44-L130)
章节来源
- [rcoder 追踪中间件](file://crates/rcoder/src/middleware/tracing_middleware.rs#L44-L130)
- [agent_runner 追踪中间件](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L44-L130)
### 健康检查与代理监控
- 健康检查
- /health 返回标准结构,包含状态、时间戳与服务名
- rcoder 与 agent_runner 均提供独立实现
- 代理监控
- /proxy/status返回代理配置、后端列表与健康状态快照
- /proxy/stats返回总请求数、成功/失败响应数、平均响应时间等指标
- /proxy/config返回代理配置与健康检查配置
- 代理健康检查
- 配置包含启用开关、检查间隔、超时、健康阈值与不健康阈值
- 启动时可按配置启动健康检查循环
```mermaid
sequenceDiagram
participant Client as "客户端"
participant API as "代理 API 处理器"
participant ProxySvc as "Pingora 代理服务"
participant HC as "健康检查"
Client->>API : "GET /proxy/status"
API->>ProxySvc : "读取配置/后端/健康快照"
ProxySvc-->>API : "聚合状态信息"
API-->>Client : "返回状态/后端列表/健康状态"
Client->>API : "GET /proxy/stats"
API->>ProxySvc : "读取指标总请求数/成功/失败/平均响应时间"
ProxySvc-->>API : "返回指标"
API-->>Client : "返回统计信息"
Client->>API : "GET /proxy/config"
API->>ProxySvc : "读取代理配置"
API->>HC : "读取健康检查配置"
ProxySvc-->>API : "返回代理配置"
HC-->>API : "返回健康检查配置"
API-->>Client : "返回配置信息"
```
图表来源
- [rcoder 代理 API 处理器](file://crates/rcoder/src/handler/proxy_handler_api.rs#L1-L206)
- [agent_runner 代理 API 处理器](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L1-L206)
- [rcoder 配置](file://crates/rcoder/src/config.rs#L52-L80)
- [agent_runner 配置](file://crates/agent_runner/src/config.rs#L51-L73)
章节来源
- [rcoder 健康检查处理器](file://crates/rcoder/src/handler/health_handler.rs#L1-L36)
- [agent_runner 健康检查处理器](file://crates/agent_runner/src/handler/health_handler.rs#L1-L36)
- [rcoder 代理 API 处理器](file://crates/rcoder/src/handler/proxy_handler_api.rs#L1-L206)
- [agent_runner 代理 API 处理器](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L1-L206)
- [rcoder 配置](file://crates/rcoder/src/config.rs#L52-L80)
- [agent_runner 配置](file://crates/agent_runner/src/config.rs#L51-L73)
### 清理任务与资源回收
- rcoder 清理任务
- 基于 RAII 原则:从 project_and_agent_map 移除条目,触发 AgentLifecycleGuard 自动清理
- 保护期:新建容器在最小保护时间内不清理,避免误删
- 超时判断:考虑最后活动时间与创建时间,加入 1 秒缓冲避免时间误差
- 孤立容器清理:扫描 rcoder-agent-* 容器,批量并行清理,限制单次清理数量
- 超时保护:清理过程整体超时,防止阻塞
- agent_runner 清理任务
- 清理孤立的 SSE 会话与消息
- 仅清理 Idle 状态且超时的 agent避免中断 Active/Terminating 状态
```mermaid
flowchart TD
ScanStart["开始扫描"] --> Collect["收集所有项目ID"]
Collect --> Eval["逐个评估agent状态/最后活动/创建时间"]
Eval --> Protected{"是否在保护期内?"}
Protected --> |是| Skip["跳过清理"]
Protected --> |否| Timeout{"是否超时且Idle"}
Timeout --> |否| Skip
Timeout --> |是| Remove["从MAP移除触发RAII清理"]
Remove --> Orphan["清理孤立SSE会话/消息"]
Orphan --> Done["统计并记录清理结果"]
Skip --> Done
```
图表来源
- [rcoder 清理任务](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L248-L420)
- [agent_runner 清理任务](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L156-L245)
章节来源
- [rcoder 清理任务](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L1-L420)
- [agent_runner 清理任务](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L1-L245)
### 错误处理与返回值
- 统一错误类型
- AppErrorAnyhowError、IoError、Generic
- 实现 IntoResponse返回 JSON 结构,包含 success=false 与 error.code/message
- 代理 API 错误
- 未启用代理时返回 SERVICE_UNAVAILABLE携带错误码与消息
- 健康检查
- /health 返回标准结构,包含 status、timestamp、service
章节来源
- [共享错误类型](file://crates/shared_types/src/model/app_error.rs#L1-L65)
- [rcoder 代理 API 处理器](file://crates/rcoder/src/handler/proxy_handler_api.rs#L1-L120)
- [agent_runner 代理 API 处理器](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L1-L120)
- [rcoder 健康检查处理器](file://crates/rcoder/src/handler/health_handler.rs#L1-L36)
- [agent_runner 健康检查处理器](file://crates/agent_runner/src/handler/health_handler.rs#L1-L36)
### 配置与参数
- rcoder 配置
- AppConfigdefault_agent、projects_dir、port、proxy_config、docker_config
- ProxyConfiglisten_port、default_backend_port、backend_host、port_param、health_check
- HealthCheckConfigenabled、interval_seconds、timeout_seconds、healthy_threshold、unhealthy_threshold
- DockerConfigmulti_image_config、network_mode、work_dir、auto_cleanup、container_ttl_seconds
- agent_runner 配置
- AppConfigdefault_agent、projects_dir、port、proxy_config
- ProxyConfiglisten_port、default_backend_port、backend_host、port_param、health_check
- HealthCheckConfigenabled、interval_seconds、timeout_seconds、healthy_threshold、unhealthy_threshold
- 环境变量覆盖
- rcoderRCODER_PORT、RCODER_PROJECTS_DIR、RCODER_NETWORK_MODE、RCODER_WORK_DIR、RCODER_AUTO_CLEANUP、RCODER_CONTAINER_TTL
- agent_runnerRCODER_PORT、RCODER_PROJECTS_DIR部分
章节来源
- [rcoder 配置](file://crates/rcoder/src/config.rs#L37-L110)
- [rcoder 配置](file://crates/rcoder/src/config.rs#L112-L210)
- [rcoder 配置](file://crates/rcoder/src/config.rs#L253-L332)
- [agent_runner 配置](file://crates/agent_runner/src/config.rs#L38-L110)
- [agent_runner 配置](file://crates/agent_runner/src/config.rs#L112-L180)
- [agent_runner 配置](file://crates/agent_runner/src/config.rs#L252-L315)
### 与容器与镜像的关系
- 服务镜像配置
- ServiceImageConfigimage/arm64_image/amd64_image/default_image、environment、mounts、resource_limits、work_dir、network_mode、container_path_template
- 支持镜像选择、环境变量合并、挂载点校验与路径模板解析
- Docker 配置
- rcoder DockerConfig 支持多镜像配置与环境变量覆盖,提供验证与摘要信息
- 启动时合并应用配置与多镜像配置,初始化全局 DockerManager
章节来源
- [服务镜像配置](file://crates/shared_types/src/service_config.rs#L1-L120)
- [服务镜像配置](file://crates/shared_types/src/service_config.rs#L120-L262)
- [服务镜像配置](file://crates/shared_types/src/service_config.rs#L314-L401)
- [rcoder 配置](file://crates/rcoder/src/config.rs#L148-L211)
## 依赖关系分析
- 日志与追踪
- rcoder/agent_runner 主程序分别初始化 tracing-subscriber 与 OpenTelemetry Propagator
- 追踪中间件依赖 tracing/tracing-opentelemetry生成/注入 trace_id
- 代理与监控
- 代理 API 依赖 Pingora 服务对象,读取配置、后端列表与健康快照
- 代理配置包含健康检查参数,启动时可开启健康检查循环
- 清理任务
- rcoder 清理任务依赖 DockerManager 全局实例,清理孤立容器与会话
- agent_runner 清理任务清理 SSE 会话与消息
- 错误处理
- AppError 实现 IntoResponse统一错误返回格式
```mermaid
graph LR
RCMain["rcoder 主程序"] --> RT["追踪中间件"]
RCMain --> RP["代理 API 处理器"]
RCMain --> RClean["rcoder 清理任务"]
AMain["agent_runner 主程序"] --> AT["追踪中间件"]
AMain --> AP["代理 API 处理器"]
AMain --> AClean["agent_runner 清理任务"]
RT --> TE["OpenTelemetry Propagator"]
AT --> TE
RP --> P["Pingora 代理服务"]
AP --> P
RClean --> DM["DockerManager 全局实例"]
AClean --> SSE["SSE 会话/消息"]
RP --> AE["AppError"]
AP --> AE
```
图表来源
- [rcoder 主程序](file://crates/rcoder/src/main.rs#L274-L320)
- [agent_runner 主程序](file://crates/agent_runner/src/main.rs#L181-L231)
- [rcoder 追踪中间件](file://crates/rcoder/src/middleware/tracing_middleware.rs#L71-L130)
- [agent_runner 追踪中间件](file://crates/agent_runner/src/middleware/tracing_middleware.rs#L71-L130)
- [rcoder 代理 API 处理器](file://crates/rcoder/src/handler/proxy_handler_api.rs#L1-L120)
- [agent_runner 代理 API 处理器](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L1-L120)
- [rcoder 清理任务](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L431-L602)
- [agent_runner 清理任务](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L156-L245)
- [共享错误类型](file://crates/shared_types/src/model/app_error.rs#L1-L65)
章节来源
- [rcoder 主程序](file://crates/rcoder/src/main.rs#L274-L320)
- [agent_runner 主程序](file://crates/agent_runner/src/main.rs#L181-L231)
- [rcoder 代理 API 处理器](file://crates/rcoder/src/handler/proxy_handler_api.rs#L1-L120)
- [agent_runner 代理 API 处理器](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L1-L120)
- [rcoder 清理任务](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L431-L602)
- [agent_runner 清理任务](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L156-L245)
- [共享错误类型](file://crates/shared_types/src/model/app_error.rs#L1-L65)
## 性能考量
- 日志滚动与保留
- 按天滚动,限制日志文件数量,降低磁盘占用与 IO 压力
- 代理指标
- 通过 /proxy/stats 获取平均响应时间等关键指标,辅助容量规划与性能调优
- 清理策略
- rcoder 清理任务对孤立容器清理加总超时与单次上限,避免阻塞
- agent_runner 清理任务仅清理 Idle 且超时的 agent避免中断活跃任务
- 超时与保护
- 清理过程整体超时、单容器清理超时、新建容器保护期,提升稳定性
章节来源
- [rcoder 主程序](file://crates/rcoder/src/main.rs#L274-L320)
- [agent_runner 主程序](file://crates/agent_runner/src/main.rs#L181-L231)
- [rcoder 清理任务](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L431-L602)
- [agent_runner 清理任务](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L156-L245)
## 故障排查指南
- Docker 相关
- 启动时自动检测宿主机挂载路径,失败时提供详细配置帮助与排错步骤
- 建议检查 DOCKER_SOCKET_PATH、Docker socket 权限与挂载路径
- 代理未启用
- 调用 /proxy/* 接口返回 SERVICE_UNAVAILABLE需确认代理配置与启动参数
- 日志定位
- 使用 trace_id 关联请求全链路日志,结合 /proxy/stats 观察异常时段的指标波动
- 清理异常
- rcoder 清理任务对单次清理与总清理过程设置超时,若出现长时间卡顿,检查 Docker API 可用性与容器状态
- 健康检查
- /health 返回 healthy 表示服务正常,若异常需结合日志与代理状态进一步排查
章节来源
- [rcoder 主程序](file://crates/rcoder/src/main.rs#L48-L118)
- [rcoder 主程序](file://crates/rcoder/src/main.rs#L322-L351)
- [rcoder 代理 API 处理器](file://crates/rcoder/src/handler/proxy_handler_api.rs#L1-L120)
- [agent_runner 代理 API 处理器](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L1-L120)
- [rcoder 清理任务](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L431-L602)
## 结论
本项目通过统一的日志与链路追踪中间件、Pingora 代理指标、定时清理任务与统一错误类型构建了完善的可观测性体系。rcoder 与 agent_runner 在同一套可观测框架下运行,既保证了跨服务的 trace_id 一致性,又提供了可操作的健康检查与代理监控接口。建议在生产环境中结合日志滚动策略、代理指标与清理任务配置,持续优化性能与稳定性。