Skip to content

fix(pilot): debounce process resource alarms - #140

Open
Monsooooon wants to merge 1 commit into
mainfrom
code-issue-676895-cp1
Open

fix(pilot): debounce process resource alarms#140
Monsooooon wants to merge 1 commit into
mainfrom
code-issue-676895-cp1

Conversation

@Monsooooon

Copy link
Copy Markdown
Collaborator

背景

PROCESS_RESOURCE_ALARM 当前对 CPU/Memory 采用单次超阈即告警,并且 CPU 与 Memory 共用同一个告警类型,容易造成瞬时尖峰噪声、内存重复告警以及同窗口聚合覆盖。

核心改动

  • 拆分 PROCESS_CPU_ALARMPROCESS_MEMORY_ALARM,保留原 PROCESS_RESOURCE_ALARM 类型兼容历史数据。
  • CPU 按核心数归一化后要求连续 3 个样本超阈再告警,降低瞬时尖峰噪声。
  • Memory 增加 512MB soft 连续 3 次防抖、1GB hard、2GB critical 分级语义。
  • 对进程资源告警增加 1 小时冷却,抑制同类重复上报。
  • 补充单元测试覆盖 soft memory 防抖、hard/critical 分级、CPU 连续样本、CPU/Memory 同窗口拆分、重复告警冷却。

修改文件

文件 说明
src/metrics/alarm-manager.ts 新增 CPU/Memory 独立告警类型
src/metrics/metrics-writer.ts 调整进程资源阈值、防抖、分级和冷却逻辑
tests/unit/metrics/metrics-writer.test.ts 增加资源告警策略单测

验证结果

  • 单元测试: npx vitest run tests/unit/metrics/,62/62 PASS
  • Typecheck: npm run typecheck,PASS
  • 真实 Codex E2E: 原始 session /Users/lukechen/.codex/sessions/2026/07/15/rollout-2026-07-15T10-49-06-019f63ad-9019-71f1-9022-074d5cead2aa.jsonl,Pilot trace /Users/lukechen/.loongsuite-pilot/logs/otlp-debug/loongsuite-pilot-pr-gate-codex-2026-07-15.jsonl
  • validate-trace: 1 trace / 16 spans,ENTRY=1、AGENT=1、STEP=5、LLM=5、TOOL=4,PASS=33,WARN=170,ERROR=0
  • Alarm logstore: PROCESS_CPU_ALARM 1 条,PROCESS_MEMORY_ALARM 1 条,均在 loongsuite_alarm / cn-shanghai 查询命中

备注

开源 PR 分支从 GitHub main 创建并重放本次 3 文件补丁,避免把内部仓库历史带入开源 PR。

Split CPU and memory process alarms so they no longer collide in aggregation. Debounce normalized CPU and soft memory thresholds, add hard and critical memory tiers, and cool down repeated process resource alerts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Monsooooon

Copy link
Copy Markdown
Collaborator Author

Reviewer self-check

No blocking findings in the submitted diff.

Checked scope: 1 commit (8610436), 3 files only, based on GitHub main to avoid carrying internal repository history.

Verification confirmed:

  • npx vitest run tests/unit/metrics/: 62/62 PASS
  • npm run typecheck: PASS
  • Real Codex E2E trace: 5 STEP / 4 TOOL, validate-trace ERROR=0
  • Alarm logstore: PROCESS_CPU_ALARM and PROCESS_MEMORY_ALARM both queried successfully
  • GitHub checks: CodeQL, CI build-and-test matrix, and CLA all PASS

@ralf0131 ralf0131 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Improves process resource alarm reliability by splitting the generic PROCESS_RESOURCE_ALARM into specific PROCESS_CPU_ALARM and PROCESS_MEMORY_ALARM types. CPU threshold now normalizes by core count (cpuPercent / cpuCoreCount) and requires 3 consecutive high samples before alarming — correctly preventing false positives on multi-core machines. Memory uses a tiered approach: soft (512MB, 3 consecutive samples), hard (1024MB, immediate), critical (2048MB, immediate, level 3). A 1-hour per-type cooldown (lastProcessAlarmAt map) prevents alarm spam. Tests are comprehensive — covering debounce behavior, tiered levels, CPU normalization, combined CPU+memory windows, and cooldown timing.

No issues found — well-designed debounce logic with thorough test coverage.


Automated review by github-manager-bot

@ralf0131

Copy link
Copy Markdown
Collaborator

📋 Ready to merge — approved 76h ago, CI passing, no merge conflicts.

This PR has been approved and all checks pass, but hasn't been merged yet. Pinging maintainers for follow-up.


Automated notification by github-manager-bot

}

const cpuCoreCount = Math.max(os.cpus().length, 1);
const normalizedCpuPercent = Math.round((cpuPercent / cpuCoreCount) * 100) / 100;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[High] CPU 归一化后阈值对单线程 Node 主进程可能不可达

metrics.cpucalcCpuPercent 计算,为 per-core 口径(100% = 占满 1 核,可 >100)。这里除以 os.cpus().length 归一化为整机百分比后再与 80% 比较。

影响: loongsuite-pilot 以单线程事件循环为主,典型 CPU 失控约占满 1 核 = raw ~100%,归一化后在 8 核机上仅 12.5%,永远达不到 80%;要触发需 raw > 80×核数(8 核需 >640%)。结果 PROCESS_CPU_ALARM 对主进程在多核机器上静默失效。

建议: 二选一并明确文档:(a) 维持 per-core 口径不除以核数,以"占满 ~0.8 核"为线,更贴合单线程 Node;或 (b) 确要整机口径则将阈值按核数放缩/独立配置。请确认当前阈值不可达是否为预期。

this.cpuHighSamples++;
if (this.cpuHighSamples < CPU_ALARM_CONSECUTIVE_SAMPLES) return;

this.recordProcessAlarm(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Medium] PROCESS_RESOURCE_ALARM 类型迁移需同步下游告警规则

拆分后 PROCESS_RESOURCE_ALARM 不再产出,改为 PROCESS_CPU_ALARM / PROCESS_MEMORY_ALARM(旧枚举仅为历史数据兼容)。

影响: 下游若有按 alarm_type == 'PROCESS_RESOURCE_ALARM' 建立的 SLS 告警规则/看板,上线后将静默停止命中,形成"告警看似正常实则未覆盖"的盲区。

建议: 上线前同步下游告警规则/看板到新类型,并在 PR 描述或运维变更单显式列出需更新项,release note 标注类型迁移。

@linrunqi08

Copy link
Copy Markdown
Collaborator

🔍 Code Review Summary

Severity Count
Critical 0
High 1
Medium 1
Low 2

Lifecycle Verdict

Check Result
资源释放 PASS
死锁/卡死风险 PASS
状态恢复正确性 PASS

总体结论

方向正确、无绝对阻断项。拆分 CPU/Memory 告警类型从根源解决了 AlarmManager 同 key 聚合互相覆盖的问题,内存分级 + 防抖 + 冷却设计合理,单测覆盖充分。

合入前需确认两点:

  1. [High] CPU 归一化语义:metrics.cpu 为 per-core 口径(100%=占满 1 核),除以 os.cpus().length 后与 80% 比较,导致单线程 Node 主进程在多核机器上 PROCESS_CPU_ALARM 事实不可达(8 核需 raw>640%)。需确认是否为预期,否则 CPU 告警对主进程静默失效。
  2. [Medium] 类型迁移:PROCESS_RESOURCE_ALARM 不再产出,下游按该类型建立的告警规则/看板需同步迁移到新类型,避免覆盖盲区。

Highlights(正向实践)

  • 拆分 CPU/Memory 告警类型,解决同窗口聚合覆盖。
  • 内存 soft/hard/critical 分级:hard/critical 首样本即告警,soft 防抖。
  • 保留 PROCESS_RESOURCE_ALARM 枚举兼容历史数据。
  • 单测用 os.cpus() 动态构造超阈输入,覆盖防抖/分级/拆分/冷却。

评审报告详见: code-review/pr-140/final-report.md
Generated by LoongSuite-Pilot Code Review Agent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants