听说 Chromium 里有个直方图

AI 摘要:本文探讨 Chromium Histogram 设计理念和实现方式,了解可观测性(Observability)的重要性。

2025-04-03 pv 920 字 · 4 分钟

    Chromium 🤖 Chromium 🤖 Histogram 🤖 Observability

最近工作中经常使用 Chromium 里 Histogram 这个工具。

这是一个 Telemetry 机制,可用于统计、调试,甚至性能分析。

不可否认,Chromium 是一个广泛使用,且内部实现相当复杂的巨型工程项目。没有人能保证自己写的代码一定正确。

Bug 一定存在。

重要的不是假装它不存在,而是如何快速地识别、调试并解决(Identify, debug, and resolve)。

因此今天这篇文章,打算从 Histogram 的设计理念出发,探讨实现的方式,以及我们该如何理解可观测性(Observability)。

1. 设计理念

对于单用户问题,在不同平台上有着很多经典的工具。比如性能分析,Linux 有 Perf,Windows 有 Windows Performance Toolkit 等。

但对于群体问题,传统的工具便会失效。

怎么判断某个函数被调用的频次,某个关键操作的耗时分布如何,更常规的,DAU (Daily Active User,日活跃用户数)怎么统计。

Chromium Histogram 提供了一套跨平台、分布式的数据采集方案。

功能上的定位,有点类似前端领域的 Sentry🔗。

Histogram 的设计目标是:

  • 高性能采样(无需锁)
  • 支持多种数据类型(布尔、计数器、枚举、延迟等)
  • 自动分桶和分位分析
  • 精准的数据聚合和上传

2. 实现

Chromium Histogram 的关键部分有三个:

  • 埋点
  • 采样
  • 上传

2.1 埋点

首先,Chromium 提供了多种类型的 Histogram,用于记录不同的数据类型。

类型宏描述
BooleanUMA_HISTOGRAM_BOOLEAN记录 true/false 的分布
EnumerationUMA_HISTOGRAM_ENUMERATION记录枚举类型的取值情况
Custom CountsUMA_HISTOGRAM_CUSTOM_COUNTS自定义区间和 bucket,用于记录计数(比如网络包大小)
TimesUMA_HISTOGRAM_TIMES记录时间类型,支持微秒到秒
SparseUMA_HISTOGRAM_SPARSE_SLOWLY用于高稀疏度的整数数据统计

2.2 采样

Histogram 底层的数据存储,是一个多级桶(bucket)。

类似:

struct Histogram {
std::string name;
int min;
int max;
int bucket_count;
std::vector<int> counts;
};

不同的数据类型,分桶的策略也有所差异。这样可以降低存储开销,并提高采样分布的清晰度。

类型桶布局示例用途
LinearHistogram等距计数类事件
ExponentialHistogram对数时间延迟、网络 RTT
CustomHistogram手动指定特殊值域分布(如视频帧率)

Add() 的计数是原子的,线程安全且高效。

每个进程都有一个 HistogramBase 实例,并实现了延迟实例化(Lazy Initialization)。多进程埋点不冲突。

2.3 上传

Histogram 记录的数据不会实时上传。因为有一个采样缓存机制:

  1. 所有注册的 Histogram 都由 StatisticsRecorder(只在 Browser 进程) 统一管理

  2. 触发上传时,所有 Histogram 数据被序列化(HistogramSnapshotManager)

  3. 数据通过 UKM、UMA、或者 DevTools 的 chrome://histograms 页面输出

跨进程的 Histogram 数据共享则是借助 PersistentMemoryAllocator 。

具体工作流程如下:

+-----------------+ +--------------------------+
| Renderer 进程 | | Browser 主进程 |
|-----------------| |--------------------------|
| Histogram::Add | | |
| PersistentHistogram (写入共享内存) | |
| ↓ | | |
| PersistentMemoryAllocator | |
| | | |
+-----------------+ | |
| StatisticsRecorder |
| ↓ |
| ImportGlobalPersistentHistograms()|
| ↓ |
| 合并数据并上传 UMA |
+--------------------------+

3. 启发

对于开发者,使用 Histogram 打点是简单的。

正是由于它的简洁性和高性能,在尽可能减小对软件性能影响的同时,提高了开发者对于一个复杂系统内部运行过程的观测能力。

系统越透明,失控的可能性越小。

If you can not measure it, you can not improve it.

如果你不能衡量它,你就无法改进它。

4. 总结

我喜欢简单的东西。

无论是道理,还是 App。

简单本身便是一种强大。

好的道理,应该一两句话就能说清楚;好的 App,应该让不识字的儿童都能轻松上手。

当然,能化繁为简的人,往往有着对事物异于常人的洞察。

这是简单背后的不简单。

(完)

参考

  1. Histogram Guidelines🔗
  2. Application Performance Monitoring & Error Tracking Software | Sentry🔗
在 GitHub 上编辑本页面

最后更新于: 2026-07-13T05:59:15+08:00