# 可视化与排障 · 把黑匣子画成图

> 抓到的 event log 是二进制，得靠 event_log_visualizer 画成一堆时间序列图才看得懂。这一章讲这个官方工具怎么用（--plot/--list_plots）、能画出哪些关键曲线，以及一套「看图定位子系统」的实战排障方法论。

- 作者：David（道雾轩）
- 专栏：音视频与 WebRTC 详解（https://daiw.org/manual/webrtc.md）
- 最后更新：2026-07-14
- 原文：https://daiw.org/manual/webrtc/event-log-visualizer
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 可视化与排障 · 把黑匣子画成图

[上一章](https://daiw.org/manual/webrtc/rtc-event-log)抓到了 [event log](https://daiw.org/manual/webrtc/rtc-event-log)，但它是[二进制的](https://daiw.org/manual/webrtc/rtc-event-log)，肉眼看不懂。要让它有用，得画成**时间序列图**——WebRTC 官方提供了 `event_log_visualizer`。这一章讲怎么用它，以及一套“看图定位问题”的排障套路。

## event_log_visualizer：日志变图

官方工具的用法很直接（[g3doc](https://daiw.org/manual/webrtc/reading-the-source)）：

```bash
# 把日志变成一组图(工具输出一段 python,交给 matplotlib 画)
out/Default/event_log_visualizer /path/to/log_file | python

# 只画你关心的图
out/Default/event_log_visualizer \
  --plot=incoming_packet_sizes,incoming_stream_bitrate \
  /path/to/log_file | python

# 列出所有能画的图
out/Default/event_log_visualizer --list_plots /path/to/log_file
```

<Callout type="info">
  **`event_log_visualizer` 把[黑匣子日志](https://daiw.org/manual/webrtc/rtc-event-log)转成**几十种时间序列图**——码率、丢包、RTT、[带宽估计](https://daiw.org/manual/webrtc/delay-based-bwe)、[jitter buffer 延迟](https://daiw.org/manual/webrtc/video-jitter-buffer)……用 `--plot=` 选要哪些、`--list_plots` 看全部，还能**同步各图的 x 轴**（一起缩放，方便对齐时间）。** 它输出一段 Python 脚本、由 [matplotlib](https://daiw.org/manual/webrtc/reading-the-source) 渲染。关键在于：**把“[通话期间发生的一切](https://daiw.org/manual/webrtc/rtc-event-log)”沿同一条时间轴摊开**，于是“第 30 秒卡顿”这种[时序问题](https://daiw.org/manual/webrtc/observability-overview)不再抽象——你能看到那一刻[哪条曲线出了异常](https://daiw.org/manual/webrtc/event-log-visualizer)。
</Callout>

## 几张最有用的图

`--list_plots` 列出的图很多，排障时最常盯这几张：

| 图 | 看什么 | 异常意味着 |
| --- | --- | --- |
| **incoming/outgoing stream bitrate** | 收 / 发码率随时间 | 码率骤降 → [带宽被砍 / 编码器降质](https://daiw.org/manual/webrtc/video-adaptation) |
| **bandwidth estimate** | [GoogCC 估的带宽](https://daiw.org/manual/webrtc/rate-control)曲线 | 估计塌陷或上不去 → [拥塞控制问题](https://daiw.org/manual/webrtc/congestion-control-overview) |
| **network delay / RTT** | 往返时延 | 飙升 → [网络拥塞 / bufferbloat](https://daiw.org/manual/webrtc/congestion-window) |
| **packet loss** | 丢包率 | 尖峰 → [丢包触发 NACK/FEC](https://daiw.org/manual/webrtc/nack-rtx) |
| **jitter buffer delay** | [NetEq](https://daiw.org/manual/webrtc/neteq-overview)/[视频 jitter buffer](https://daiw.org/manual/webrtc/video-jitter-buffer) 缓冲深度 | 变大 → [网络抖动、缓冲被迫拉长](https://daiw.org/manual/webrtc/neteq-buffer-delay) |
| **pacer / ALR** | [pacing 队列、应用受限区](https://daiw.org/manual/webrtc/pacing) | 队列堆积 → [发送跟不上](https://daiw.org/manual/webrtc/pacing) |

## 一套看图定位的套路

有了这些曲线，排障就从“猜”变成“[顺着数据推](https://daiw.org/manual/webrtc/observability-overview)”。一个典型的“卡顿”排查：

```mermaid
flowchart TD
    START["现象:第 30 秒视频卡顿"] --> BR["看 outgoing bitrate:那一刻掉了吗?"]
    BR -->|"掉了"| BWE["看 bandwidth estimate:是估计先塌的吗?"]
    BR -->|"没掉"| JB["看 jitter buffer delay:缓冲飙升?"]
    BWE -->|"估计塌了"| CAUSE1["根因:拥塞控制降码率<br/>→ 查那时 RTT/丢包(第 5 部分)"]
    JB -->|"飙升"| CAUSE2["根因:网络抖动<br/>→ 收端在等包(第 6/7 部分)"]
    BWE -->|"估计没塌但码率掉"| CAUSE3["根因:编码器/CPU 受限<br/>→ 查 qualityLimitationReason(getStats)"]
```

<Callout type="info">
  **排障的核心思路：**沿时间轴对齐多条曲线，找“谁先动”**。卡顿是**果**，要找**因**——是[带宽估计先塌](https://daiw.org/manual/webrtc/delay-based-bwe)（拥塞控制判断网络变差）导致降码率？还是[网络真的抖了](https://daiw.org/manual/webrtc/neteq-buffer-delay)、[jitter buffer 被迫拉长](https://daiw.org/manual/webrtc/video-jitter-buffer)？还是[编码器 CPU 顶不住](https://daiw.org/manual/webrtc/video-adaptation)主动降质？** 这几种根因在图上**长相不同**：

  - 若 **bandwidth estimate 先塌、码率随后跟着降** → [拥塞控制](https://daiw.org/manual/webrtc/rate-control)判断网络变差，去查那一刻的 [RTT / 丢包](https://daiw.org/manual/webrtc/loss-based-bwe)是不是真涨了（网络问题）还是 GoogCC 误判（算法问题）。
  - 若 **码率没降、但 jitter buffer delay 飙升** → 发端没问题，是[网络抖动](https://daiw.org/manual/webrtc/neteq-buffer-delay)让收端[缓冲拉长](https://daiw.org/manual/webrtc/video-jitter-buffer)，表现为延迟增大。
  - 若 **码率降了、但带宽估计没塌** → 不是网络，多半是[编码器 / CPU 受限](https://daiw.org/manual/webrtc/video-adaptation)，配合 [`getStats` 的 `qualityLimitationReason`](https://daiw.org/manual/webrtc/stats-report) 印证。

  **这就是 event log 的威力**：它把[散落在十几个子系统里的状态](https://daiw.org/manual/webrtc/observability-overview)拉到同一时间轴，让你像看[心电图](https://daiw.org/manual/webrtc/rtc-event-log)一样“看波形诊断”。配合本教程[前几部分建立的子系统心智模型](https://daiw.org/manual/webrtc/call-recap)，你能从一条异常曲线直接跳到“[该去读哪块源码](https://daiw.org/manual/webrtc/reading-the-source)”。
</Callout>

## 两支柱配合的完整闭环

回到[第 11 部分开头的两支柱](https://daiw.org/manual/webrtc/observability-overview)，实战里它们这样配合：[线上用 `getStats` 持续监控](https://daiw.org/manual/webrtc/stats-report) → 发现某通电话[质量指标异常](https://daiw.org/manual/webrtc/stats-report) → 对可疑通话[抓 `RtcEventLog`](https://daiw.org/manual/webrtc/rtc-event-log) → [可视化看波形定位根因](https://daiw.org/manual/webrtc/event-log-visualizer) → [跳到对应子系统源码](https://daiw.org/manual/webrtc/reading-the-source)修。**监控发现问题、黑匣子定位问题**，这是 WebRTC 工程化排障的标准闭环。

## 小结与下一章

`event_log_visualizer` 把[二进制 event log](https://daiw.org/manual/webrtc/rtc-event-log) 转成**几十种时间序列图**（`--plot=` 选图、`--list_plots` 列全部、可[同步 x 轴](https://daiw.org/manual/webrtc/event-log-visualizer)），经 matplotlib 渲染。最有用的图：[收发码率、带宽估计、RTT、丢包、jitter buffer 延迟、pacer/ALR](https://daiw.org/manual/webrtc/event-log-visualizer)。排障套路是**沿时间轴对齐多曲线、找“谁先动”**：[带宽估计先塌→拥塞控制](https://daiw.org/manual/webrtc/rate-control)、[jitter 飙升→网络抖动](https://daiw.org/manual/webrtc/neteq-buffer-delay)、[码率降但估计没塌→编码器/CPU 受限](https://daiw.org/manual/webrtc/video-adaptation)。两支柱闭环：[getStats 监控发现](https://daiw.org/manual/webrtc/stats-report) → [event log 定位根因](https://daiw.org/manual/webrtc/rtc-event-log) → [跳源码修](https://daiw.org/manual/webrtc/reading-the-source)。

第 11 部分的两大支柱看完了。下一章收尾，并补上其他调试手段。👉 [第 11 部分回顾](https://daiw.org/manual/webrtc/observability-recap)。

## 参考资料

- [1] WebRTC 官方 `g3doc/rtc_event_log.md`（`event_log_visualizer` 用法、`--plot`/`--list_plots`）。
- [2] libwebrtc 源码.`rtc_event_log/rtc_event_log_parser.h`、`tools/event_log_visualizer/`。
- [3] 关联[延迟带宽估计](https://daiw.org/manual/webrtc/delay-based-bwe)、[jitter buffer](https://daiw.org/manual/webrtc/video-jitter-buffer)、[getStats](https://daiw.org/manual/webrtc/stats-report)。
