FastGPT Redis/BullMQ SigNoz 告警实战:从稳定日志合同到生产级告警规则
【免费下载链接】FastGPTFastGPT is a knowledge-based platform built on the LLMs, offers a comprehensive suite of out-of-the-box capabilities such as data processing, RAG retrieval, and visual AI workflow orchestration, letting you easily develop and deploy complex question-answering systems without the need for extensive setup or configuration.项目地址: https://gitcode.com/GitHub_Trending/fa/FastGPT
本文基于 FastGPT 仓库中的 Redis/BullMQ 告警手册 signoz-redis-alerts.md,完整讲解如何以 DAL 层输出的 OTel 日志字段为基础,在 SigNoz 中配置覆盖连接层、队列层、业务 Cache 与限流层的 10 类 P1/P2 告警规则。读完本文,你可以理解每条规则的 Filter、阈值、分组字段与降噪策略背后的失败语义,并能在源码中定位每条告警消息的确切产生位置与测试保障。
一、设计思想:匹配稳定日志消息,分组只用低基数字段
1.1 告警可用的 OTel 字段
FastGPT 的 Redis 告警不依赖异常堆栈,而是以 DAL 层(@fastgpt/dal)主动输出的、经过测试固定的日志消息为匹配锚点。SigNoz 侧可用字段如下:
| SigNoz 字段 | 用途 |
|---|---|
service.name | 应用/进程边界 |
severity_text | error、warn、info、debug |
body.__log_message | 稳定日志消息,告警的主要匹配字段 |
body.* | role、name等低基数 metadata |
category | LogTape category,目前不同 Cache/Runtime 尚未统一 |
其中error对象、完整 Redis URL、teamId、userId、sessionId、shareId、jobId、key等高基数字段只用于排查,不得用于通知分组或模板——按这些字段分组会生成无限增长的通知组,造成告警风暴。
1.2 为什么不匹配 category
Runtime 与 BullMQ logger 当前通常继承['system'],业务 Cache 使用各自领域 category。在 category 统一之前,上述规则默认不增加 category 条件,否则会漏掉 Runtime、BullMQ 和多数 Cache 日志。基础设施 category 统一后的目标状态见本文第五节。
1.3 消息稳定性的测试保障
日志消息不是随手写出的字符串:DAL 的单元测试逐条断言了告警所依赖的消息文本。例如:
- dailyActiveDedupe.test.ts 断言
Daily active dedupe failed open; - lease.test.ts 断言
Redis lease renew failed; - session.test.ts 断言
Invalid Redis session record; - teamPoint.test.ts 断言
Failed to get team point cache; - workflowStopSignal.test.ts 断言
Workflow stop signal read failed open; - bullmq-services.test.ts 断言
Failed to push collection update job; - streamResume.test.ts 断言
Failed to mirror stream response to redis。
这意味着“重命名日志消息”在仓库内会先被测试拦截,也为手册中“消息重命名必须同步更新对应规则”的约束提供了工程基础。
二、使用前提:service.name
告警示例统一使用:
service.name = 'fastgpt-cn-client'实际值由 OTEL service name 环境变量决定。packages/service/env.ts 中定义了LOG_OTEL_SERVICE_NAME、METRICS_OTEL_SERVICE_NAME、TRACING_OTEL_SERVICE_NAME等变量,默认值均为fastgpt-client;不同环境部署可将其设置为各自的应用名(如示例中的fastgpt-cn-client)。
App 与 Pro 使用不同 service name 时分别创建规则,不要为了复用查询合并两个进程——合并会掩盖单侧进程的故障边界,也使service.name分组失去区分能力。
三、通用配置
所有规则共享以下默认配置:
| 参数 | 默认值 |
|---|---|
| Evaluation window | Rolling 5 分钟 |
| Evaluation frequency | 1 分钟 |
| No-data | No alert / OK |
| Match type | at least once |
| Repeat notification | P1 15 分钟;P2 60 分钟 |
| 推荐 Group By | body.__log_message、body.role、body.name、service.name |
发布、Redis 维护和故障演练使用 SigNoz maintenance window 或通知路由静默,不修改 Filter 绕过一次发布。
四、连接层规则:R1–R3
连接层日志统一由进程级 Redis Runtime 输出。connection.ts 中的RedisRuntime按command/blocking/queue/worker四种角色管理连接,每个 ioredis 事件都映射为一条带rolemetadata 的稳定日志。
R1. Redis 连接错误(P1)
- Filter:
service.name = 'fastgpt-cn-client' AND severity_text = 'error' AND body.__log_message = 'Redis connection error'- Aggregate:
count();Group By:body.role、service.name。 - 阈值:同一 role 5 分钟内
>= 3。 - 处理:检查 Redis 实例、网络、认证和连接数,并关联 R3/R4。
源码依据:connection.ts 在error事件上记录Redis connection error并附带role,同时上报connection.errormetric。由于按role分组,可以区分是命令连接、阻塞连接还是 BullMQ 队列/Worker 连接出问题。
R2. Redis 进程关闭失败(P1)
- Filter:
service.name = 'fastgpt-cn-client' AND severity_text = 'error' AND body.__log_message = 'Redis runtime close failed after process shutdown signal'- Aggregate:
count();Group By:service.name。 - 阈值:5 分钟内
>= 1。 - 处理:关联部署信号、进程退出码、Next.js drain 和 BullMQ close 日志。
源码依据:shutdown.ts 注册了 SIGTERM/SIGINT 处理,信号触发后执行runtime.close();成功路径输出Redis runtime closed after process shutdown signal(info,进程退出码 0),失败路径输出本规则匹配的错误消息(进程退出码 1)。因此该消息天然与发布/缩容动作强相关,单条即 P1,处理时应先看部署平台侧的信号与退出码。
R3. Redis 重连抖动(P2)
- Filter:
service.name = 'fastgpt-cn-client' AND severity_text = 'warn' AND ( body.__log_message = 'Redis connection closed' OR body.__log_message = 'Redis reconnect scheduled' OR body.__log_message = 'Redis reconnect requested by command error' )- Aggregate:
count();Group By:body.role、service.name。 - 阈值:同一 role 5 分钟内
>= 5;单条 close 不告警。 - 处理:R1 同时触发时按连接故障处理,否则检查 failover、网络抖动和连接压力。
源码依据:Redis connection closed由 connection.ts 的close事件输出;Redis reconnect scheduled与Redis reconnect requested by command error由 policy.ts 在重连策略层输出。阈值>= 5的降噪意图是:偶发 failover 切换会产生 1~2 条 close+reconnect,只有持续抖动才值得通知。
五、队列层规则:R4–R5
R4. BullMQ Queue/Worker 错误(P1)
- Filter:
service.name = 'fastgpt-cn-client' AND severity_text = 'error' AND ( body.__log_message = 'BullMQ queue error' OR body.__log_message = 'BullMQ worker error' OR body.__log_message = 'BullMQ worker restart failed, will retry' )- Aggregate:
count();Group By:body.name、service.name。 - 阈值:同一 queue/worker 5 分钟内
>= 3。 - 处理:先排除 R1;Redis 正常时检查 processor、job payload 和 BullMQ 版本。
源码依据:
BullMQ queue error:queue-manager.ts,Queue 的error事件处理器,namemetadata 即队列名。BullMQ worker error:worker-manager.ts。BullMQ worker restart failed, will retry:worker-manager.ts 中 Worker 关闭后自动重启循环的失败分支——Worker 意外关闭会触发带restartDelayMs的重试,连续重启失败才会打出这条 error。
R5. BullMQ 生命周期异常(P2,非部署窗口可提升 P1)
- Filter 消息(8 条,叠加
severity_text = 'warn',用 OR 匹配body.__log_message):
BullMQ worker closed, attempting restart BullMQ worker resume failed BullMQ queue close failed BullMQ worker close failed BullMQ queue connection forced disconnect failed BullMQ worker connection forced disconnect failed Failed to release Redis connection after BullMQ queue creation error Failed to release Redis connection after BullMQ worker creation error- Aggregate:
count();Group By:body.name、body.__log_message。 - 阈值:5 分钟内
>= 3;close/forced-disconnect failure 可单独设置>= 1。 - 降噪:部署期间静默;单条
worker closed不代表故障。
源码依据:
BullMQ worker closed, attempting restart与BullMQ worker resume failed:worker-manager.ts,前者是closed事件在 running 状态下触发自动重启的日志,后者是paused后延迟 resume 失败。BullMQ queue close failed:queue-manager.ts;BullMQ worker close failed:worker-manager.ts,两者均在带超时的close()失败后降级为强制断连。- 两条
Failed to release Redis connection after BullMQ ... creation error:Queue/Worker 创建抛错时释放底层连接的兜底日志,见 queue-manager.ts 与 worker-manager.ts。 - 从源码结构看,
... forced disconnect failed由关闭兜底模块 close.ts 的forceDisconnect统一输出,对应 queue/worker 主连接与 worker blocking 连接两类资源。
六、业务 Cache 规则:R6
R6. Redis Cache 持续降级(P2)
业务 Cache 的降级路径在 DAL 内刻意区分了 fail-open(业务放行、记 warn)与硬失败(记 error),这些消息共同构成“Redis 正在影响业务但连接层尚未全面故障”的信号:
Daily active dedupe failed open DingTalk accessToken cache read failed DingTalk accessToken cache write failed Invalid Redis session record Failed to delete invalid Redis session record Redis lease renew failed Redis lease acquire failed Redis lease release failed Failed to get team point cache Failed to set team point cache Failed to increment team point cache Failed to clear team point cache Workflow stop signal read failed open Workflow stop signal clear failed Failed to get team vector count cache Failed to set team vector count cache Failed to invalidate team vector count cache- Filter 叠加
severity_text IN ('error', 'warn'),用 OR 匹配上述消息。 - Aggregate:
count();Group By:body.__log_message、service.name。 - 阈值:5 分钟内
>= 10;session 损坏或 lease acquire failure 可设>= 3。 - 处理:R1 未触发时,检查单一 Cache 的数据格式、TTL 和降级路径。
源码抽查印证了这些消息的落点,例如:
Daily active dedupe failed open:dailyActiveDedupe.ts,Redis 读失败时选择放行(failed open),仅影响去重统计。Redis lease renew failed/Redis lease renew failed because token no longer matches:lease.ts,租约续约是互斥与锁语义的基础,因此可设更低的>= 3阈值。Invalid Redis session record:session.ts,属于数据损坏信号。Workflow stop signal read failed open:workflowStopSignal.ts,读失败时无法确认工作流停止信号,fail-open 会让停止操作可能失效。Failed to get team point cache:teamPoint.ts。
特别说明:Skipped invalid team point cache value(teamPoint.ts)属于数据质量信号,表示某条缓存值非法被跳过,不代表 Redis 可用性问题,不并入本告警。
七、流恢复规则:R7
R7. Stream Resume 镜像失败(P1;内存压力状态变化为 P2)
FastGPT 支持会话流式响应中断后从 Redis 镜像恢复。P1 消息(恢复链路硬失败):
Failed to clear stream resume redis keys before mirror Failed to mirror stream response to redis Failed to shrink stream resume redis ttl- 阈值:合计 5 分钟内
>= 5;恢复能力属于核心 SLA 时可低频通知单次失败。
P2 消息(状态/检查类):
Disabling new stream resume mirrors due to Redis memory pressure Failed to inspect Redis memory pressure for stream resume mirror Failed to persist stream resume unavailable state cleanStaleGeneratingChats: failed to inspect stream resume activity- 阈值:内存压力状态变化
>= 1/10 分钟;检查或状态写入失败>= 3/5 分钟。
源码依据:镜像写入与 key 清理失败日志在 streamResume.ts 中(如Failed to mirror stream response to redis);内存压力导致禁用新镜像的日志由 Service 层 resume.ts 输出,说明该规则跨越 DAL 与 service 两层,分组只用body.__log_message和service.name才能兼容两层日志。
八、限流规则:R8
R8. 限流服务 Fail-closed(P1)
限流是少数 Redis 故障直接转换为用户可见 429的路径,因此定为 P1:
- Filter:
service.name = 'fastgpt-cn-client' AND severity_text = 'error' AND ( body.__log_message = 'Fixed window rate limit failed closed' OR body.__log_message = 'Team QPM configuration lookup failed closed' OR body.__log_message = 'Team QPM rate limit failed closed' )- Aggregate:
count();Group By:body.__log_message、body.type。 - 阈值:5 分钟内
>= 1;高流量环境可使用>= 3。 - 禁止按 teamId 或 key 分组。
源码依据:frequencyLimit.ts 中,QPM 配置查询失败与限流计数失败都会打出对应的failed closed日志并立即返回code: 429(Rate limit service unavailable)。底层限流实现为固定窗口算法,计数原子性由 DAL 的 rateLimit.ts 保证,且该 Cache 的注释明确“Redis 执行错误向上抛出,由 Service 层按场景映射故障策略”——这正是 fail-closed 语义的出处。需要说明的是:当前仓库源码中可确认的是两条 Team QPM 消息,Fixed window rate limit failed closed属于限流 Cache 层 fail-closed 场景的预留文案,在配置规则时保留该分支不会造成误报。
九、Pro 专属规则:R9
R9. Pro 企微订单 Cache 故障(P1,由支付错误率决定是否降为 P2)
- Filter:
service.name = 'fastgpt-cn-client' AND severity_text = 'error' AND ( body.__log_message = 'Failed to get WeChat Work pending order cache' OR body.__log_message = 'Failed to set WeChat Work pending order cache' OR body.__log_message = 'Failed to clean WeChat Work pending order cache' )- Aggregate:
count();Group By:body.__log_message、service.name。 - 阈值:5 分钟内
>= 1,只关注持续故障时使用>= 3。 - 禁止按 teamId 或 orderId 分组。
按 DAL 设计文档 的所有权约定,Pro 专属 Cache 保留在pro/admin/src/dal,因此该规则仅适用于部署 Pro 侧(企业微信/支付能力)的环境;订单缓存读写失败会直接打断“下单-轮询-回调”的支付闭环,故阈值比 R6 更严格。
十、业务任务规则:R10
R10. BullMQ 业务任务失败
这类错误来自各队列的 service 层封装,不能单独证明 Redis 不可用,应与 R1/R4 分开配置:
Failed to push collection update job Failed to update collection Failed to check evaluation job status Failed to remove evaluation job Failed to enqueue skill creation job, marked skill creation failed Failed to resume pending skill creation jobs Failed to resume marked skill delete jobs Reply job failed Wechat getUpdates request failed getUpdates API error Schedule next poll (completed) failed Schedule next poll (failed) failed- 严重度和阈值按业务 SLA,默认
>= 3/5 分钟。 - Group By 使用稳定消息或业务 category;
shareId只能做去重计数,不能形成通知组。 - R1/R4 未触发时,按 processor、第三方 API 或 job payload 排查。
源码落点均在 packages/dal/redis/bullmq/services/ 下:Failed to push collection update job见 collectionUpdate.ts,Failed to check evaluation job status见 evaluation.ts;Wechat getUpdates request failed属于第三方 API 拉取失败,落在 Service 层 wechat/mq.ts。这类日志混有“Redis 推任务失败”和“任务处理器本身失败”两种根因,所以必须与连接层规则解耦,避免 Redis 恢复后仍被业务侧误判为缓存故障。
十一、Dashboard 边界:哪些只画曲线不通知
以下消息属于正常生命周期与恢复信号,只用于 dashboard 或趋势,不直接通知:
Redis connection established Redis connection ready Redis runtime closed after process shutdown signal BullMQ worker ready BullMQ worker restarted successfully BullMQ worker paused Collection update job pushed Dataset sync scheduler reconcile finished Redis memory pressure recovered; stream resume mirror creation resumed幂等补偿、资源已不存在和 active job 无法删除等 warning 也属于业务 dashboard。只有它们与 R1/R4 或明确业务 SLA 同时满足时才升级。其中前四条可在 connection.ts 的connect/ready事件与 shutdown.ts 的正常关闭路径中找到对应输出,BullMQ worker ready/restarted successfully/paused则对应 worker-manager.ts 的生命周期事件——把它们保留在曲线上,恰好可以反向验证 R1~R5 触发与否。
十二、维护约束:消息重命名与 category 统一
- 日志消息重命名必须同步更新对应 SigNoz 规则,且仓库内 DAL 测试会先拦截这类改动;本文档刻意不维护一份与源码重复的全量消息清单,规则以 signoz-redis-alerts.md 为唯一事实来源。
- 基础设施 category 统一后,Redis Runtime/health/shutdown 使用
LogCategories.INFRA.REDIS,BullMQ Runtime 使用LogCategories.INFRA.QUEUE;业务 Cache 保留领域 category,并额外提供低基数component字段。 - 在 SigNoz 中确认 category 的实际存储类型之前,不批量修改现有规则,避免规则静默失效。
小结
FastGPT 的 Redis 告警体系可以概括为四层防线:连接层(R1–R3)回答“Redis 还能不能连上”,队列层(R4–R5)回答“任务链路是不是断的”,业务 Cache 层(R6、R7、R8)回答“降级是否已经影响用户”,Pro/业务任务层(R9、R10)回答“具体业务闭环是否受损”。所有规则共享同一套低基数分组纪律与 5 分钟滚动窗口,并通过维护窗口而非修改 Filter 的方式应对发布与演练。由于每条告警消息都有源码落点和单元测试钉住,这套规则具备可审计、可回归的长期可维护性。
【免费下载链接】FastGPTFastGPT is a knowledge-based platform built on the LLMs, offers a comprehensive suite of out-of-the-box capabilities such as data processing, RAG retrieval, and visual AI workflow orchestration, letting you easily develop and deploy complex question-answering systems without the need for extensive setup or configuration.项目地址: https://gitcode.com/GitHub_Trending/fa/FastGPT
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考