ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Onyx 本地监控栈实战:用 Prometheus + Grafana 观测 API 与 Celery 索引流水线

Onyx 本地监控栈实战:用 Prometheus + Grafana 观测 API 与 Celery 索引流水线 Onyx 本地监控栈实战用 Prometheus Grafana 观测 API 与 Celery 索引流水线【免费下载链接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM项目地址: https://gitcode.com/GitHub_Trending/da/danswer本文是一份基于 Onyx 开源仓库AI Chat 平台兼容各类 LLMtools/profiling目录的本地监控指南。它讲解如何用一套 Docker Compose 启动的 Prometheus Grafana 栈对本地开发环境中的 Onyx API Server 与 5 类 Celery Worker 进行指标采集与可视化并预加载三张针对 Onyx 后端深度定制的仪表盘DB 连接池健康、索引流水线、权限同步。读完本文你将能一键起监控、读懂每张仪表盘背后的 PromQL 与指标语义、按需覆盖端口与密码等配置并安全地在 Grafana UI 中迭代仪表盘而不丢失改动。一、监控栈概览为本地开发而生tools/profiling下的这套栈定位非常明确——本地开发调试。它不是生产部署方案而是让开发者在本机就能看到后端在做什么、瓶颈在哪里的仪表盘工具箱。核心组件只有两个Prometheusprom/prometheus:v3.2.1时序数据库负责抓取并存储指标Grafanagrafana/grafana:11.6.0可视化面板预加载了 Onyx 后端的定制仪表盘。整个栈由 docker-compose.yml、prometheus.yml 以及grafana/下的 provisioning 配置共同驱动所有文件都集中在 tools/profiling 目录内独立、可复现、可丢弃。两个容器都通过extra_hosts配置了host.docker.internal:host-gateway这意味着 Prometheus 可以通过宿主机回环地址直接抓取你在 IDE如 VSCode中本地启动的 Onyx 进程而无需将后端也容器化——这正是本地开发监控的关键设计。二、一键启动两条命令进入监控界面启动与关闭都非常简单cd tools/profiling/ docker compose up -d首次启动会拉取prom/prometheus:v3.2.1与grafana/grafana:11.6.0两个镜像并创建命名卷prometheus_data、grafana_data指标与面板数据在容器重建后依然保留。启动完成后两个服务即可访问服务地址凭据Grafanahttp://localhost:3001admin / adminPrometheushttp://localhost:9090—需要停止时执行docker compose down即可注意这不会删除命名卷历史指标仍在只有加-v才会清空卷。2.1 存储与运行参数Prometheus 服务的command中预设了几个值得留意的参数见 docker-compose.yml--storage.tsdb.path/prometheusTSDB 数据落在命名卷中--storage.tsdb.retention.time200h指标默认保留约 8.3 天适合本地调试周期也避免磁盘被长期占用--web.enable-lifecycle开启动态重载能力可通过POST /-/reload热加载配置方便你反复调整prometheus.yml时无需重启容器。三、Scrape Targets抓哪些进程、在哪个端口Prometheus 的抓取配置集中在 prometheus.yml。全局抓取间隔为 15s而对 Onyx 相关 Job 全部收窄到5s以便在本地调试时看到足够细的时间粒度。Job端口抓取目标说明prometheus9090localhost:9090Prometheus 自身监控onyx-api-server8080FastAPI/metrics与 .vscode/launch.json 中的 API Server 启动配置端口一致onyx-monitoring-worker9096Celery 监控 Worker负责心跳、队列深度等监控类指标onyx-docfetching-worker9092Celery 文档抓取 Worker拉取源数据onyx-docprocessing-worker9093Celery 文档处理 Worker切分、embedding 等处理onyx-heavy-worker9094Celery 重型 Workerpruning、权限同步、外部组同步等重任务onyx-light-worker9095Celery 轻型 WorkerVespa 同步、删除、权限 upsert 等轻任务所有 Onyx Job 的metrics_path都是/metrics目标地址统一写为host.docker.internal:port与容器内host-gateway的映射配合直接抓取宿主机的本地进程。3.1 端口分配的启示从 README 与 prometheus.yml 可以归纳出 Onyx 后台任务体系的一个关键事实每个 Celery Worker 都在独立端口暴露自己的/metrics。这样 Prometheus 可以用 5 个独立的 Job 分别标注指标来源仪表盘上就能按 worker 类型区分指标例如区分文档抓取与文档处理的吞吐与延迟。这种按职责分 Worker、按端口分指标的设计是诊断索引瓶颈时最有力的抓手——你一眼就能看出是抓取慢、处理慢还是重型任务权限同步拖了后腿。四、环境变量端口与密码可覆盖默认端口 3001Grafana可能与你的其他本地服务冲突默认密码admin也可能想改掉。这套栈支持通过.env文件放在tools/profiling/目录下或直接在 shell 中导出环境变量来覆盖默认值docker-compose.yml 中使用了${VAR:-default}语法变量默认值说明PROMETHEUS_PORT9090Prometheus UI 的宿主机端口GRAFANA_PORT3001Grafana UI 的宿主机端口GF_ADMIN_PASSWORDadminGrafana 管理员密码例如想改用 3002 端口并设置强密码cat tools/profiling/.env EOF PROMETHEUS_PORT9091 GRAFANA_PORT3002 GF_ADMIN_PASSWORDmy-strong-pass EOF cd tools/profiling/ docker compose up -d注意GF_ADMIN_PASSWORD通过容器环境变量GF_SECURITY_ADMIN_PASSWORD注入 Grafana是首次启动时初始化管理员凭据的机制如果之前已经用旧密码初始化过数据卷仅改环境变量不会重置已有密码。五、三大预置仪表盘深度解析Grafana 通过 provisioning 自动加载仪表盘无需手动导入。仪表盘 JSON 存放在 grafana/dashboards/onyx/ 目录下共三张。5.1 Onyx DB Pool Health —— 连接池是聊天并发的咽喉仪表盘文件db-pool-health.json。它专为诊断 PostgreSQL 连接池瓶颈设计默认展示最近 15 分钟数据刷新间隔 5s。核心面板与 PromQL 如下面板PromQL 关键表达式关注点Pool Connections Checked Out (sync)onyx_db_pool_checked_out{enginesync}叠加onyx_db_pool_size{enginesync}虚线应用代码当前持有的连接数应短暂尖峰后回落至 ~0若随并发流式请求持续爬升并居高不下说明存在连接泄漏Pool Connections Checked Out (all engines)onyx_db_pool_checked_out按enginesync / async / readonly堆叠的全局占用视图Connections Held by Endpointonyx_db_connections_held_by_endpoint{enginesync} 0哪些 API handler 正持有 DB 连接可定位到具体接口Connection Hold Duration (p50/p95/p99)histogram_quantile(0.95, sum by (le)(rate(onyx_db_connection_hold_seconds_bucket{enginesync}[1m])))连接被持有的时长分布p95 应从流式响应全程30s降到亚秒级才算健康Async vs Sync Hold Duration (p99)同上分别对enginesync与engineasync取 p99sync 修复后应亚秒级async 因 FastAPI 认证依赖在整个StreamingResponse生命周期内持有 session会持续偏高Pool Checkout Raterate(onyx_db_pool_checkout_total{enginesync}[30s])/rate(onyx_db_pool_checkin_total{enginesync}[30s])每秒 checkout/checkin 速率修复后一次聊天会变成多次短 checkout 而非一次长占用Pool Overflow Timeoutsonyx_db_pool_overflow{enginesync}与increase(onyx_db_pool_checkout_timeout_total{enginesync}[30s])overflow 超出 pool_size 的连接timeouts 拿不到连接的请求任何一次 timeout 都是用户可见错误Current Pool State / Total Checkout Timeouts / Pool Utilization % / Total Checkoutsonyx_db_pool_checked_out{enginesync}、sum(onyx_db_pool_checkout_timeout_total)、onyx_db_pool_checked_out / onyx_db_pool_size * 100、sum(onyx_db_pool_checkout_total{enginesync})当前快照、累计超时、利用率、累计 checkout 数这些指标的实际埋点位于后端 postgres_connection_pool.py从源码路径可以看出它是挂接在 Onyx 自己的 SQLAlchemy 连接池封装层上的——也就是说这张仪表盘观测的是 Onyx 对 DB 连接生命周期checkout / checkin / hold / overflow / timeout的真实管理行为而不是通用的 PG 服务器指标。仪表盘还内置了$DS_PROMETHEUS数据源模板变量随 provisioning 自动指向本地 Prometheus。5.2 Onyx Indexing Pipeline v2 —— 从连接器到队列的全链路透视仪表盘文件indexing-pipeline.json。默认展示最近 1 小时数据刷新间隔 10s并内置source、connector_name、tenant_id三个下拉模板变量支持多选与 All可以直接按数据源类型、具体连接器甚至租户过滤全部面板。整体分为四块Connector Health连接器健康onyx_index_attempts_active{tenant_id~$tenant_id, source~$source, connector_name~$connector_name}按状态in_progress、not_started与连接器展示当前正在进行的索引尝试sum by (status) (onyx_connectors_by_status{tenant_id~$tenant_id})所有连接器当前状态分布Active、Paused 等的饼图sum(onyx_connectors_in_error_total{tenant_id~$tenant_id})处于持续报错状态的连接器总数黄线 1、红线 5topk(20, onyx_connector_last_success_age_seconds{...})每个连接器距上次成功索引的秒数表1 小时黄色、1 天红色是哪个连接器悄悄停滞的最直观信号onyx_connector_in_error_state 1已进入反复失败错误态、需要人工介入的连接器清单onyx_connector_docs_indexed与onyx_connector_error_count合并表每个连接器累计索引文档数与失败尝试数。Indexing Pipeline索引流水线吞吐sum by (source, outcome) (rate(onyx_indexing_task_completed_total{...}[5m])) * 60按 source 与成功/失败拆分的每分钟完成任务数延迟histogram_quantile(0.95/0.50, sum by (source, le)(rate(onyx_indexing_task_duration_seconds_bucket{...}[5m])))p95 代表最差情况、p50 代表典型情况用于揪出慢连接器类型单连接器维度同样的吞吐与 p95 延迟表达式按connector_name拆分横向对比各连接器快慢热力图sum(increase(onyx_indexing_task_duration_seconds_bucket[5m])) by (le)对数坐标用于发现双峰分布与离群任务Celery 事件rate(onyx_celery_task_retried_total[5m]) * 60、revoked、rejected重试代表瞬时故障、撤销代表被取消、拒绝代表 worker 拒收。Queue Infrastructure队列基础设施onyx_queue_depth20 种 Celery 队列各自的积压任务数高值意味着 worker 消费速度跟不上deriv(onyx_queue_depth[5m]) * 60队列深度变化率正 堆积负 排空onyx_queue_oldest_task_age_seconds 0非空队列中最老任务的等待年龄60s 黄、300s 红用于发现卡死/饥饿队列。Redis Workersonyx_redis_memory_used_bytesvsonyx_redis_memory_peak_bytes观察内存增长趋势排查泄漏或队列无界增长onyx_redis_memory_fragmentation_ratio1.5 显著碎片化1.0 意味着 Redis 在换盘严重onyx_redis_connected_clients连接数持续上升通常意味着连接泄漏onyx_celery_active_worker_count与onyx_celery_worker_up由监控 worker 每 60s 心跳探测连续 10 次未响应即判定 worker 下线up{job~onyx-.*}每个 Prometheus 抓取目标指标 HTTP 端点的存活状态红 worker 不可达或指标服务未启动。上述onyx_indexing_task_*、onyx_queue_*、onyx_connector_*等指标的埋点可在 indexing_task_metrics.py 中找到对应实现它驱动着从任务完成计数到任务耗时直方图的全套索引指标。5.3 Onyx Permission Sync —— 权限同步与外部组同步体检仪表盘文件permission-sync.json。默认展示最近 6 小时数据提供connector_type下拉过滤。它围绕 Onyx 权限体系的两条同步链路文档权限同步 外部组同步以及其底层的 Celery 任务拆成三个区域Doc Permission Sync文档权限同步onyx_doc_perm_sync_duration_seconds_bucket单次同步总耗时 p50/p95/p99按连接器类型onyx_doc_perm_sync_db_update_duration_seconds_bucket单次同步内逐元素 DB 更新的累计耗时吞吐sum(rate(onyx_doc_perm_sync_docs_processed_total{...}[$__rate_interval])) by (connector_type) * 60docs/min错误率sum(rate(onyx_doc_perm_sync_errors_total{...}[$__rate_interval])) by (connector_type) * 60errors/min累计 Statsum(onyx_doc_perm_sync_docs_processed_total)与sum(onyx_doc_perm_sync_errors_total)。External Group Sync外部组同步onyx_group_sync_duration_seconds_bucket/onyx_group_sync_upsert_duration_seconds_bucket同步总耗时与批量 upsert 耗时分位数onyx_group_sync_groups_processed_total与onyx_group_sync_users_processed_total每分钟处理组数/用户数onyx_group_sync_errors_total错误率与累计值。Celery Task MetricsPerm Sync 任务任务耗时 p95histogram_quantile(0.95, sum(rate(onyx_celery_task_duration_seconds_bucket{task_name~connector_permission_sync_generator_task|connector_external_group_sync_generator_task|check_for_doc_permissions_sync|check_for_external_group_sync}[$__rate_interval])) by (le, task_name))任务结果sum(increase(onyx_celery_task_completed_total{task_name~..., outcomesuccess|failure}[$__rate_interval])) by (task_name)撤销/重试/拒绝onyx_celery_task_revoked_total、retried_total、rejected_total排队等待 p95onyx_celery_task_queue_wait_seconds_bucket衡量任务在队列中等待执行的时间。这几组权限相关指标的后端埋点位于 perm_sync_metrics.py与 README 中onyx-heavy-worker承担 pruning, perm sync, group sync 的角色描述完全对应——权限同步这类重任务正是跑在 heavy worker 上因此排查权限同步问题时应同时盯住 heavy worker9094的存活与这张仪表盘。六、编辑仪表盘UI 可改但持久化靠文件grafana/provisioning/dashboards/dashboards.yaml中注册了两个仪表盘 Provider行为刻意做了区分providers: - name: onyx-dashboards orgId: 1 folder: Onyx type: file updateIntervalSeconds: 10 allowUiUpdates: true options: path: /var/lib/grafana/dashboards/onyx - name: onyx-dashboards-helm orgId: 1 folder: Onyx type: file updateIntervalSeconds: 10 allowUiUpdates: false options: path: /var/lib/grafana/dashboards/helm两者的关键差异onyx-dashboards本地仪表盘allowUiUpdates: true你可以在 Grafana UI 中直接编辑。但改动不会随docker compose down持久化——provisioning 的文件 Provider 会在容器启动/重载时以磁盘 JSON 覆盖。要保留修改正确姿势是在 UI 中完成调整后导出仪表盘 JSON覆盖写回grafana/dashboards/onyx/下的对应文件如indexing-pipeline.json下次启动即生效。onyx-dashboards-helm生产仪表盘allowUiUpdates: falseUI 改动被禁止因为改了也会悄悄丢失。这批仪表盘来自 Helm Chart 目录通过 docker-compose.yml 以只读卷方式挂载- ../../deployment/helm/charts/onyx/dashboards:/var/lib/grafana/dashboards/helm:ro注释写得很明确Helm chart dashboards are the source of truth for any dashboard that ships to prod。也就是说deployment/helm/charts/onyx/dashboards是随生产部署的仪表盘的唯一事实来源本地栈只负责把它们原样展示出来供迭代预览任何要上生产的仪表盘修改都应该改 Helm Chart 目录下的 JSON 文件而不是在本地 UI 里改。这一设计贯穿了本地可随意折腾、生产有唯一真源的工程原则本地迭代用tools/profiling/grafana/dashboards/onyx/生产发布用deployment/helm/charts/onyx/dashboards两者通过allowUiUpdates与只读挂载从机制上杜绝了UI 改了却不生效的坑。七、数据源自动配置datasource.yaml 负责自动注册 Prometheus 数据源无需手动创建datasources: - name: Prometheus type: prometheus access: proxy url: http://prometheus:9090 isDefault: true uid: PBFA97CFB590B2093 editable: true它通过 Docker 内部网络名prometheus:9090访问uid固定因此仪表盘 JSON 中的${DS_PROMETHEUS}模板变量总能解析到同一个数据源editable: true允许在 UI 中进一步调整。八、常见排查路径从仪表盘到源码本地监控的价值不止于看数据更在于把现象快速定位到实现。可以按下面几条路径把仪表盘指标与后端代码对应起来连接池异常看 DB Pool Health 的checked_out是否随并发爬升 → 对应实现见 postgres_connection_pool.py可据此判断是 handler 持有 session 过久还是连接池配置问题索引变慢Indexing Pipeline 中对比各source/connector_name的 p95 耗时 → 对应实现见 indexing_task_metrics.py再结合 Queue Depths 与 Oldest Task Age 判断是任务本身慢还是队列饥饿权限同步卡住Permission Sync 中看 doc/group 同步吞吐是否归零、Celery 任务 p95 是否激增 → 对应实现见 perm_sync_metrics.py同时确认 heavy worker9094的up状态。这套仪表盘 → PromQL → 后端 metrics 模块的链路正是tools/profiling目录希望给本地开发带来的调试体验不再靠猜而是让每一项指标都能追溯到一行明确的埋点代码。九、从本地到生产的边界最后需要明确这套栈的使用边界tools/profiling是本地开发/负载测试工具。README 与 docker-compose 中没有任何面向生产的多副本、认证加固、持久化 HA 配置Prometheus 数据卷、200h 保留期、admin/admin默认凭据都只适合开发环境。生产环境应当使用仓库中的 Helm Chart 所承载的仪表盘定义本地只读挂载正是为了与它保持一致并自行规划指标存储与权限方案。简言之本地调试请用tools/profiling生产可视化请以 Helm Chart 仪表盘为真源——两者各司其职共同构成 Onyx 从开发到生产的可观测性闭环。【免费下载链接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM项目地址: https://gitcode.com/GitHub_Trending/da/danswer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表