blob: 56fc9a6a7892146c1d6cad22c70a53723b1340d6 [file] [log] [blame] [view]
mpearson2b5f7e02016-10-03 21:27:031# Histogram Guidelines
2
3This document gives the best practices on how to use histograms in code and how
Caitlin Fischerb5e94352020-10-27 17:34:504to document the histograms for the dashboards. There are three general types
Darwin Huang1ca97ac2020-06-17 18:09:205of histograms: [enumerated histograms](#Enum-Histograms),
6[count histograms](#Count-Histograms) (for arbitrary numbers), and
7[sparse histograms](#When-To-Use-Sparse-Histograms) (for anything when the
8precision is important over a wide range and/or the range is not possible to
9specify a priori).
mpearson2b5f7e02016-10-03 21:27:0310
11[TOC]
12
Ilya Shermanb9641892020-11-06 00:53:5513## Defining Useful Metrics
Mark Pearsonb1d608d2018-06-05 19:59:4414
Ilya Shermanb9641892020-11-06 00:53:5515### Directly Measure What You Want
16
17Measure exactly what you want, whether that's the time used for a function call,
18the number of bytes transmitted to fetch a page, the number of items in a list,
19etc. Do not assume you can calculate what you want from other histograms, as
20most ways of doing this are incorrect.
21
22For example, suppose you want to measure the runtime of a function that just
23calls two subfunctions, each of which is instrumented with histogram logging.
24You might assume that you can simply sum the histograms for those two functions
25to get the total time, but that results in misleading data. If we knew which
26emissions came from which calls, we could pair them up and derive the total time
27for the function. However, histograms are pre-aggregated client-side, which
28means that there's no way to recover which emissions should be paired up. If you
29simply add up the two histograms to get a total duration histogram, you're
30implicitly assuming the two histograms' values are independent, which may not be
31the case.
32
33Directly measure what you care about; don't try to derive it from other data.
34
35### Provide Context
36
37When defining a new metric, think ahead about how you will analyze the
38data. Often, this will require providing context in order for the data to be
39interpretable.
40
41For enumerated histograms in particular, that often means including a bucket
42that can be used as a baseline for understanding the data recorded to other
43buckets: see the [enumerated histogram section](#Enum-Histograms).
44
45### Naming Your Histogram
46
47Histograms are taxonomized into categories, using dot (`.`) characters as
48separators. Thus, histogram names should be in the form Category.Name or
49Category.Subcategory.Name, etc., where each category organizes related
50histograms.
51
52It should be quite rare to introduce new top-level categories into the existing
53taxonomy. If you're tempted to do so, please look through the existing
Robert Kaplowcbc6fd62021-03-19 15:11:4054categories to see whether any matches the metric(s) that you are adding. To
55create a new category, the CL must be reviewed by
56[email protected].
Mark Pearsonb1d608d2018-06-05 19:59:4457
Mark Pearson4c4bc972018-05-16 20:01:0658## Coding (Emitting to Histograms)
59
Daniel Cheng01cd75932020-02-06 16:43:4560Prefer the helper functions defined in
Mark Pearsoned73f1f2019-03-22 18:00:1261[histogram_functions.h](https://cs.chromium.org/chromium/src/base/metrics/histogram_functions.h).
Daniel Cheng01cd75932020-02-06 16:43:4562These functions take a lock and perform a map lookup, but the overhead is
63generally insignificant. However, when recording metrics on the critical path
64(e.g. called in a loop or logged multiple times per second), use the macros in
65[histogram_macros.h](https://cs.chromium.org/chromium/src/base/metrics/histogram_macros.h)
66instead. These macros cache a pointer to the histogram object for efficiency,
67though this comes at the cost of increased binary size: 130 bytes/macro usage
68sounds small but quickly adds up.
Mark Pearson159c38972018-06-05 19:44:0869
Mark Pearson4c4bc972018-05-16 20:01:0670### Don't Use the Same Histogram Logging Call in Multiple Places
71
72These logging macros and functions have long names and sometimes include extra
Caitlin Fischerb5e94352020-10-27 17:34:5073parameters (defining the number of buckets for example). Use a helper function
74if possible. This leads to shorter, more readable code that's also more
75resilient to problems that could be introduced when making changes. (One could,
Mark Pearson4c4bc972018-05-16 20:01:0676for example, erroneously change the bucketing of the histogram in one call but
77not the other.)
78
79### Use Fixed Strings When Using Histogram Macros
80
81When using histogram macros (calls such as `UMA_HISTOGRAM_ENUMERATION`), you're
Victor-Gabriel Savub2afb6f42019-10-23 07:28:2382not allowed to construct your string dynamically so that it can vary at a
Caitlin Fischerb5e94352020-10-27 17:34:5083callsite. At a given callsite (preferably you have only one), the string
84should be the same every time the macro is called. If you need to use dynamic
Mark Pearson74c53212019-03-08 00:34:0885names, use the functions in histogram_functions.h instead of the macros.
Mark Pearson4c4bc972018-05-16 20:01:0686
Arthur Milchiora70d5e62022-08-02 05:10:5687### Don't Use Same Inline String in Multiple Places
Mark Pearson4c4bc972018-05-16 20:01:0688
89If you must use the histogram name in multiple places, use a compile-time
90constant of appropriate scope that can be referenced everywhere. Using inline
91strings in multiple places can lead to errors if you ever need to revise the
Jana Grill81103722023-01-19 16:31:5392name and you update one location and forget another.
Mark Pearson4c4bc972018-05-16 20:01:0693
94### Efficiency
95
Mark Pearsoned73f1f2019-03-22 18:00:1296Generally, don't be concerned about the processing cost of emitting to a
97histogram (unless you're using [sparse
98histograms](#When-To-Use-Sparse-Histograms)). The normal histogram code is
99highly optimized. If you are recording to a histogram in particularly
100performance-sensitive or "hot" code, make sure you're using the histogram
101macros; see [reasons above](#Coding-Emitting-to-Histograms).
Mark Pearson4c4bc972018-05-16 20:01:06102
103## Picking Your Histogram Type
mpearson2b5f7e02016-10-03 21:27:03104
mpearson2b5f7e02016-10-03 21:27:03105### Enum Histograms
106
107Enumerated histogram are most appropriate when you have a list of connected /
Caitlin Fischerb5e94352020-10-27 17:34:50108related states that should be analyzed jointly. For example, the set of actions
109that can be done on the New Tab Page (use the omnibox, click a most visited
110tile, click a bookmark, etc.) would make a good enumerated histogram.
mpearson2b5f7e02016-10-03 21:27:03111If the total count of your histogram (i.e. the sum across all buckets) is
Caitlin Fischerb5e94352020-10-27 17:34:50112something meaningful—as it is in this example—that is generally a good sign.
mpearson2b5f7e02016-10-03 21:27:03113However, the total count does not have to be meaningful for an enum histogram
114to still be the right choice.
115
Caitlin Fischerb5e94352020-10-27 17:34:50116Enumerated histograms are also appropriate for counting events. Use a simple
Ilya Shermanb9641892020-11-06 00:53:55117boolean histogram. It's usually best if you have a comparison point in the same
Caitlin Fischerb5e94352020-10-27 17:34:50118histogram. For example, if you want to count pages opened from the history page,
119it might be a useful comparison to have the same histogram record the number of
120times the history page was opened.
Mark Pearsona768d0222019-03-20 02:16:00121
Ilya Shermanb9641892020-11-06 00:53:55122In rarer cases, it's okay if you only log to one bucket (say, `true`). However,
123think about whether this will provide enough [context](#Provide-Context). For
124example, suppose we want to understand how often users interact with a button.
Jared Saul73a9daaf2021-05-04 15:33:02125Just knowing that users clicked this particular button 1 million times in a day
Ilya Shermanb9641892020-11-06 00:53:55126is not very informative on its own: The size of Chrome's user base is constantly
127changing, only a subset of users have consented to metrics reporting, different
128platforms have different sampling rates for metrics reporting, and so on. The
129data would be much easier to make sense of if it included a baseline: how often
130is the button shown?
131
Caitlin Fischerb5e94352020-10-27 17:34:50132If only a few buckets are emitted to, consider using a [sparse
Mark Pearson4d0b4632017-10-04 21:58:48133histogram](#When-To-Use-Sparse-Histograms).
134
Daniel Cheng914170d22019-05-08 09:46:32135#### Requirements
136
137Enums logged in histograms must:
138
139- be prefixed with the comment:
140 ```c++
141 // These values are persisted to logs. Entries should not be renumbered and
142 // numeric values should never be reused.
143 ```
144- be numbered starting from `0`. Note this bullet point does *not* apply for
145 enums logged with sparse histograms.
Caitlin Fischerb5e94352020-10-27 17:34:50146- have enumerators with explicit values (`= 0`, `= 1`, `= 2`) to make it clear
Daniel Cheng914170d22019-05-08 09:46:32147 that the actual values are important. This also makes it easy to match the
148 values between the C++/Java definition and [histograms.xml](./histograms.xml).
149- not renumber or reuse enumerator values. When adding a new enumerator, append
150 the new enumerator to the end. When removing an unused enumerator, comment it
151 out, making it clear the value was previously used.
152
153If your enum histogram has a catch-all / miscellaneous bucket, put that bucket
Caitlin Fischerb5e94352020-10-27 17:34:50154first (`= 0`). This makes the bucket easy to find on the dashboard if additional
155buckets are added later.
Daniel Cheng914170d22019-05-08 09:46:32156
157#### Usage
158
Ilya Shermanb6bd3c72020-04-15 23:08:15159*In C++*, define an `enum class` with a `kMaxValue` enumerator:
Daniel Cheng914170d22019-05-08 09:46:32160
Steven Holteecf841d2018-08-10 00:53:34161```c++
Hong Xu4b0bc44f2023-08-01 20:30:42162// These values are persisted to logs. Entries should not be renumbered and
163// numeric values should never be reused.
James Lee53e80dc2024-04-19 11:31:06164//
165// LINT.IfChange(NewTabPageAction)
Daniel Chengcda1df5b2018-03-30 21:30:16166enum class NewTabPageAction {
167 kUseOmnibox = 0,
168 kClickTitle = 1,
Daniel Cheng914170d22019-05-08 09:46:32169 // kUseSearchbox = 2, // no longer used, combined into omnibox
170 kOpenBookmark = 3,
Daniel Chengcda1df5b2018-03-30 21:30:16171 kMaxValue = kOpenBookmark,
172};
James Lee53e80dc2024-04-19 11:31:06173// LINT.ThenChange(//path/to/enums.xml:NewTabPageActionEnum)
Daniel Chengcda1df5b2018-03-30 21:30:16174```
Daniel Chengcda1df5b2018-03-30 21:30:16175
James Lee53e80dc2024-04-19 11:31:06176The `LINT.IfChange / LINT.ThenChange` comments point between the code and XML
177definitions of the enum, to encourage them to be kept in sync. See
178[guide](https://www.chromium.org/chromium-os/developer-library/guides/development/keep-files-in-sync/)
179and [more details](http://go/gerrit-ifthisthenthat).
180
Daniel Cheng914170d22019-05-08 09:46:32181`kMaxValue` is a special enumerator that must share the highest enumerator
182value, typically done by aliasing it with the enumerator with the highest
183value: clang automatically checks that `kMaxValue` is correctly set for `enum
184class`.
185
Takashi Toyoshima0b520762024-05-08 23:17:33186*In Mojo*, define an `enum` without a `kMaxValue` enumerator as `kMaxValue` is
187autogenerated for Mojo C++ bindings:
188
189```c++
190// These values are persisted to logs. Entries should not be renumbered and
191// numeric values should never be reused.
192//
193// LINT.IfChange(PreloadType)
194enum PrerenderType {
195 kPrefetch = 0,
196 // kPrerender = 1, // deprecated, revamped as kPrerender2
197 kNoStatePrefetch = 2,
198 kPrerender2 = 3,
199};
200// LINT.ThenChange(//path/to/enums.xml:PreloadType)
201```
202
203*In C++*, the histogram helpers use the `kMaxValue` convention, and the enum may
204be logged with:
Daniel Cheng914170d22019-05-08 09:46:32205
206```c++
Daniel Chengcda1df5b2018-03-30 21:30:16207UMA_HISTOGRAM_ENUMERATION("NewTabPageAction", action);
208```
Daniel Chengcda1df5b2018-03-30 21:30:16209
Daniel Cheng914170d22019-05-08 09:46:32210or:
211
Steven Holteecf841d2018-08-10 00:53:34212```c++
Daniel Cheng914170d22019-05-08 09:46:32213UmaHistogramEnumeration("NewTabPageAction", action);
Daniel Chengcda1df5b2018-03-30 21:30:16214```
Steven Holteecf841d2018-08-10 00:53:34215
Hong Xu365a4f72022-02-25 04:26:02216where `action` is an enumerator of the enumeration type `NewTabPageAction`.
217
Nate Fischer1f6efe52020-06-17 19:18:21218Logging histograms from Java should look similar:
219
220```java
221// These values are persisted to logs. Entries should not be renumbered and
222// numeric values should never be reused.
223@IntDef({NewTabPageAction.USE_OMNIBOX, NewTabPageAction.CLICK_TITLE,
224 NewTabPageAction.OPEN_BOOKMARK})
225private @interface NewTabPageAction {
226 int USE_OMNIBOX = 0;
227 int CLICK_TITLE = 1;
228 // int USE_SEARCHBOX = 2; // no longer used, combined into omnibox
229 int OPEN_BOOKMARK = 3;
230 int COUNT = 4;
231}
232
233// Using a helper function is optional, but avoids some boilerplate.
234private static void logNewTabPageAction(@NewTabPageAction int action) {
235 RecordHistogram.recordEnumeratedHistogram(
236 "NewTabPageAction", action, NewTabPageAction.COUNT);
237}
238```
239
Hong Xu77292842022-05-18 06:43:59240Finally, regardless of the programming language you are using, add the
James Lee53e80dc2024-04-19 11:31:06241definition of the enumerator to [enums.xml](./enums.xml), and add linter checks
242to keep the C++/Java and XML values in sync:
243
244```xml
245<!-- LINT.IfChange(NewTabPageActionEnum) -->
246<enum name="NewTabPageActionEnum">
247 ...
248</enum>
249<!-- LINT.ThenChange(//path/to/cpp_definition.h:NewTabPageAction) -->
250```
Hong Xu77292842022-05-18 06:43:59251
Daniel Cheng914170d22019-05-08 09:46:32252#### Legacy Enums
253
254**Note: this method of defining histogram enums is deprecated. Do not use this
Ilya Shermanb6bd3c72020-04-15 23:08:15255for new enums *in C++*.**
Daniel Cheng914170d22019-05-08 09:46:32256
Chris Blumebdca7ca2020-06-08 15:48:35257Many legacy enums define a `kCount` sentinel, relying on the compiler to
Daniel Cheng914170d22019-05-08 09:46:32258automatically update it when new entries are added:
259
Steven Holteecf841d2018-08-10 00:53:34260```c++
Daniel Chengcda1df5b2018-03-30 21:30:16261enum class NewTabPageAction {
262 kUseOmnibox = 0,
263 kClickTitle = 1,
Daniel Cheng914170d22019-05-08 09:46:32264 // kUseSearchbox = 2, // no longer used, combined into omnibox
265 kOpenBookmark = 3,
Daniel Chengcda1df5b2018-03-30 21:30:16266 kCount,
267};
Daniel Cheng914170d22019-05-08 09:46:32268```
Steven Holteecf841d2018-08-10 00:53:34269
Daniel Cheng914170d22019-05-08 09:46:32270These enums must be recorded using the legacy helpers:
271
272```c++
Daniel Chengcda1df5b2018-03-30 21:30:16273UMA_HISTOGRAM_ENUMERATION("NewTabPageAction", action, NewTabPageAction::kCount);
274```
275
Daniel Cheng914170d22019-05-08 09:46:32276or:
277
278```c++
279UmaHistogramEnumeration("NewTabPageAction", action, NewTabPageAction::kCount);
280```
mpearsonb36013be2017-02-10 20:10:54281
Matt Giucaf3e0e2532017-10-03 23:07:52282### Flag Histograms
283
284When adding a new flag in
285[about_flags.cc](../../../chrome/browser/about_flags.cc), you need to add a
Caitlin Fischerb5e94352020-10-27 17:34:50286corresponding entry to [enums.xml](./enums.xml). This is automatically verified
287by the `AboutFlagsHistogramTest` unit test.
Matt Giucaf3e0e2532017-10-03 23:07:52288
289To add a new entry:
290
manukh26fe9852022-10-04 23:38:142911. After adding flags
292 to [about_flags.cc](../../../chrome/browser/about_flags.cc),
293 run `generate_flag_enums.py --feature <your awesome feature>` or
294 simply `generate_flag_enums.py` (slower).
295
296You can alternatively follow these steps:
297
Matt Giucaf3e0e2532017-10-03 23:07:522981. Edit [enums.xml](./enums.xml), adding the feature to the `LoginCustomFlags`
Brett Wilsonf4d58772017-10-30 21:37:57299 enum section, with any unique value (just make one up, although whatever it
Caitlin Fischerb5e94352020-10-27 17:34:50300 is needs to appear in sorted order; `pretty_print.py` can do this for you).
Matt Giucaf3e0e2532017-10-03 23:07:523012. Build `unit_tests`, then run `unit_tests
Eric Lawrenced4d7d5c2023-05-09 20:48:25302 --gtest_filter=AboutFlagsHistogramTest.*` to compute the correct value.
Matt Giucaf3e0e2532017-10-03 23:07:523033. Update the entry in [enums.xml](./enums.xml) with the correct value, and move
Caitlin Fischerb5e94352020-10-27 17:34:50304 it so the list is sorted by value (`pretty_print.py` can do this for you).
Matt Giucaf3e0e2532017-10-03 23:07:523054. Re-run the test to ensure the value and ordering are correct.
306
307You can also use `tools/metrics/histograms/validate_format.py` to check the
308ordering (but not that the value is correct).
309
310Don't remove entries when removing a flag; they are still used to decode data
311from previous Chrome versions.
312
mpearson2b5f7e02016-10-03 21:27:03313### Count Histograms
314
315[histogram_macros.h](https://cs.chromium.org/chromium/src/base/metrics/histogram_macros.h)
Caitlin Fischerfc138c82021-11-04 21:31:19316provides macros for some common count types, such as memory or elapsed time, in
Caitlin Fischerb5e94352020-10-27 17:34:50317addition to general count macros. These have reasonable default values; you
318seldom need to choose the number of buckets or histogram min. However, you still
319need to choose the histogram max (use the advice below).
mpearson2b5f7e02016-10-03 21:27:03320
Caitlin Fischerfc138c82021-11-04 21:31:19321If none of the default macros work well for you, please thoughtfully choose a
322min, max, and bucket count for your histogram using the advice below.
mpearson2b5f7e02016-10-03 21:27:03323
rkaplow6dfcb892016-10-04 14:04:27324#### Count Histograms: Choosing Min and Max
mpearson2b5f7e02016-10-03 21:27:03325
Caitlin Fischerfc138c82021-11-04 21:31:19326For the max, choose a value such that very few histogram samples exceed the max.
327If a sample is greater than or equal to the max value, it is put in an
328"overflow" bucket. If this bucket is too large, it can be difficult to compute
329statistics. One rule of thumb is that at most 1% of samples should be in the
Robert Kaplowcbc6fd62021-03-19 15:11:40330overflow bucket (and ideally, less). This allows analysis of the 99th
331percentile. Err on the side of too large a range versus too short a range.
Caitlin Fischerfc138c82021-11-04 21:31:19332Remember that if you choose poorly, you'll have to wait for another release
333cycle to fix it.
mpearson2b5f7e02016-10-03 21:27:03334
Caitlin Fischerfc138c82021-11-04 21:31:19335For the min, use 1 if you care about all possible values (zero and above). All
336histograms have an underflow bucket for emitted zeros, so a min of 1 is
337appropriate. Otherwise, choose the min appropriate for your particular
338situation.
mpearson2b5f7e02016-10-03 21:27:03339
rkaplow6dfcb892016-10-04 14:04:27340#### Count Histograms: Choosing Number of Buckets
mpearson2b5f7e02016-10-03 21:27:03341
Caitlin Fischerb5e94352020-10-27 17:34:50342Choose the smallest number of buckets that give you the granularity you need. By
Hong Xu3a229d832022-05-12 04:37:30343default, count histogram bucket sizes increase exponentially with respect to the
344value (i.e., exponential binning), so you can get fine granularity when the
345values are small yet still reasonable resolution when the values are larger. The
346macros default to 50 buckets (or 100 buckets for histograms with wide ranges),
347which is appropriate for most purposes. Because histograms pre-allocate all the
348buckets, the number of buckets selected directly dictates how much memory is
349used. Do not exceed 100 buckets without good reason (and consider whether
350[sparse histograms](#When-To-Use-Sparse-Histograms) might work better for you in
351that case—they do not pre-allocate their buckets).
rkaplow8a62ef62016-10-06 14:42:34352
Mark Pearson6be2f35c2018-08-14 07:06:02353### Timing Histograms
354
Yoshisato Yanagisawa4782e2f2024-04-19 00:50:34355You can easily emit a time duration (time delta) using base::UmaHistogramTimes,
356base::UmaHistogramMediumTimes, base::UmaHistogramLongTimes, and their friends.
357For the critical path, UMA_HISTOGRAM_TIMES, UMA_HISTOGRAM_MEDIUM_TIMES,
358UMA_HISTOGRAM_LONG_TIMES macros, and their friends, as well as helpers like
359SCOPED_UMA_HISTOGRAM_TIMER are also available. Many timing
Mark Pearson6be2f35c2018-08-14 07:06:02360histograms are used for performance monitoring; if this is the case for you,
361please read [this document about how to structure timing histograms to make
362them more useful and
Paul Jensen5107d9c2018-10-22 22:24:06363actionable](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/speed/diagnostic_metrics.md).
Mark Pearson6be2f35c2018-08-14 07:06:02364
Mark Pearson49928ec2018-06-05 20:15:49365### Percentage or Ratio Histograms
366
Caitlin Fischerb5e94352020-10-27 17:34:50367You can easily emit a percentage histogram using the UMA_HISTOGRAM_PERCENTAGE
368macro provided in
Mark Pearson49928ec2018-06-05 20:15:49369[histogram_macros.h](https://cs.chromium.org/chromium/src/base/metrics/histogram_macros.h).
Caitlin Fischerb5e94352020-10-27 17:34:50370You can also easily emit any ratio as a linear histogram (for equally sized
371buckets).
Mark Pearson49928ec2018-06-05 20:15:49372
Caitlin Fischerb5e94352020-10-27 17:34:50373For such histograms, you want each value recorded to cover approximately the
374same span of time. This typically means emitting values periodically at a set
375time interval, such as every 5 minutes. We do not recommend recording a ratio at
376the end of a video playback, as video lengths vary greatly.
Mark Pearson49928ec2018-06-05 20:15:49377
Mark Pearson9be8bffa2020-03-03 19:08:02378It is okay to emit at the end of an animation sequence when what's being
Caitlin Fischerb5e94352020-10-27 17:34:50379animated is fixed / known. In this case, each value represents roughly the same
380span of time.
Mark Pearson9be8bffa2020-03-03 19:08:02381
Caitlin Fischerb5e94352020-10-27 17:34:50382Why? You typically cannot make decisions based on histograms whose values are
383recorded in response to an event that varies in length because such metrics can
384conflate heavy usage with light usage. It's easier to reason about metrics that
385avoid this source of bias.
Mark Pearson49928ec2018-06-05 20:15:49386
Caitlin Fischerb5e94352020-10-27 17:34:50387Many developers have been bitten by this. For example, it was previously common
388to emit an actions-per-minute ratio whenever Chrome was backgrounded. Precisely,
389these metrics computed the number of uses of a particular action during a Chrome
390session, divided by length of time Chrome had been open. Sometimes, the recorded
391rate was based on a short interaction with Chrome–a few seconds or a minute.
392Other times, the recorded rate was based on a long interaction, tens of minutes
393or hours. These two situations are indistinguishable in the UMA logs–the
394recorded values can be identical.
Mark Pearson49928ec2018-06-05 20:15:49395
Caitlin Fischerb5e94352020-10-27 17:34:50396The inability to distinguish these two qualitatively different settings make
397such histograms effectively uninterpretable and not actionable. Emitting at a
398regular interval avoids the issue. Each value represents the same amount of time
399(e.g., one minute of video playback).
Mark Pearson49928ec2018-06-05 20:15:49400
rkaplow8a62ef62016-10-06 14:42:34401### Local Histograms
402
Gayane Petrosyana6ee443c2018-05-17 21:39:54403Histograms can be added via [Local macros](https://codesearch.chromium.org/chromium/src/base/metrics/histogram_macros_local.h).
Caitlin Fischerb5e94352020-10-27 17:34:50404These still record locally, but are not uploaded to UMA and are therefore not
405available for analysis. This can be useful for metrics only needed for local
406debugging. We don't recommend using local histograms outside of that scenario.
rkaplow8a62ef62016-10-06 14:42:34407
408### Multidimensional Histograms
409
Caitlin Fischerb5e94352020-10-27 17:34:50410It is common to be interested in logging multidimensional data–where multiple
rkaplow8a62ef62016-10-06 14:42:34411pieces of information need to be logged together. For example, a developer may
412be interested in the counts of features X and Y based on whether a user is in
413state A or B. In this case, they want to know the count of X under state A,
414as well as the other three permutations.
415
416There is no general purpose solution for this type of analysis. We suggest
417using the workaround of using an enum of length MxN, where you log each unique
418pair {state, feature} as a separate entry in the same enum. If this causes a
Gayane Petrosyana6ee443c2018-05-17 21:39:54419large explosion in data (i.e. >100 enum entries), a [sparse histogram](#When-To-Use-Sparse-Histograms)
Caitlin Fischerb5e94352020-10-27 17:34:50420may be appropriate. If you are unsure of the best way to proceed, please contact
421someone from the OWNERS file.
Gayane Petrosyana6ee443c2018-05-17 21:39:54422
423## Histogram Expiry
424
Caitlin Fischerb5e94352020-10-27 17:34:50425Histogram expiry is specified by the `expires_after` attribute in histogram
Mark Pearson37c3c9a2023-06-29 17:17:30426descriptions in histograms.xml. It is a required attribute. The attribute can
427be specified as date in **YYYY-MM-DD** format or as Chrome milestone in
428**M**\*(e.g. M105) format. In the latter case, the actual expiry date is about
42912 weeks after that branch is cut, or basically when it is replaced on the
430"stable" channel by the following release.
Brian Whitefa0a3fa2019-05-13 16:58:11431
Mark Pearsonce4371c2021-03-15 23:57:42432After a histogram expires, it ceases to be displayed on the dashboard.
433Follow [these directions](#extending) to extend it.
Brian Whitefa0a3fa2019-05-13 16:58:11434
Caitlin Fischerb5e94352020-10-27 17:34:50435Once a histogram has expired, the code that records it becomes dead code and
Gabriel Gauthier-Shalom0c0f1d862022-02-09 15:47:33436should be removed from the codebase. You should also [clean up](#obsolete) the
Alexei Svitkined4cbf402022-11-14 20:55:25437corresponding entry in histograms.xml. In _rare_ cases, a histogram may be
438expired intentionally while keeping the code around; such cases must be
Alexei Svitkine6fbe8ac2022-11-14 21:17:40439[annotated appropriately](#Intentionally-expired-histograms) in histograms.xml.
Gayane Petrosyana6ee443c2018-05-17 21:39:54440
Brian White8614f812019-02-07 21:07:01441In **rare** cases, the expiry can be set to "never". This is used to denote
Robert Kaplowcbc6fd62021-03-19 15:11:40442metrics of critical importance that are, typically, used for other reports. For
443example, all metrics of the
444"[heartbeat](https://uma.googleplex.com/p/chrome/variations)" are set to never
445expire. All metrics that never expire must have an XML comment describing why so
446that it can be audited in the future. Setting an expiry to "never" must be
447reviewed by [email protected].
Brian White8614f812019-02-07 21:07:01448
449```
450<!-- expires-never: "heartbeat" metric (internal: go/uma-heartbeats) -->
451```
452
Mark Pearson37c3c9a2023-06-29 17:17:30453It is never appropriate to set the expiry to "never" on a new histogram. Most
454new histograms don't turn out to have the properties the implementer wants,
455whether due to bugs in the implementation or simply an evolving understanding
456of what should be measured.
Gayane Petrosyana6ee443c2018-05-17 21:39:54457
Yoshisato Yanagisawa19d35ca2024-04-09 03:50:18458#### Guidelines on expiry
Gayane Petrosyana6ee443c2018-05-17 21:39:54459
Ilya Sherman67418ea2019-11-27 01:28:23460Here are some guidelines for common scenarios:
Gayane Petrosyana6ee443c2018-05-17 21:39:54461
Yoshisato Yanagisawa19d35ca2024-04-09 03:50:18462* If the listed owner moved to a different project, find a new owner.
Ilya Sherman67418ea2019-11-27 01:28:23463* If neither the owner nor the team uses the histogram, remove it.
464* If the histogram is not in use now, but might be useful in the far future,
465 remove it.
466* If the histogram is not in use now, but might be useful in the near
Brian Whitedb68067b2021-10-13 18:27:28467 future, pick ~3 months (also ~3 milestones) ahead.
Yoshisato Yanagisawa19d35ca2024-04-09 03:50:18468* Otherwise, pick an expiry that is reasonable for how long the metric should
469 be used, up to a year.
Ilya Sherman67418ea2019-11-27 01:28:23470
Brian Whitedb68067b2021-10-13 18:27:28471We also have a tool that automatically extends expiry dates. The most frequently
472accessed histograms, currently 99%, have their expirations automatically
473extended every Tuesday to 6 months from the date of the run. Googlers can view
474the [design
475doc](https://docs.google.com/document/d/1IEAeBF9UnYQMDfyh2gdvE7WlUKsfIXIZUw7qNoU89A4)
476of the program that does this. The bottom line is: If the histogram is being
477checked, it should be extended without developer interaction.
Gayane Petrosyana6ee443c2018-05-17 21:39:54478
Yoshisato Yanagisawa19d35ca2024-04-09 03:50:18479#### How to choose expiry for new histograms
480
481In general, set an expiry that is reasonable for how long the metric should
482be used, up to a year.
483
484Some common cases:
485
486* When adding a histogram to evaluate a feature launch, set an expiry date
487 consistent with the expected feature launch date.
488* If you expect the histogram to be useful for an indefinite time, set an
489 expiry date up to 1 year out. This gives a chance to re-evaluate whether
490 the histogram indeed proved to be useful.
491* Otherwise, 3-6 months (3-6 milestones) is typically a good choice.
492
Mark Pearsonce4371c2021-03-15 23:57:42493#### How to extend an expired histogram {#extending}
494
495You can revive an expired histogram by setting the expiration date to a
496date in the future.
497
498There's some leeway here. A client may continue to send data for that
499histogram for some time after the official expiry date so simply bumping
500the 'expires_after' date at HEAD may be sufficient to resurrect it without
501any data discontinuity.
502
503If a histogram expired more than a month ago (for histograms with an
504expiration date) or more than one milestone ago (for histograms with
505expiration milestones; this means top-of-tree is two or more milestones away
506from expired milestone), then you may be outside the safety window. In this
507case, when extending the histogram add to the histogram description a
508message: "Warning: this histogram was expired from DATE to DATE; data may be
509missing." (For milestones, write something similar.)
510
511When reviving a histogram outside the safety window, realize the change to
512histograms.xml to revive it rolls out with the binary release. It takes
513some time to get to the stable channel.
514
515It you need to revive it faster, the histogram can be re-enabled via adding to
516the [expired histogram allowlist](#Expired-histogram-allowlist).
517
Gayane Petrosyana6ee443c2018-05-17 21:39:54518### Expired histogram notifier
519
Caitlin Fischerb5e94352020-10-27 17:34:50520The expired histogram notifier notifies histogram owners before their histograms
521expire by creating crbugs, which are assigned to owners. This allows owners to
522extend the lifetime of their histograms, if needed, or deprecate them. The
523notifier regularly checks all histograms across the histograms.xml files and
524identifies expired or soon-to-be expired histograms. It then creates or updates
525crbugs accordingly.
Gayane Petrosyana6ee443c2018-05-17 21:39:54526
Caitlin Fischer9f4841052020-11-04 21:02:44527### Expired histogram allowlist
Gayane Petrosyana6ee443c2018-05-17 21:39:54528
Caitlin Fischerb5e94352020-10-27 17:34:50529If a histogram expires but turns out to be useful, you can add the histogram's
Alexei Svitkined4cbf402022-11-14 20:55:25530name to the allowlist to re-enable logging for it, until the updated expiration
531date reaches the Stable channel. When doing so, update the histogram's summary
532to document the period during which the histogram's data is incomplete. To add a
533histogram to the allowlist, see the internal documentation:
Caitlin Fischerb5e94352020-10-27 17:34:50534[Histogram Expiry](https://goto.google.com/histogram-expiry-gdoc).
mpearson2b5f7e02016-10-03 21:27:03535
Alexei Svitkine6fbe8ac2022-11-14 21:17:40536### Intentionally expired histograms
Alexei Svitkined4cbf402022-11-14 20:55:25537
538In **rare** cases, a histogram may be expired intentionally while keeping the
539code around. For example, this can be useful for diagnostic metrics that are
540occasionally needed to investigate specific bugs, but do not need to be reported
541otherwise.
542
543To avoid such histograms to be flagged for code clean up, they must be annotated
544in the histograms.xml with the `expired_intentionally` tag as follows:
545
546```xml
547<histogram name="Tab.Open" enum="TabType" expires_after="M100">
548 <expired_intentionally>Kept as a diagnostic metric.</expired_intentionally>
549 <owner>[email protected]</owner>
550 <summary>Histogram summary.</summary>
551</histogram>
552```
553
mpearson72a5c91392017-05-09 22:49:44554## Testing
mpearson2b5f7e02016-10-03 21:27:03555
Caitlin Fischerb5e94352020-10-27 17:34:50556Test your histograms using `chrome://histograms`. Make sure they're being
rkaplow6dfcb892016-10-04 14:04:27557emitted to when you expect and not emitted to at other times. Also check that
Caitlin Fischerb5e94352020-10-27 17:34:50558the values emitted to are correct. Finally, for count histograms, make sure
rkaplow6dfcb892016-10-04 14:04:27559that buckets capture enough precision for your needs over the range.
mpearson2b5f7e02016-10-03 21:27:03560
Ivan Sandrk8ffc5832018-07-09 12:34:58561Pro tip: You can filter the set of histograms shown on `chrome://histograms` by
Luc Nguyenb1324cb2022-12-17 16:23:41562appending to the URL. For example, `chrome://histograms/UserActions` shows
563only histograms whose names contain "UserActions", such as
564"UMA.UserActionsCount".
Ivan Sandrk8ffc5832018-07-09 12:34:58565
mpearson72a5c91392017-05-09 22:49:44566In addition to testing interactively, you can have unit tests examine the
Caitlin Fischerb5e94352020-10-27 17:34:50567values emitted to histograms. See [histogram_tester.h](https://cs.chromium.org/chromium/src/base/test/metrics/histogram_tester.h)
mpearson72a5c91392017-05-09 22:49:44568for details.
mpearson2b5f7e02016-10-03 21:27:03569
Luc Nguyenb1324cb2022-12-17 16:23:41570See also `chrome://metrics-internals` ([docs](https://chromium.googlesource.com/chromium/src/+/master/components/metrics/debug/README.md))
571for more thorough manual testing if needed.
572
Robert Kaplow82027632023-02-13 16:31:52573By default, histograms in unit or browser tests will not be actually uploaded.
574In general, you can rely on the UMA infrastructure to upload the metrics correctly.
575
Alan Screen291bc9a2023-06-27 21:16:49576### Don't Use Histograms to Prove Main Logic Correctness
577
578Do not rely upon using histograms in tests as a way to prove correctness of
579your main program logic. If a unit or browser test uses a histogram count as a
580way to validate logic then that test coverage would be lost if the histogram is
581deleted after it has expired. That situation would prevent cleanup of the
582histogram. Construct your tests using other means to validate your general
583logic, and only use
584[`HistogramTester`](https://cs.chromium.org/chromium/src/base/test/metrics/histogram_tester.h)
585to verify that the histogram values are being generated as you would expect.
586
Dana Friedac15ff82024-04-02 21:19:34587### Verify Enum and Variant Values
588
589If you have <enum> or <variant> entries that need to be updated to match code,
590you can use
591[HistogramEnumReader](https://cs.chromium.org/chromium/src/base/test/metrics/histogram_enum_reader.h)
592or
593[HistogramVariantsReader](https://cs.chromium.org/chromium/src/base/test/metrics/histogram_enum_reader.h)
594to read and verify the expected values in a unit test. This prevents a mismatch
595between code and histogram data from slipping through CQ.
596
597For an example, see
598[BrowserUserEducationServiceTest.CheckFeaturePromoHistograms](https://cs.chromium.org/chromium/src/chrome/browser/ui/views/user_education/browser_user_education_service_unittest.cc).
599
Mark Pearson4c4bc972018-05-16 20:01:06600## Interpreting the Resulting Data
601
602The top of [go/uma-guide](http://go/uma-guide) has good advice on how to go
Caitlin Fischerb5e94352020-10-27 17:34:50603about analyzing and interpreting the results of UMA data uploaded by users. If
Mark Pearson4c4bc972018-05-16 20:01:06604you're reading this page, you've probably just finished adding a histogram to
605the Chromium source code and you're waiting for users to update their version of
Caitlin Fischerb5e94352020-10-27 17:34:50606Chrome to a version that includes your code. In this case, the best advice is
607to remind you that users who update frequently / quickly are biased. Best take
Mark Pearson4c4bc972018-05-16 20:01:06608the initial statistics with a grain of salt; they're probably *mostly* right but
609not entirely so.
610
mpearson72a5c91392017-05-09 22:49:44611## Revising Histograms
612
Robert Kaplowcbc6fd62021-03-19 15:11:40613When changing the semantics of a histogram (when it's emitted, what the buckets
614represent, the bucket range or number of buckets, etc.), create a new histogram
615with a new name. Otherwise analysis that mixes the data pre- and post- change
616may be misleading. If the histogram name is still the best name choice, the
617recommendation is to simply append a '2' to the name. See [Cleaning Up Histogram
Austin Sullivan1040ce22022-04-13 15:51:29618Entries](#obsolete) for details on how to handle the XML changes.
mpearson2b5f7e02016-10-03 21:27:03619
mpearson72a5c91392017-05-09 22:49:44620## Deleting Histograms
mpearson2b5f7e02016-10-03 21:27:03621
Caitlin Fischerb5e94352020-10-27 17:34:50622Please delete code that emits to histograms that are no longer needed.
623Histograms take up memory. Cleaning up histograms that you no longer care
624about is good! But see the note below on
Gabriel Gauthier-Shalom0c0f1d862022-02-09 15:47:33625[Cleaning Up Histogram Entries](#obsolete).
mpearson2b5f7e02016-10-03 21:27:03626
627## Documenting Histograms
628
Darren Shenda91dc752023-03-01 05:28:30629Document histograms in an appropriate [metadata/foo/histograms.xml](https://source.chromium.org/search?q=f:metadata%2F.*%2Fhistograms.xml&ss=chromium%2Fchromium%2Fsrc)
630file.
631
632There is also a [google-internal version of the file](https://goto.google.com/chrome-histograms-internal)
633for two cases:
634
635* The histogram is confidential (an accurate description about how to interpret
636 the histogram would reveal information about Google's plans). In this case,
637 you must only document the histogram in the internal version.
638* The corresponding code that emits the histogram is internal (added only to
639 Chrome code, not to Chromium code). In this case, you may document the
640 histogram in either the internal or external version.
Mark Pearson159c38972018-06-05 19:44:08641
mpearson2b5f7e02016-10-03 21:27:03642### Add Histogram and Documentation in the Same Changelist
643
vapier52b9aba2016-12-14 06:09:25644If possible, please add the [histograms.xml](./histograms.xml) description in
Caitlin Fischerb5e94352020-10-27 17:34:50645the same changelist in which you add the histogram-emitting code. This has
646several benefits. One, it sometimes happens that the
vapier52b9aba2016-12-14 06:09:25647[histograms.xml](./histograms.xml) reviewer has questions or concerns about the
648histogram description that reveal problems with interpretation of the data and
Caitlin Fischerb5e94352020-10-27 17:34:50649call for a different recording strategy. Two, it allows the histogram reviewer
vapier52b9aba2016-12-14 06:09:25650to easily review the emission code to see if it comports with these best
Caitlin Fischerb5e94352020-10-27 17:34:50651practices and to look for other errors.
mpearson2b5f7e02016-10-03 21:27:03652
653### Understandable to Everyone
654
655Histogram descriptions should be roughly understandable to someone not familiar
Caitlin Fischerb5e94352020-10-27 17:34:50656with your feature. Please add a sentence or two of background if necessary.
mpearson2b5f7e02016-10-03 21:27:03657
Robert Kaplowcbc6fd62021-03-19 15:11:40658Note any caveats associated with your histogram in the summary. For example, if
659the set of supported platforms is surprising, such as if a desktop feature is
660not available on Mac, the summary should explain where it is recorded. It is
661also common to have caveats along the lines of "this histogram is only recorded
662if X" (e.g., upon a successful connection to a service, a feature is enabled by
663the user).
664
mpearson2b5f7e02016-10-03 21:27:03665
666### State When It Is Recorded
667
668Histogram descriptions should clearly state when the histogram is emitted
669(profile open? network request received? etc.).
670
Mark Pearsond8fc9fd22021-03-12 20:18:58671Some histograms record error conditions. These should be clear about whether
672all errors are recorded or only the first. If only the first, the histogram
673description should have text like:
674```
675In the case of multiple errors, only the first reason encountered is recorded. Refer
676to Class::FunctionImplementingLogic() for details.
677```
678
Ilya Sherman470c95a2020-09-21 23:05:43679### Provide Clear Units or Enum Labels
680
681For enumerated histograms, including boolean and sparse histograms, provide an
682`enum=` attribute mapping enum values to semantically contentful labels. Define
683the `<enum>` in enums.xml if none of the existing enums are a good fit. Use
684labels whenever they would be clearer than raw numeric values.
685
686For non-enumerated histograms, include a `units=` attribute. Be specific:
687e.g. distinguish "MB" vs. "MiB", refine generic labels like "counts" to more
688precise labels like "pages", etc.
689
jsbellda3a66c2017-02-09 21:40:32690### Owners
rkaplow8a62ef62016-10-06 14:42:34691
Caitlin Fischer254a12f72019-07-31 20:57:03692Histograms need owners, who are the experts on the metric and the points of
693contact for any questions or maintenance tasks, such as extending a histogram's
694expiry or deprecating the metric.
rkaplow8a62ef62016-10-06 14:42:34695
Caitlin Fischer254a12f72019-07-31 20:57:03696Histograms must have a primary owner and may have secondary owners. A primary
Mario Bianucci9947bbd2020-10-28 17:41:47697owner is a Googler with an @google.com or @chromium.org email address, e.g.
Caitlin Fischerb5e94352020-10-27 17:34:50698<owner>[email protected]</owner>, who is ultimately responsible for maintaining
699the metric. Secondary owners may be other individuals, team mailing lists, e.g.
700<owner>[email protected]</owner>, or paths to OWNERS files, e.g.
701<owner>src/directory/OWNERS</owner>.
Mark Pearson74c53212019-03-08 00:34:08702
Caitlin Fischer254a12f72019-07-31 20:57:03703It's a best practice to list multiple owners, so that there's no single point
704of failure for histogram-related questions and maintenance tasks. If you are
705using a metric heavily and understand it intimately, feel free to add yourself
Caitlin Fischerb5e94352020-10-27 17:34:50706as an owner.
Mark Pearson74c53212019-03-08 00:34:08707
Caitlin Fischer254a12f72019-07-31 20:57:03708Notably, owners are asked to determine whether histograms have outlived their
Caitlin Fischerb5e94352020-10-27 17:34:50709usefulness. When a histogram is nearing expiry, a robot files a reminder bug in
710Monorail. It's important that somebody familiar with the histogram notices and
711triages such bugs!
rkaplow8a62ef62016-10-06 14:42:34712
Ilya Shermanf64bca252020-11-10 23:16:24713Tip: When removing someone from the owner list for a histogram, it's a nice
714courtesy to ask them for approval.
715
Caitlin Fischerfeafb4392020-10-05 21:10:07716### Components
717
Ariel Zhang62ee3f42024-02-26 23:25:29718Histograms may be associated with a component, which can help make sure that
Caitlin Fischerfeafb4392020-10-05 21:10:07719histogram expiry bugs don't fall through the cracks.
720
Ariel Zhang62ee3f42024-02-26 23:25:29721A histogram is associated with the `buganizer_public` component listed in the
722DIR_METADATA file adjacent to the histograms.xml file if present.
723
724There are two other ways in which components may be associated with a
725histogram. The first way is to add a tag containing the component ID to a
726histogram or histogram suffix, e.g. <component>1456399</component>. The second
727way is to specify an OWNERS file as a secondary owner for a histogram. If the
728OWNERS file has an adjacent DIR_METADATA file that contains a
729`buganizer_public` component, then that component is associated with the
730histogram. If there isn't a parallel DIR_METADATA file with such a component,
731but an ancestor directory has one, then the ancestor directory's component is
732used.
733
734If more than one component is associated with a histogram, <component> tag is
735favored over adjacent DIR_METADATA file and over OWNERS file.
736
737**Note:** For non-Chromium Issue Tracker (ChromeOS Public Tracker or internal)
738components, make sure [email protected] has access to create and
739update issues.
740
Caitlin Fischerfeafb4392020-10-05 21:10:07741
Sun Yueru39385712023-02-09 20:11:08742### Improvement Direction
743For some histograms, an increase or a decrease in the reported values can be
744associated with either an improvement or a deterioration. For example, if you
745are tracking page load speed, then seeing your metrics tracking page load time
746in milliseconds getting gradually larger values, perhaps as the result of a
747Finch study, may signify worse performance; on the contrary, seeing a reduction
748in the page load speed may indicate an improvement. You can provide this
749information on the movement direction by adding a tag
750 `<improvement direction="LOWER_IS_BETTER"/>` within your `<histogram>`. The
751opposite is `<improvement direction="HIGHER_IS_BETTER"/>`.
752
753For other histograms where there may not be a movement direction that's clearly
754better, you can set `<improvement direction="NEITHER_IS_BETTER"/>`.
755
756This `<improvement>` tag is optional. You can also add/delete this tag or make a
757correction to its `direction` attribute any time.
758
Gabriel Gauthier-Shalom0c0f1d862022-02-09 15:47:33759### Cleaning Up Histogram Entries {#obsolete}
mpearson2b5f7e02016-10-03 21:27:03760
Alexei Svitkine7bfb6702023-11-28 18:18:24761When the code to log a histogram is deleted, its corresponding histograms.xml
762entry should also be removed. Past histogram data will still be available for
763viewing on Google's internal UMA dashboard.
Pavol Marko17ed24e2023-09-11 09:43:15764
Alexei Svitkine7bfb6702023-11-28 18:18:24765The CL to remove one or more histograms can also specify an obsoletion message
766through special syntax in the CL description. This also applies to variants of a
Gabriel Gauthier-Shalom0c0f1d862022-02-09 15:47:33767[patterned histogram](#Patterned-Histograms) and to suffix entries for a
768suffixed histogram.
Mark Pearson2a311c52019-03-19 21:47:01769
Ariel Zhanged17ef22023-05-18 16:42:48770The changelist that obsoletes a histogram entry should be reviewed by all
771current owners.
Mark Pearson2a311c52019-03-19 21:47:01772
Ariel Zhanged17ef22023-05-18 16:42:48773#### Remove the Entry
Mark Pearson2a311c52019-03-19 21:47:01774
Ariel Zhanged17ef22023-05-18 16:42:48775Delete the entry in the histograms.xml file.
Gabriel Gauthier-Shalom0c0f1d862022-02-09 15:47:33776
Gabriel Gauthier-Shaloma7394aa2022-02-14 16:33:37777* In some cases there may be artifacts that remain, with some examples being:
Charlie Harrison1ad2f852023-11-06 18:22:23778 * Empty `<token>` blocks, or individual `<variant>`s.
Gabriel Gauthier-Shaloma7394aa2022-02-14 16:33:37779 * `<enum>` blocks from enums.xml that are no longer used.
Alexei Svitkine7bfb6702023-11-28 18:18:24780 * Suffix entries in `histogram_suffixes_list.xml`.
Gabriel Gauthier-Shaloma7394aa2022-02-14 16:33:37781* Please remove these artifacts if you find them.
Sun Yueruf81cee32023-01-19 01:52:58782 * **Exception**: please update the label of `<int value=... label=... />` with
783 the `(Obsolete) ` prefix, e.g.
784 `<int value="1" label="(Obsolete) Navigation failed. Removed in 2023/01."/>`
785 rather than deleting them, if the surrounding `<enum>` block is not being
786 deleted.
Ariel Zhanged17ef22023-05-18 16:42:48787
788#### Add an Obsoletion Message
789
Will Harris0874e552023-08-25 16:09:44790An obsoletion message is displayed on the dashboard and provides developers
791context for why the histogram was removed and, if applicable, which histogram
792it was replaced by.
793
Alexei Svitkine7bfb6702023-11-28 18:18:24794**Note:** You can skip this step if the histogram is expired. This is because
795tooling automatically records the date and milestone of a histogram's
Ariel Zhangd111b722023-12-12 15:48:58796removal.
Ariel Zhang1cd268202023-07-14 19:30:56797
Will Harris0874e552023-08-25 16:09:44798You can provide a custom obsoletion message for a removed histogram via tags
799on the CL description:
Ariel Zhanged17ef22023-05-18 16:42:48800
801* Add the obsoletion message in the CL description in the format
Alexei Svitkine7bfb6702023-11-28 18:18:24802 `OBSOLETE_HISTOGRAM[histogram name]=message`, e.g.:
803 `OBSOLETE_HISTOGRAM[Tab.Count]=Replaced by Tab.Count2`
804* To add the same obsoletion message to all the histograms removed in the CL,
805 you can use `OBSOLETE_HISTOGRAMS=message`, e.g.:
806 `OBSOLETE_HISTOGRAMS=Patterned histogram Hist.{Token} is replaced by Hist.{Token}.2`
Ariel Zhang7b8cbf92023-06-21 22:24:14807* **Notes:**
Ariel Zhangd111b722023-12-12 15:48:58808 * **The full tag should be put on a single line, even if it is longer than the
809 maximum CL description width.**
Ariel Zhang1cd268202023-07-14 19:30:56810 * You can add multiple obsoletion message tags in one CL.
Alexei Svitkine7bfb6702023-11-28 18:18:24811 * `OBSOLETE_HISTOGRAMS` messages will be overwritten by histogram-specific
812 ones, if present.
813* You could also include information about why the histogram was removed. For
814 example, you might indicate how the histogram's summary did not accurately
815 describe the collected data.
816* If the histogram is being replaced, include the name of the replacement and
817 make sure that the new description is different from the original to reflect
818 the change between versions.
Ilya Sherman8f0034a2020-07-22 22:06:34819
Ilya Sherman9e22dea2020-10-05 22:32:36820### Patterned Histograms
Ilya Shermanf54104b2017-07-12 23:45:47821
822It is sometimes useful to record several closely related metrics, which measure
Ilya Sherman9e22dea2020-10-05 22:32:36823the same type of data, with some minor variations. You can declare the metadata
824for these concisely using patterned histograms. For example:
Ilya Shermanf54104b2017-07-12 23:45:47825
Ilya Sherman9e22dea2020-10-05 22:32:36826```xml
Jared Saul73a9daaf2021-05-04 15:33:02827<histogram name="Pokemon.{Character}.EfficacyAgainst{OpponentType}"
Robert Kaplowe1430ce2021-03-25 19:02:18828 units="multiplier" expires_after="M95">
Ilya Sherman9e22dea2020-10-05 22:32:36829 <owner>[email protected]</owner>
830 <owner>[email protected]</owner>
831 <summary>
832 The efficacy multiplier for {Character} against an opponent of
833 {OpponentType} type.
834 </summary>
835 <token key="Character">
836 <variant name="Bulbasaur"/>
837 <variant name="Charizard"/>
838 <variant name="Mewtwo"/>
839 </token>
840 <token key="OpponentType">
841 <variant name="Dragon" summary="dragon"/>
842 <variant name="Flying" summary="flappity-flap"/>
843 <variant name="Psychic" summary="psychic"/>
844 <variant name="Water" summary="water"/>
845 </token>
846</histogram>
847```
848
849This example defines metadata for 12 (= 3 x 4) concrete histograms, such as
850
851```xml
Robert Kaplowe1430ce2021-03-25 19:02:18852<histogram name="Pokemon.Charizard.EfficacyAgainstWater"
853 units="multiplier" expires_after="M95">
Ilya Sherman9e22dea2020-10-05 22:32:36854 <owner>[email protected]</owner>
855 <owner>[email protected]</owner>
856 <summary>
857 The efficacy multiplier for Charizard against an opponent of water type.
858 </summary>
859</histogram>
860```
861
James Lee53e80dc2024-04-19 11:31:06862Each token `<variant>` defines what text should be substituted for it,
863both in the histogram name and in the summary text. The name part gets
864substituted into the histogram name; the summary part gets substituted in
Mark Pearson268ea6b2021-09-28 00:44:45865the summary field (the histogram description). As shorthand, a
866`<variant>` that omits the `summary` attribute substitutes the value of
867the `name` attribute in the histogram's `<summary>` text as well.
Ilya Sherman9e22dea2020-10-05 22:32:36868
869*** promo
870Tip: You can declare an optional token by listing an empty name: `<variant
871name="" summary="aggregated across all breakdowns"/>`. This can be useful when
872recording a "parent" histogram that aggregates across a set of breakdowns.
873***
874
875You can use the `<variants>` tag to define a set of `<variant>`s out-of-line.
876This is useful for token substitutions that are shared among multiple families
Ariel Zhang6adadaf2023-06-07 14:55:15877of histograms within the same file. See
Ilya Sherman9e22dea2020-10-05 22:32:36878[histograms.xml](https://source.chromium.org/search?q=file:histograms.xml%20%3Cvariants)
879for examples.
880
Joe Masonb468cc42022-06-21 18:02:16881*** promo
882Warning: The `name` attribute of the `<variants>` tag is globally scoped, so
Ariel Zhang6adadaf2023-06-07 14:55:15883use detailed names to avoid collisions. The `<variants>` defined should only
884be used within the file.
Joe Masonb468cc42022-06-21 18:02:16885***
886
Caitlin Fischerb5e94352020-10-27 17:34:50887By default, a `<variant>` inherits the owners declared for the patterned
Ilya Sherman9e22dea2020-10-05 22:32:36888histogram. Each variant can optionally override the inherited list with custom
889owners:
890```xml
891<variant name="SubteamBreakdown" ...>
892 <owner>[email protected]</owner>
893 <owner>[email protected]</owner>
894</variant>
895```
Mark Pearsona0109122018-05-30 18:23:05896
Ilya Sherman9e22dea2020-10-05 22:32:36897*** promo
Oksana Zhuravlova5242ad22021-02-19 00:14:20898Tip: You can run `print_expanded_histograms.py --pattern=` to show all generated
Weilun Shibac61d9d32020-11-12 02:40:26899histograms by patterned histograms or histogram suffixes including their
900summaries and owners. For example, this can be run (from the repo root) as:
901```
Oksana Zhuravlova5242ad22021-02-19 00:14:20902./tools/metrics/histograms/print_expanded_histograms.py --pattern=^UMA.A.B
Weilun Shibac61d9d32020-11-12 02:40:26903```
904***
905
906*** promo
Ilya Sherman9e22dea2020-10-05 22:32:36907Tip: You can run `print_histogram_names.py --diff` to enumerate all the
908histogram names that are generated by a particular CL. For example, this can be
909run (from the repo root) as:
Charlie Harrison90407d92020-05-19 23:57:32910```
Egor Pasko5ec32b72021-07-23 14:34:22911./tools/metrics/histograms/print_histogram_names.py --diff origin/main
Charlie Harrison90407d92020-05-19 23:57:32912```
Ilya Sherman9e22dea2020-10-05 22:32:36913***
914
915For documentation about the `<histogram_suffixes>` syntax, which is deprecated,
916see
917https://chromium.googlesource.com/chromium/src/+/refs/tags/87.0.4270.1/tools/metrics/histograms/one-pager.md#histogram-suffixes-deprecated-in-favor-of-pattern-histograms
Charlie Harrison90407d92020-05-19 23:57:32918
mpearson2b5f7e02016-10-03 21:27:03919## When To Use Sparse Histograms
920
Caitlin Fischerb5e94352020-10-27 17:34:50921Sparse histograms are well-suited for recording counts of exact sample values
922that are sparsely distributed over a large range. They can be used with enums
Ilya Sherman1eee82c4c2017-12-08 01:22:19923as well as regular integer values. It is often valuable to provide labels in
924[enums.xml](./enums.xml).
mpearson2b5f7e02016-10-03 21:27:03925
926The implementation uses a lock and a map, whereas other histogram types use a
927vector and no lock. It is thus more costly to add values to, and each value
928stored has more overhead, compared to the other histogram types. However it
929may be more efficient in memory if the total number of sample values is small
930compared to the range of their values.
931
Mark Pearsoned73f1f2019-03-22 18:00:12932Please talk with the metrics team if there are more than a thousand possible
933different values that you could emit.
934
rkaplow6dfcb892016-10-04 14:04:27935For more information, see [sparse_histograms.h](https://cs.chromium.org/chromium/src/base/metrics/sparse_histogram.h).
Caitlin Fischerb466a042019-07-31 21:41:46936
Ilya Shermanf64bca252020-11-10 23:16:24937
Robert Kaplow6be6fbf2021-04-19 17:30:38938# Becoming a Metrics Reviewer
Caitlin Fischerb466a042019-07-31 21:41:46939
Jared Saul73a9daaf2021-05-04 15:33:02940Any Chromium committer who is also a Google employee is eligible to become a
941metrics reviewer. Please follow the instructions at [go/reviewing-metrics](https://goto.google.com/reviewing-metrics).
942This consists of reviewing our training materials and passing an informational
943quiz. Since metrics have a direct impact on internal systems and have privacy
Robert Kaplow6be6fbf2021-04-19 17:30:38944considerations, we're currently only adding Googlers into this program.
945
946
947# Reviewing Metrics CLs
Ilya Shermanf64bca252020-11-10 23:16:24948
Robert Kaplowcbc6fd62021-03-19 15:11:40949If you are a metric OWNER, you have the serious responsibility of ensuring
950Chrome's data collection is following best practices. If there's any concern
951about an incoming metrics changelist, please escalate by assigning to
952[email protected].
953
Ilya Shermanf64bca252020-11-10 23:16:24954When reviewing metrics CLs, look at the following, listed in approximate order
955of importance:
956
Robert Kaplow6be6fbf2021-04-19 17:30:38957## Privacy
Ilya Shermanf64bca252020-11-10 23:16:24958
959Does anything tickle your privacy senses? (Googlers, see
960[go/uma-privacy](https://goto.google.com/uma-privacy) for guidelines.)
961
962**Please escalate if there's any doubt!**
963
Robert Kaplow6be6fbf2021-04-19 17:30:38964## Clarity
Ilya Shermanf64bca252020-11-10 23:16:24965
966Is the metadata clear enough for [all Chromies](#Understandable-to-Everyone) to
967understand what the metric is recording? Consider the histogram name,
968description, units, enum labels, etc.
969
970It's really common for developers to forget to list [when the metric is
971recorded](#State-When-It-Is-Recorded). This is particularly important context,
972so please remind developers to clearly document it.
973
974Note: Clarity is a bit less important for very niche metrics used only by a
975couple of engineers. However, it's hard to assess the metric design and
976correctness if the metadata is especially unclear.
977
Robert Kaplow6be6fbf2021-04-19 17:30:38978## Metric design
Ilya Shermanf64bca252020-11-10 23:16:24979
980* Does the metric definition make sense?
981* Will the resulting data be interpretable at analysis time?
982
Robert Kaplow6be6fbf2021-04-19 17:30:38983## Correctness
Ilya Shermanf64bca252020-11-10 23:16:24984
985Is the histogram being recorded correctly?
986
987* Does the bucket layout look reasonable?
988
989 * The metrics APIs like base::UmaHistogram* have some sharp edges,
990 especially for the APIs that require specifying the number of
991 buckets. Check for off-by-one errors and unused buckets.
992
993 * Is the bucket layout efficient? Typically, push back if there are >50
994 buckets -- this can be ok in some cases, but make sure that the CL author
995 has consciously considered the tradeoffs here and is making a reasonable
996 choice.
997
998 * For timing metrics, do the min and max bounds make sense for the duration
999 that is being measured?
1000
1001* The base::UmaHistogram* functions are
1002 [generally preferred](#Coding-Emitting-to-Histograms) over the
1003 UMA_HISTOGRAM_* macros. If using the macros, remember that names must be
1004 runtime constants!
1005
1006Also, related to [clarity](#Clarity): Does the client logic correctly implement
1007the metric described in the XML metadata? Some common errors to watch out for:
1008
1009* The metric is only emitted within an if-stmt (e.g., only if some data is
1010 available) and this restriction isn't mentioned in the metadata description.
1011
1012* The metric description states that it's recorded when X happens, but it's
1013 actually recorded when X is scheduled to occur, or only emitted when X
1014 succeeds (but omitted on failure), etc.
1015
1016When the metadata and the client logic do not match, the appropriate solution
1017might be to update the metadata, or it might be to update the client
1018logic. Guide this decision by considering what data will be more easily
1019interpretable and what data will have hidden surprises/gotchas.
1020
Robert Kaplow6be6fbf2021-04-19 17:30:381021## Sustainability
Ilya Shermanf64bca252020-11-10 23:16:241022
Robert Kaplowcd6e0422021-04-07 21:58:531023* Is the CL adding a reasonable number of metrics/buckets?
Ilya Shermanf64bca252020-11-10 23:16:241024 * When reviewing a CL that is trying to add many metrics at once, guide the CL
1025 author toward an appropriate solution for their needs. For example,
1026 multidimensional metrics can be recorded via UKM, and we are currently
Robert Kaplowcd6e0422021-04-07 21:58:531027 building support for structured metrics in UMA.
1028 * There's no hard rule, but anything above 20 separate histograms should be
1029 escalated by being assigned to [email protected].
1030 * Similarly, any histogram with more than 100 possible buckets should be
1031 escalated by being assigned to [email protected].
Ilya Shermanf64bca252020-11-10 23:16:241032
1033* Are expiry dates being set
1034 [appropriately](#How-to-choose-expiry-for-histograms)?
1035
Robert Kaplow6be6fbf2021-04-19 17:30:381036## Everything Else!
Ilya Shermanf64bca252020-11-10 23:16:241037
1038This document describes many other nuances that are important for defining and
1039recording useful metrics. Check CLs for these other types of issues as well.
1040
1041And, as you would with a language style guide, periodically re-review the doc to
1042stay up to date on the details.
1043
Ilya Shermanf64bca252020-11-10 23:16:241044
Robert Kaplow6be6fbf2021-04-19 17:30:381045# Team Documentation
Ilya Shermanf64bca252020-11-10 23:16:241046
Caitlin Fischerb466a042019-07-31 21:41:461047
1048## Processing histograms.xml
1049
1050When working with histograms.xml, verify whether you require fully expanded
1051OWNERS files. Many scripts in this directory process histograms.xml, and
1052sometimes OWNERS file paths are expanded and other times they are not. OWNERS
1053paths are expanded when scripts make use of merge_xml's function MergeFiles;
1054otherwise, they are not.