# PR #25340 完整报告

- 仓库：`sgl-project/sglang`
- 标题：fix: strip "[asctime]" prefix when parsing JSON log lines in nightly tests
- 合并时间：2026-05-15 11:17
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/25340

---

# 执行摘要

- 一句话：修复因日志前缀变更导致的夜间测试失败
- 推荐动作：值得合入以修复 CI 稳定性；可精读解析逻辑的健壮性改进，这种 `find` + try/except 模式适合作为测试中解析带前缀日志的标准模式。

# 功能与动机

三个夜间单 GPU 测试因日志格式变更持续失败，表现为 `request.received event not found` 和 `scheduler.status event not found`。PR body 引用了具体失败 CI 运行 URL。PR #24521 在 `python/sglang/srt/utils/log_utils.py:53` 添加了时间戳前缀，但测试解析逻辑未同步更新。

# 实现拆解

1. **修改 `_find_log_events` 函数 **（`test_scheduler_status_logger.py`）：用 `line.find("{")` 替换 `line.startswith("{")`，找到第一个 `{` 位置后从该处开始解析 JSON，并捕获 `json.JSONDecodeError` 跳过非 JSON 行。
2. **修改 `TestRequestLoggerJson` 的 `_verify_logs` 和 `_verify_openai_logs`**（`test_request_logger.py`）：两个方法中的 JSON 解析逻辑均改为 `line.find("{")` + `json.loads(line[idx:])` + try/except，移除原有的 `line.strip()` 和 `startswith` 检查。
3. **修改 `_verify_multi_turn_logs` 方法 **（`test_bench_serving_functionality.py`）：类似地改为 `line.find("{")` + try/except，并移除直接 `json.loads(line)` 的调用。
4. 所有变更均为纯测试文件修改，共计 +21/-10 行，风险极低。

关键文件：
- `test/registered/utils/test_scheduler_status_logger.py`（模块 调度器日志；类别 test；类型 test-coverage；符号 _find_log_events）: 修改了 `_find_log_events` 函数，这是调度器状态日志解析的核心逻辑。
- `test/registered/utils/test_request_logger.py`（模块 请求日志；类别 test；类型 test-coverage）: 修改了两个辅助方法 `_verify_logs` 和 `_verify_openai_logs` 中的 JSON 解析逻辑。
- `test/registered/bench_fn/test_bench_serving_functionality.py`（模块 基准测试；类别 test；类型 test-coverage）: 修改了 `_verify_multi_turn_logs` 中的日志解析逻辑。

关键符号：_find_log_events

## 关键源码片段

### `test/registered/utils/test_scheduler_status_logger.py`

修改了 `_find_log_events` 函数，这是调度器状态日志解析的核心逻辑。

```python
# test/registered/utils/test_scheduler_status_logger.py

def _find_log_events(log_dir: str, event_name: str):
    for f in Path(log_dir).glob("*.log"):
        for line in f.read_text().splitlines():
            # 不再依赖行首为 '{'，而是找到第一个 '{' 的位置
            idx = line.find("{")
            if idx == -1:
                continue  # 没有 JSON 对象就跳过
            try:
                data = json.loads(line[idx:])
            except json.JSONDecodeError:
                # 即使找到 '{' 也可能解析失败，安全跳过
                continue
            if data.get("event") == event_name:
                yield data

```

### `test/registered/utils/test_request_logger.py`

修改了两个辅助方法 `_verify_logs` 和 `_verify_openai_logs` 中的 JSON 解析逻辑。

```python
# test/registered/utils/test_request_logger.py
# 在 _verify_logs 和 _verify_openai_logs 中解析 JSON 行的模式变为：
for line in content.splitlines():
    idx = line.find("{")
    if idx == -1:
        continue
    try:
        data = json.loads(line[idx:])
    except json.JSONDecodeError:
        continue
    # 后续逻辑不变

```

### `test/registered/bench_fn/test_bench_serving_functionality.py`

修改了 `_verify_multi_turn_logs` 中的日志解析逻辑。

```python
# test/registered/bench_fn/test_bench_serving_functionality.py
# 在 _verify_multi_turn_logs 中解析 JSON 行的模式变为：
for line in content.splitlines():
    idx = line.find("{")
    if idx == -1:
        continue
    try:
        obj = json.loads(line[idx:])
    except json.JSONDecodeError:
        continue
    # 后续逻辑不变

```

# 评论区精华

无 review 讨论（仅一个批准）。

- 暂无高价值评论线程

# 风险与影响

- 风险：低风险：仅修改测试辅助函数中的日志解析逻辑，不涉及生产代码。所有修改均增加 try/except 保护，即使解析失败也不会影响整体测试流程。改动范围局限在三个测试文件内。
- 影响：直接影响三个夜间测试的稳定性，使其在日志带时间戳前缀的新格式下仍能正确解析 JSON 事件。对其他测试和系统无影响。
- 风险标记：测试兼容性修复

# 关联脉络

- PR #24521 Add timestamp prefix to log lines: 本 PR 正是为了修复 #24521 引入的日志前缀导致的测试失败。