blob: dfd252c08266225aa5d520c8a9e91c2f986d7811 [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.
Daniel Chengcda1df5b2018-03-30 21:30:16164enum class NewTabPageAction {
165 kUseOmnibox = 0,
166 kClickTitle = 1,
Daniel Cheng914170d22019-05-08 09:46:32167 // kUseSearchbox = 2, // no longer used, combined into omnibox
168 kOpenBookmark = 3,
Daniel Chengcda1df5b2018-03-30 21:30:16169 kMaxValue = kOpenBookmark,
170};
171```
Daniel Chengcda1df5b2018-03-30 21:30:16172
Daniel Cheng914170d22019-05-08 09:46:32173`kMaxValue` is a special enumerator that must share the highest enumerator
174value, typically done by aliasing it with the enumerator with the highest
175value: clang automatically checks that `kMaxValue` is correctly set for `enum
176class`.
177
178The histogram helpers use the `kMaxValue` convention, and the enum may be
179logged with:
180
181```c++
Daniel Chengcda1df5b2018-03-30 21:30:16182UMA_HISTOGRAM_ENUMERATION("NewTabPageAction", action);
183```
Daniel Chengcda1df5b2018-03-30 21:30:16184
Daniel Cheng914170d22019-05-08 09:46:32185or:
186
Steven Holteecf841d2018-08-10 00:53:34187```c++
Daniel Cheng914170d22019-05-08 09:46:32188UmaHistogramEnumeration("NewTabPageAction", action);
Daniel Chengcda1df5b2018-03-30 21:30:16189```
Steven Holteecf841d2018-08-10 00:53:34190
Hong Xu365a4f72022-02-25 04:26:02191where `action` is an enumerator of the enumeration type `NewTabPageAction`.
192
Nate Fischer1f6efe52020-06-17 19:18:21193Logging histograms from Java should look similar:
194
195```java
196// These values are persisted to logs. Entries should not be renumbered and
197// numeric values should never be reused.
198@IntDef({NewTabPageAction.USE_OMNIBOX, NewTabPageAction.CLICK_TITLE,
199 NewTabPageAction.OPEN_BOOKMARK})
200private @interface NewTabPageAction {
201 int USE_OMNIBOX = 0;
202 int CLICK_TITLE = 1;
203 // int USE_SEARCHBOX = 2; // no longer used, combined into omnibox
204 int OPEN_BOOKMARK = 3;
205 int COUNT = 4;
206}
207
208// Using a helper function is optional, but avoids some boilerplate.
209private static void logNewTabPageAction(@NewTabPageAction int action) {
210 RecordHistogram.recordEnumeratedHistogram(
211 "NewTabPageAction", action, NewTabPageAction.COUNT);
212}
213```
214
Hong Xu77292842022-05-18 06:43:59215Finally, regardless of the programming language you are using, add the
216definition of the enumerator to [enums.xml](./enums.xml).
217
Daniel Cheng914170d22019-05-08 09:46:32218#### Legacy Enums
219
220**Note: this method of defining histogram enums is deprecated. Do not use this
Ilya Shermanb6bd3c72020-04-15 23:08:15221for new enums *in C++*.**
Daniel Cheng914170d22019-05-08 09:46:32222
Chris Blumebdca7ca2020-06-08 15:48:35223Many legacy enums define a `kCount` sentinel, relying on the compiler to
Daniel Cheng914170d22019-05-08 09:46:32224automatically update it when new entries are added:
225
Steven Holteecf841d2018-08-10 00:53:34226```c++
Daniel Chengcda1df5b2018-03-30 21:30:16227enum class NewTabPageAction {
228 kUseOmnibox = 0,
229 kClickTitle = 1,
Daniel Cheng914170d22019-05-08 09:46:32230 // kUseSearchbox = 2, // no longer used, combined into omnibox
231 kOpenBookmark = 3,
Daniel Chengcda1df5b2018-03-30 21:30:16232 kCount,
233};
Daniel Cheng914170d22019-05-08 09:46:32234```
Steven Holteecf841d2018-08-10 00:53:34235
Daniel Cheng914170d22019-05-08 09:46:32236These enums must be recorded using the legacy helpers:
237
238```c++
Daniel Chengcda1df5b2018-03-30 21:30:16239UMA_HISTOGRAM_ENUMERATION("NewTabPageAction", action, NewTabPageAction::kCount);
240```
241
Daniel Cheng914170d22019-05-08 09:46:32242or:
243
244```c++
245UmaHistogramEnumeration("NewTabPageAction", action, NewTabPageAction::kCount);
246```
mpearsonb36013be2017-02-10 20:10:54247
Matt Giucaf3e0e2532017-10-03 23:07:52248### Flag Histograms
249
250When adding a new flag in
251[about_flags.cc](../../../chrome/browser/about_flags.cc), you need to add a
Caitlin Fischerb5e94352020-10-27 17:34:50252corresponding entry to [enums.xml](./enums.xml). This is automatically verified
253by the `AboutFlagsHistogramTest` unit test.
Matt Giucaf3e0e2532017-10-03 23:07:52254
255To add a new entry:
256
manukh26fe9852022-10-04 23:38:142571. After adding flags
258 to [about_flags.cc](../../../chrome/browser/about_flags.cc),
259 run `generate_flag_enums.py --feature <your awesome feature>` or
260 simply `generate_flag_enums.py` (slower).
261
262You can alternatively follow these steps:
263
Matt Giucaf3e0e2532017-10-03 23:07:522641. Edit [enums.xml](./enums.xml), adding the feature to the `LoginCustomFlags`
Brett Wilsonf4d58772017-10-30 21:37:57265 enum section, with any unique value (just make one up, although whatever it
Caitlin Fischerb5e94352020-10-27 17:34:50266 is needs to appear in sorted order; `pretty_print.py` can do this for you).
Matt Giucaf3e0e2532017-10-03 23:07:522672. Build `unit_tests`, then run `unit_tests
Eric Lawrenced4d7d5c2023-05-09 20:48:25268 --gtest_filter=AboutFlagsHistogramTest.*` to compute the correct value.
Matt Giucaf3e0e2532017-10-03 23:07:522693. Update the entry in [enums.xml](./enums.xml) with the correct value, and move
Caitlin Fischerb5e94352020-10-27 17:34:50270 it so the list is sorted by value (`pretty_print.py` can do this for you).
Matt Giucaf3e0e2532017-10-03 23:07:522714. Re-run the test to ensure the value and ordering are correct.
272
273You can also use `tools/metrics/histograms/validate_format.py` to check the
274ordering (but not that the value is correct).
275
276Don't remove entries when removing a flag; they are still used to decode data
277from previous Chrome versions.
278
mpearson2b5f7e02016-10-03 21:27:03279### Count Histograms
280
281[histogram_macros.h](https://cs.chromium.org/chromium/src/base/metrics/histogram_macros.h)
Caitlin Fischerfc138c82021-11-04 21:31:19282provides macros for some common count types, such as memory or elapsed time, in
Caitlin Fischerb5e94352020-10-27 17:34:50283addition to general count macros. These have reasonable default values; you
284seldom need to choose the number of buckets or histogram min. However, you still
285need to choose the histogram max (use the advice below).
mpearson2b5f7e02016-10-03 21:27:03286
Caitlin Fischerfc138c82021-11-04 21:31:19287If none of the default macros work well for you, please thoughtfully choose a
288min, max, and bucket count for your histogram using the advice below.
mpearson2b5f7e02016-10-03 21:27:03289
rkaplow6dfcb892016-10-04 14:04:27290#### Count Histograms: Choosing Min and Max
mpearson2b5f7e02016-10-03 21:27:03291
Caitlin Fischerfc138c82021-11-04 21:31:19292For the max, choose a value such that very few histogram samples exceed the max.
293If a sample is greater than or equal to the max value, it is put in an
294"overflow" bucket. If this bucket is too large, it can be difficult to compute
295statistics. One rule of thumb is that at most 1% of samples should be in the
Robert Kaplowcbc6fd62021-03-19 15:11:40296overflow bucket (and ideally, less). This allows analysis of the 99th
297percentile. Err on the side of too large a range versus too short a range.
Caitlin Fischerfc138c82021-11-04 21:31:19298Remember that if you choose poorly, you'll have to wait for another release
299cycle to fix it.
mpearson2b5f7e02016-10-03 21:27:03300
Caitlin Fischerfc138c82021-11-04 21:31:19301For the min, use 1 if you care about all possible values (zero and above). All
302histograms have an underflow bucket for emitted zeros, so a min of 1 is
303appropriate. Otherwise, choose the min appropriate for your particular
304situation.
mpearson2b5f7e02016-10-03 21:27:03305
rkaplow6dfcb892016-10-04 14:04:27306#### Count Histograms: Choosing Number of Buckets
mpearson2b5f7e02016-10-03 21:27:03307
Caitlin Fischerb5e94352020-10-27 17:34:50308Choose the smallest number of buckets that give you the granularity you need. By
Hong Xu3a229d832022-05-12 04:37:30309default, count histogram bucket sizes increase exponentially with respect to the
310value (i.e., exponential binning), so you can get fine granularity when the
311values are small yet still reasonable resolution when the values are larger. The
312macros default to 50 buckets (or 100 buckets for histograms with wide ranges),
313which is appropriate for most purposes. Because histograms pre-allocate all the
314buckets, the number of buckets selected directly dictates how much memory is
315used. Do not exceed 100 buckets without good reason (and consider whether
316[sparse histograms](#When-To-Use-Sparse-Histograms) might work better for you in
317that case—they do not pre-allocate their buckets).
rkaplow8a62ef62016-10-06 14:42:34318
Mark Pearson6be2f35c2018-08-14 07:06:02319### Timing Histograms
320
321You can easily emit a time duration (time delta) using UMA_HISTOGRAM_TIMES,
Caitlin Fischerb5e94352020-10-27 17:34:50322UMA_HISTOGRAM_MEDIUM_TIMES, UMA_HISTOGRAM_LONG_TIMES macros, and their
323friends, as well as helpers like SCOPED_UMA_HISTOGRAM_TIMER. Many timing
Mark Pearson6be2f35c2018-08-14 07:06:02324histograms are used for performance monitoring; if this is the case for you,
325please read [this document about how to structure timing histograms to make
326them more useful and
Paul Jensen5107d9c2018-10-22 22:24:06327actionable](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/speed/diagnostic_metrics.md).
Mark Pearson6be2f35c2018-08-14 07:06:02328
Mark Pearson49928ec2018-06-05 20:15:49329### Percentage or Ratio Histograms
330
Caitlin Fischerb5e94352020-10-27 17:34:50331You can easily emit a percentage histogram using the UMA_HISTOGRAM_PERCENTAGE
332macro provided in
Mark Pearson49928ec2018-06-05 20:15:49333[histogram_macros.h](https://cs.chromium.org/chromium/src/base/metrics/histogram_macros.h).
Caitlin Fischerb5e94352020-10-27 17:34:50334You can also easily emit any ratio as a linear histogram (for equally sized
335buckets).
Mark Pearson49928ec2018-06-05 20:15:49336
Caitlin Fischerb5e94352020-10-27 17:34:50337For such histograms, you want each value recorded to cover approximately the
338same span of time. This typically means emitting values periodically at a set
339time interval, such as every 5 minutes. We do not recommend recording a ratio at
340the end of a video playback, as video lengths vary greatly.
Mark Pearson49928ec2018-06-05 20:15:49341
Mark Pearson9be8bffa2020-03-03 19:08:02342It is okay to emit at the end of an animation sequence when what's being
Caitlin Fischerb5e94352020-10-27 17:34:50343animated is fixed / known. In this case, each value represents roughly the same
344span of time.
Mark Pearson9be8bffa2020-03-03 19:08:02345
Caitlin Fischerb5e94352020-10-27 17:34:50346Why? You typically cannot make decisions based on histograms whose values are
347recorded in response to an event that varies in length because such metrics can
348conflate heavy usage with light usage. It's easier to reason about metrics that
349avoid this source of bias.
Mark Pearson49928ec2018-06-05 20:15:49350
Caitlin Fischerb5e94352020-10-27 17:34:50351Many developers have been bitten by this. For example, it was previously common
352to emit an actions-per-minute ratio whenever Chrome was backgrounded. Precisely,
353these metrics computed the number of uses of a particular action during a Chrome
354session, divided by length of time Chrome had been open. Sometimes, the recorded
355rate was based on a short interaction with Chrome–a few seconds or a minute.
356Other times, the recorded rate was based on a long interaction, tens of minutes
357or hours. These two situations are indistinguishable in the UMA logs–the
358recorded values can be identical.
Mark Pearson49928ec2018-06-05 20:15:49359
Caitlin Fischerb5e94352020-10-27 17:34:50360The inability to distinguish these two qualitatively different settings make
361such histograms effectively uninterpretable and not actionable. Emitting at a
362regular interval avoids the issue. Each value represents the same amount of time
363(e.g., one minute of video playback).
Mark Pearson49928ec2018-06-05 20:15:49364
rkaplow8a62ef62016-10-06 14:42:34365### Local Histograms
366
Gayane Petrosyana6ee443c2018-05-17 21:39:54367Histograms can be added via [Local macros](https://codesearch.chromium.org/chromium/src/base/metrics/histogram_macros_local.h).
Caitlin Fischerb5e94352020-10-27 17:34:50368These still record locally, but are not uploaded to UMA and are therefore not
369available for analysis. This can be useful for metrics only needed for local
370debugging. We don't recommend using local histograms outside of that scenario.
rkaplow8a62ef62016-10-06 14:42:34371
372### Multidimensional Histograms
373
Caitlin Fischerb5e94352020-10-27 17:34:50374It is common to be interested in logging multidimensional data–where multiple
rkaplow8a62ef62016-10-06 14:42:34375pieces of information need to be logged together. For example, a developer may
376be interested in the counts of features X and Y based on whether a user is in
377state A or B. In this case, they want to know the count of X under state A,
378as well as the other three permutations.
379
380There is no general purpose solution for this type of analysis. We suggest
381using the workaround of using an enum of length MxN, where you log each unique
382pair {state, feature} as a separate entry in the same enum. If this causes a
Gayane Petrosyana6ee443c2018-05-17 21:39:54383large explosion in data (i.e. >100 enum entries), a [sparse histogram](#When-To-Use-Sparse-Histograms)
Caitlin Fischerb5e94352020-10-27 17:34:50384may be appropriate. If you are unsure of the best way to proceed, please contact
385someone from the OWNERS file.
Gayane Petrosyana6ee443c2018-05-17 21:39:54386
387## Histogram Expiry
388
Caitlin Fischerb5e94352020-10-27 17:34:50389Histogram expiry is specified by the `expires_after` attribute in histogram
Mark Pearson37c3c9a2023-06-29 17:17:30390descriptions in histograms.xml. It is a required attribute. The attribute can
391be specified as date in **YYYY-MM-DD** format or as Chrome milestone in
392**M**\*(e.g. M105) format. In the latter case, the actual expiry date is about
39312 weeks after that branch is cut, or basically when it is replaced on the
394"stable" channel by the following release.
Brian Whitefa0a3fa2019-05-13 16:58:11395
Mark Pearsonce4371c2021-03-15 23:57:42396After a histogram expires, it ceases to be displayed on the dashboard.
397Follow [these directions](#extending) to extend it.
Brian Whitefa0a3fa2019-05-13 16:58:11398
Caitlin Fischerb5e94352020-10-27 17:34:50399Once a histogram has expired, the code that records it becomes dead code and
Gabriel Gauthier-Shalom0c0f1d862022-02-09 15:47:33400should be removed from the codebase. You should also [clean up](#obsolete) the
Alexei Svitkined4cbf402022-11-14 20:55:25401corresponding entry in histograms.xml. In _rare_ cases, a histogram may be
402expired intentionally while keeping the code around; such cases must be
Alexei Svitkine6fbe8ac2022-11-14 21:17:40403[annotated appropriately](#Intentionally-expired-histograms) in histograms.xml.
Gayane Petrosyana6ee443c2018-05-17 21:39:54404
Brian White8614f812019-02-07 21:07:01405In **rare** cases, the expiry can be set to "never". This is used to denote
Robert Kaplowcbc6fd62021-03-19 15:11:40406metrics of critical importance that are, typically, used for other reports. For
407example, all metrics of the
408"[heartbeat](https://uma.googleplex.com/p/chrome/variations)" are set to never
409expire. All metrics that never expire must have an XML comment describing why so
410that it can be audited in the future. Setting an expiry to "never" must be
411reviewed by [email protected].
Brian White8614f812019-02-07 21:07:01412
413```
414<!-- expires-never: "heartbeat" metric (internal: go/uma-heartbeats) -->
415```
416
Mark Pearson37c3c9a2023-06-29 17:17:30417It is never appropriate to set the expiry to "never" on a new histogram. Most
418new histograms don't turn out to have the properties the implementer wants,
419whether due to bugs in the implementation or simply an evolving understanding
420of what should be measured.
Gayane Petrosyana6ee443c2018-05-17 21:39:54421
Yoshisato Yanagisawa19d35ca2024-04-09 03:50:18422#### Guidelines on expiry
Gayane Petrosyana6ee443c2018-05-17 21:39:54423
Ilya Sherman67418ea2019-11-27 01:28:23424Here are some guidelines for common scenarios:
Gayane Petrosyana6ee443c2018-05-17 21:39:54425
Yoshisato Yanagisawa19d35ca2024-04-09 03:50:18426* If the listed owner moved to a different project, find a new owner.
Ilya Sherman67418ea2019-11-27 01:28:23427* If neither the owner nor the team uses the histogram, remove it.
428* If the histogram is not in use now, but might be useful in the far future,
429 remove it.
430* If the histogram is not in use now, but might be useful in the near
Brian Whitedb68067b2021-10-13 18:27:28431 future, pick ~3 months (also ~3 milestones) ahead.
Yoshisato Yanagisawa19d35ca2024-04-09 03:50:18432* Otherwise, pick an expiry that is reasonable for how long the metric should
433 be used, up to a year.
Ilya Sherman67418ea2019-11-27 01:28:23434
Brian Whitedb68067b2021-10-13 18:27:28435We also have a tool that automatically extends expiry dates. The most frequently
436accessed histograms, currently 99%, have their expirations automatically
437extended every Tuesday to 6 months from the date of the run. Googlers can view
438the [design
439doc](https://docs.google.com/document/d/1IEAeBF9UnYQMDfyh2gdvE7WlUKsfIXIZUw7qNoU89A4)
440of the program that does this. The bottom line is: If the histogram is being
441checked, it should be extended without developer interaction.
Gayane Petrosyana6ee443c2018-05-17 21:39:54442
Yoshisato Yanagisawa19d35ca2024-04-09 03:50:18443#### How to choose expiry for new histograms
444
445In general, set an expiry that is reasonable for how long the metric should
446be used, up to a year.
447
448Some common cases:
449
450* When adding a histogram to evaluate a feature launch, set an expiry date
451 consistent with the expected feature launch date.
452* If you expect the histogram to be useful for an indefinite time, set an
453 expiry date up to 1 year out. This gives a chance to re-evaluate whether
454 the histogram indeed proved to be useful.
455* Otherwise, 3-6 months (3-6 milestones) is typically a good choice.
456
Mark Pearsonce4371c2021-03-15 23:57:42457#### How to extend an expired histogram {#extending}
458
459You can revive an expired histogram by setting the expiration date to a
460date in the future.
461
462There's some leeway here. A client may continue to send data for that
463histogram for some time after the official expiry date so simply bumping
464the 'expires_after' date at HEAD may be sufficient to resurrect it without
465any data discontinuity.
466
467If a histogram expired more than a month ago (for histograms with an
468expiration date) or more than one milestone ago (for histograms with
469expiration milestones; this means top-of-tree is two or more milestones away
470from expired milestone), then you may be outside the safety window. In this
471case, when extending the histogram add to the histogram description a
472message: "Warning: this histogram was expired from DATE to DATE; data may be
473missing." (For milestones, write something similar.)
474
475When reviving a histogram outside the safety window, realize the change to
476histograms.xml to revive it rolls out with the binary release. It takes
477some time to get to the stable channel.
478
479It you need to revive it faster, the histogram can be re-enabled via adding to
480the [expired histogram allowlist](#Expired-histogram-allowlist).
481
Gayane Petrosyana6ee443c2018-05-17 21:39:54482### Expired histogram notifier
483
Caitlin Fischerb5e94352020-10-27 17:34:50484The expired histogram notifier notifies histogram owners before their histograms
485expire by creating crbugs, which are assigned to owners. This allows owners to
486extend the lifetime of their histograms, if needed, or deprecate them. The
487notifier regularly checks all histograms across the histograms.xml files and
488identifies expired or soon-to-be expired histograms. It then creates or updates
489crbugs accordingly.
Gayane Petrosyana6ee443c2018-05-17 21:39:54490
Caitlin Fischer9f4841052020-11-04 21:02:44491### Expired histogram allowlist
Gayane Petrosyana6ee443c2018-05-17 21:39:54492
Caitlin Fischerb5e94352020-10-27 17:34:50493If a histogram expires but turns out to be useful, you can add the histogram's
Alexei Svitkined4cbf402022-11-14 20:55:25494name to the allowlist to re-enable logging for it, until the updated expiration
495date reaches the Stable channel. When doing so, update the histogram's summary
496to document the period during which the histogram's data is incomplete. To add a
497histogram to the allowlist, see the internal documentation:
Caitlin Fischerb5e94352020-10-27 17:34:50498[Histogram Expiry](https://goto.google.com/histogram-expiry-gdoc).
mpearson2b5f7e02016-10-03 21:27:03499
Alexei Svitkine6fbe8ac2022-11-14 21:17:40500### Intentionally expired histograms
Alexei Svitkined4cbf402022-11-14 20:55:25501
502In **rare** cases, a histogram may be expired intentionally while keeping the
503code around. For example, this can be useful for diagnostic metrics that are
504occasionally needed to investigate specific bugs, but do not need to be reported
505otherwise.
506
507To avoid such histograms to be flagged for code clean up, they must be annotated
508in the histograms.xml with the `expired_intentionally` tag as follows:
509
510```xml
511<histogram name="Tab.Open" enum="TabType" expires_after="M100">
512 <expired_intentionally>Kept as a diagnostic metric.</expired_intentionally>
513 <owner>[email protected]</owner>
514 <summary>Histogram summary.</summary>
515</histogram>
516```
517
mpearson72a5c91392017-05-09 22:49:44518## Testing
mpearson2b5f7e02016-10-03 21:27:03519
Caitlin Fischerb5e94352020-10-27 17:34:50520Test your histograms using `chrome://histograms`. Make sure they're being
rkaplow6dfcb892016-10-04 14:04:27521emitted to when you expect and not emitted to at other times. Also check that
Caitlin Fischerb5e94352020-10-27 17:34:50522the values emitted to are correct. Finally, for count histograms, make sure
rkaplow6dfcb892016-10-04 14:04:27523that buckets capture enough precision for your needs over the range.
mpearson2b5f7e02016-10-03 21:27:03524
Ivan Sandrk8ffc5832018-07-09 12:34:58525Pro tip: You can filter the set of histograms shown on `chrome://histograms` by
Luc Nguyenb1324cb2022-12-17 16:23:41526appending to the URL. For example, `chrome://histograms/UserActions` shows
527only histograms whose names contain "UserActions", such as
528"UMA.UserActionsCount".
Ivan Sandrk8ffc5832018-07-09 12:34:58529
mpearson72a5c91392017-05-09 22:49:44530In addition to testing interactively, you can have unit tests examine the
Caitlin Fischerb5e94352020-10-27 17:34:50531values emitted to histograms. See [histogram_tester.h](https://cs.chromium.org/chromium/src/base/test/metrics/histogram_tester.h)
mpearson72a5c91392017-05-09 22:49:44532for details.
mpearson2b5f7e02016-10-03 21:27:03533
Luc Nguyenb1324cb2022-12-17 16:23:41534See also `chrome://metrics-internals` ([docs](https://chromium.googlesource.com/chromium/src/+/master/components/metrics/debug/README.md))
535for more thorough manual testing if needed.
536
Robert Kaplow82027632023-02-13 16:31:52537By default, histograms in unit or browser tests will not be actually uploaded.
538In general, you can rely on the UMA infrastructure to upload the metrics correctly.
539
Alan Screen291bc9a2023-06-27 21:16:49540### Don't Use Histograms to Prove Main Logic Correctness
541
542Do not rely upon using histograms in tests as a way to prove correctness of
543your main program logic. If a unit or browser test uses a histogram count as a
544way to validate logic then that test coverage would be lost if the histogram is
545deleted after it has expired. That situation would prevent cleanup of the
546histogram. Construct your tests using other means to validate your general
547logic, and only use
548[`HistogramTester`](https://cs.chromium.org/chromium/src/base/test/metrics/histogram_tester.h)
549to verify that the histogram values are being generated as you would expect.
550
Dana Friedac15ff82024-04-02 21:19:34551### Verify Enum and Variant Values
552
553If you have <enum> or <variant> entries that need to be updated to match code,
554you can use
555[HistogramEnumReader](https://cs.chromium.org/chromium/src/base/test/metrics/histogram_enum_reader.h)
556or
557[HistogramVariantsReader](https://cs.chromium.org/chromium/src/base/test/metrics/histogram_enum_reader.h)
558to read and verify the expected values in a unit test. This prevents a mismatch
559between code and histogram data from slipping through CQ.
560
561For an example, see
562[BrowserUserEducationServiceTest.CheckFeaturePromoHistograms](https://cs.chromium.org/chromium/src/chrome/browser/ui/views/user_education/browser_user_education_service_unittest.cc).
563
Mark Pearson4c4bc972018-05-16 20:01:06564## Interpreting the Resulting Data
565
566The top of [go/uma-guide](http://go/uma-guide) has good advice on how to go
Caitlin Fischerb5e94352020-10-27 17:34:50567about analyzing and interpreting the results of UMA data uploaded by users. If
Mark Pearson4c4bc972018-05-16 20:01:06568you're reading this page, you've probably just finished adding a histogram to
569the Chromium source code and you're waiting for users to update their version of
Caitlin Fischerb5e94352020-10-27 17:34:50570Chrome to a version that includes your code. In this case, the best advice is
571to remind you that users who update frequently / quickly are biased. Best take
Mark Pearson4c4bc972018-05-16 20:01:06572the initial statistics with a grain of salt; they're probably *mostly* right but
573not entirely so.
574
mpearson72a5c91392017-05-09 22:49:44575## Revising Histograms
576
Robert Kaplowcbc6fd62021-03-19 15:11:40577When changing the semantics of a histogram (when it's emitted, what the buckets
578represent, the bucket range or number of buckets, etc.), create a new histogram
579with a new name. Otherwise analysis that mixes the data pre- and post- change
580may be misleading. If the histogram name is still the best name choice, the
581recommendation is to simply append a '2' to the name. See [Cleaning Up Histogram
Austin Sullivan1040ce22022-04-13 15:51:29582Entries](#obsolete) for details on how to handle the XML changes.
mpearson2b5f7e02016-10-03 21:27:03583
mpearson72a5c91392017-05-09 22:49:44584## Deleting Histograms
mpearson2b5f7e02016-10-03 21:27:03585
Caitlin Fischerb5e94352020-10-27 17:34:50586Please delete code that emits to histograms that are no longer needed.
587Histograms take up memory. Cleaning up histograms that you no longer care
588about is good! But see the note below on
Gabriel Gauthier-Shalom0c0f1d862022-02-09 15:47:33589[Cleaning Up Histogram Entries](#obsolete).
mpearson2b5f7e02016-10-03 21:27:03590
591## Documenting Histograms
592
Darren Shenda91dc752023-03-01 05:28:30593Document histograms in an appropriate [metadata/foo/histograms.xml](https://source.chromium.org/search?q=f:metadata%2F.*%2Fhistograms.xml&ss=chromium%2Fchromium%2Fsrc)
594file.
595
596There is also a [google-internal version of the file](https://goto.google.com/chrome-histograms-internal)
597for two cases:
598
599* The histogram is confidential (an accurate description about how to interpret
600 the histogram would reveal information about Google's plans). In this case,
601 you must only document the histogram in the internal version.
602* The corresponding code that emits the histogram is internal (added only to
603 Chrome code, not to Chromium code). In this case, you may document the
604 histogram in either the internal or external version.
Mark Pearson159c38972018-06-05 19:44:08605
mpearson2b5f7e02016-10-03 21:27:03606### Add Histogram and Documentation in the Same Changelist
607
vapier52b9aba2016-12-14 06:09:25608If possible, please add the [histograms.xml](./histograms.xml) description in
Caitlin Fischerb5e94352020-10-27 17:34:50609the same changelist in which you add the histogram-emitting code. This has
610several benefits. One, it sometimes happens that the
vapier52b9aba2016-12-14 06:09:25611[histograms.xml](./histograms.xml) reviewer has questions or concerns about the
612histogram description that reveal problems with interpretation of the data and
Caitlin Fischerb5e94352020-10-27 17:34:50613call for a different recording strategy. Two, it allows the histogram reviewer
vapier52b9aba2016-12-14 06:09:25614to easily review the emission code to see if it comports with these best
Caitlin Fischerb5e94352020-10-27 17:34:50615practices and to look for other errors.
mpearson2b5f7e02016-10-03 21:27:03616
617### Understandable to Everyone
618
619Histogram descriptions should be roughly understandable to someone not familiar
Caitlin Fischerb5e94352020-10-27 17:34:50620with your feature. Please add a sentence or two of background if necessary.
mpearson2b5f7e02016-10-03 21:27:03621
Robert Kaplowcbc6fd62021-03-19 15:11:40622Note any caveats associated with your histogram in the summary. For example, if
623the set of supported platforms is surprising, such as if a desktop feature is
624not available on Mac, the summary should explain where it is recorded. It is
625also common to have caveats along the lines of "this histogram is only recorded
626if X" (e.g., upon a successful connection to a service, a feature is enabled by
627the user).
628
mpearson2b5f7e02016-10-03 21:27:03629
630### State When It Is Recorded
631
632Histogram descriptions should clearly state when the histogram is emitted
633(profile open? network request received? etc.).
634
Mark Pearsond8fc9fd22021-03-12 20:18:58635Some histograms record error conditions. These should be clear about whether
636all errors are recorded or only the first. If only the first, the histogram
637description should have text like:
638```
639In the case of multiple errors, only the first reason encountered is recorded. Refer
640to Class::FunctionImplementingLogic() for details.
641```
642
Ilya Sherman470c95a2020-09-21 23:05:43643### Provide Clear Units or Enum Labels
644
645For enumerated histograms, including boolean and sparse histograms, provide an
646`enum=` attribute mapping enum values to semantically contentful labels. Define
647the `<enum>` in enums.xml if none of the existing enums are a good fit. Use
648labels whenever they would be clearer than raw numeric values.
649
650For non-enumerated histograms, include a `units=` attribute. Be specific:
651e.g. distinguish "MB" vs. "MiB", refine generic labels like "counts" to more
652precise labels like "pages", etc.
653
jsbellda3a66c2017-02-09 21:40:32654### Owners
rkaplow8a62ef62016-10-06 14:42:34655
Caitlin Fischer254a12f72019-07-31 20:57:03656Histograms need owners, who are the experts on the metric and the points of
657contact for any questions or maintenance tasks, such as extending a histogram's
658expiry or deprecating the metric.
rkaplow8a62ef62016-10-06 14:42:34659
Caitlin Fischer254a12f72019-07-31 20:57:03660Histograms must have a primary owner and may have secondary owners. A primary
Mario Bianucci9947bbd2020-10-28 17:41:47661owner is a Googler with an @google.com or @chromium.org email address, e.g.
Caitlin Fischerb5e94352020-10-27 17:34:50662<owner>[email protected]</owner>, who is ultimately responsible for maintaining
663the metric. Secondary owners may be other individuals, team mailing lists, e.g.
664<owner>[email protected]</owner>, or paths to OWNERS files, e.g.
665<owner>src/directory/OWNERS</owner>.
Mark Pearson74c53212019-03-08 00:34:08666
Caitlin Fischer254a12f72019-07-31 20:57:03667It's a best practice to list multiple owners, so that there's no single point
668of failure for histogram-related questions and maintenance tasks. If you are
669using a metric heavily and understand it intimately, feel free to add yourself
Caitlin Fischerb5e94352020-10-27 17:34:50670as an owner.
Mark Pearson74c53212019-03-08 00:34:08671
Caitlin Fischer254a12f72019-07-31 20:57:03672Notably, owners are asked to determine whether histograms have outlived their
Caitlin Fischerb5e94352020-10-27 17:34:50673usefulness. When a histogram is nearing expiry, a robot files a reminder bug in
674Monorail. It's important that somebody familiar with the histogram notices and
675triages such bugs!
rkaplow8a62ef62016-10-06 14:42:34676
Ilya Shermanf64bca252020-11-10 23:16:24677Tip: When removing someone from the owner list for a histogram, it's a nice
678courtesy to ask them for approval.
679
Caitlin Fischerfeafb4392020-10-05 21:10:07680### Components
681
Ariel Zhang62ee3f42024-02-26 23:25:29682Histograms may be associated with a component, which can help make sure that
Caitlin Fischerfeafb4392020-10-05 21:10:07683histogram expiry bugs don't fall through the cracks.
684
Ariel Zhang62ee3f42024-02-26 23:25:29685A histogram is associated with the `buganizer_public` component listed in the
686DIR_METADATA file adjacent to the histograms.xml file if present.
687
688There are two other ways in which components may be associated with a
689histogram. The first way is to add a tag containing the component ID to a
690histogram or histogram suffix, e.g. <component>1456399</component>. The second
691way is to specify an OWNERS file as a secondary owner for a histogram. If the
692OWNERS file has an adjacent DIR_METADATA file that contains a
693`buganizer_public` component, then that component is associated with the
694histogram. If there isn't a parallel DIR_METADATA file with such a component,
695but an ancestor directory has one, then the ancestor directory's component is
696used.
697
698If more than one component is associated with a histogram, <component> tag is
699favored over adjacent DIR_METADATA file and over OWNERS file.
700
701**Note:** For non-Chromium Issue Tracker (ChromeOS Public Tracker or internal)
702components, make sure [email protected] has access to create and
703update issues.
704
Caitlin Fischerfeafb4392020-10-05 21:10:07705
Sun Yueru39385712023-02-09 20:11:08706### Improvement Direction
707For some histograms, an increase or a decrease in the reported values can be
708associated with either an improvement or a deterioration. For example, if you
709are tracking page load speed, then seeing your metrics tracking page load time
710in milliseconds getting gradually larger values, perhaps as the result of a
711Finch study, may signify worse performance; on the contrary, seeing a reduction
712in the page load speed may indicate an improvement. You can provide this
713information on the movement direction by adding a tag
714 `<improvement direction="LOWER_IS_BETTER"/>` within your `<histogram>`. The
715opposite is `<improvement direction="HIGHER_IS_BETTER"/>`.
716
717For other histograms where there may not be a movement direction that's clearly
718better, you can set `<improvement direction="NEITHER_IS_BETTER"/>`.
719
720This `<improvement>` tag is optional. You can also add/delete this tag or make a
721correction to its `direction` attribute any time.
722
Gabriel Gauthier-Shalom0c0f1d862022-02-09 15:47:33723### Cleaning Up Histogram Entries {#obsolete}
mpearson2b5f7e02016-10-03 21:27:03724
Alexei Svitkine7bfb6702023-11-28 18:18:24725When the code to log a histogram is deleted, its corresponding histograms.xml
726entry should also be removed. Past histogram data will still be available for
727viewing on Google's internal UMA dashboard.
Pavol Marko17ed24e2023-09-11 09:43:15728
Alexei Svitkine7bfb6702023-11-28 18:18:24729The CL to remove one or more histograms can also specify an obsoletion message
730through special syntax in the CL description. This also applies to variants of a
Gabriel Gauthier-Shalom0c0f1d862022-02-09 15:47:33731[patterned histogram](#Patterned-Histograms) and to suffix entries for a
732suffixed histogram.
Mark Pearson2a311c52019-03-19 21:47:01733
Ariel Zhanged17ef22023-05-18 16:42:48734The changelist that obsoletes a histogram entry should be reviewed by all
735current owners.
Mark Pearson2a311c52019-03-19 21:47:01736
Ariel Zhanged17ef22023-05-18 16:42:48737#### Remove the Entry
Mark Pearson2a311c52019-03-19 21:47:01738
Ariel Zhanged17ef22023-05-18 16:42:48739Delete the entry in the histograms.xml file.
Gabriel Gauthier-Shalom0c0f1d862022-02-09 15:47:33740
Gabriel Gauthier-Shaloma7394aa2022-02-14 16:33:37741* In some cases there may be artifacts that remain, with some examples being:
Charlie Harrison1ad2f852023-11-06 18:22:23742 * Empty `<token>` blocks, or individual `<variant>`s.
Gabriel Gauthier-Shaloma7394aa2022-02-14 16:33:37743 * `<enum>` blocks from enums.xml that are no longer used.
Alexei Svitkine7bfb6702023-11-28 18:18:24744 * Suffix entries in `histogram_suffixes_list.xml`.
Gabriel Gauthier-Shaloma7394aa2022-02-14 16:33:37745* Please remove these artifacts if you find them.
Sun Yueruf81cee32023-01-19 01:52:58746 * **Exception**: please update the label of `<int value=... label=... />` with
747 the `(Obsolete) ` prefix, e.g.
748 `<int value="1" label="(Obsolete) Navigation failed. Removed in 2023/01."/>`
749 rather than deleting them, if the surrounding `<enum>` block is not being
750 deleted.
Ariel Zhanged17ef22023-05-18 16:42:48751
752#### Add an Obsoletion Message
753
Will Harris0874e552023-08-25 16:09:44754An obsoletion message is displayed on the dashboard and provides developers
755context for why the histogram was removed and, if applicable, which histogram
756it was replaced by.
757
Alexei Svitkine7bfb6702023-11-28 18:18:24758**Note:** You can skip this step if the histogram is expired. This is because
759tooling automatically records the date and milestone of a histogram's
Ariel Zhangd111b722023-12-12 15:48:58760removal.
Ariel Zhang1cd268202023-07-14 19:30:56761
Will Harris0874e552023-08-25 16:09:44762You can provide a custom obsoletion message for a removed histogram via tags
763on the CL description:
Ariel Zhanged17ef22023-05-18 16:42:48764
765* Add the obsoletion message in the CL description in the format
Alexei Svitkine7bfb6702023-11-28 18:18:24766 `OBSOLETE_HISTOGRAM[histogram name]=message`, e.g.:
767 `OBSOLETE_HISTOGRAM[Tab.Count]=Replaced by Tab.Count2`
768* To add the same obsoletion message to all the histograms removed in the CL,
769 you can use `OBSOLETE_HISTOGRAMS=message`, e.g.:
770 `OBSOLETE_HISTOGRAMS=Patterned histogram Hist.{Token} is replaced by Hist.{Token}.2`
Ariel Zhang7b8cbf92023-06-21 22:24:14771* **Notes:**
Ariel Zhangd111b722023-12-12 15:48:58772 * **The full tag should be put on a single line, even if it is longer than the
773 maximum CL description width.**
Ariel Zhang1cd268202023-07-14 19:30:56774 * You can add multiple obsoletion message tags in one CL.
Alexei Svitkine7bfb6702023-11-28 18:18:24775 * `OBSOLETE_HISTOGRAMS` messages will be overwritten by histogram-specific
776 ones, if present.
777* You could also include information about why the histogram was removed. For
778 example, you might indicate how the histogram's summary did not accurately
779 describe the collected data.
780* If the histogram is being replaced, include the name of the replacement and
781 make sure that the new description is different from the original to reflect
782 the change between versions.
Ilya Sherman8f0034a2020-07-22 22:06:34783
Ilya Sherman9e22dea2020-10-05 22:32:36784### Patterned Histograms
Ilya Shermanf54104b2017-07-12 23:45:47785
786It is sometimes useful to record several closely related metrics, which measure
Ilya Sherman9e22dea2020-10-05 22:32:36787the same type of data, with some minor variations. You can declare the metadata
788for these concisely using patterned histograms. For example:
Ilya Shermanf54104b2017-07-12 23:45:47789
Ilya Sherman9e22dea2020-10-05 22:32:36790```xml
Jared Saul73a9daaf2021-05-04 15:33:02791<histogram name="Pokemon.{Character}.EfficacyAgainst{OpponentType}"
Robert Kaplowe1430ce2021-03-25 19:02:18792 units="multiplier" expires_after="M95">
Ilya Sherman9e22dea2020-10-05 22:32:36793 <owner>[email protected]</owner>
794 <owner>[email protected]</owner>
795 <summary>
796 The efficacy multiplier for {Character} against an opponent of
797 {OpponentType} type.
798 </summary>
799 <token key="Character">
800 <variant name="Bulbasaur"/>
801 <variant name="Charizard"/>
802 <variant name="Mewtwo"/>
803 </token>
804 <token key="OpponentType">
805 <variant name="Dragon" summary="dragon"/>
806 <variant name="Flying" summary="flappity-flap"/>
807 <variant name="Psychic" summary="psychic"/>
808 <variant name="Water" summary="water"/>
809 </token>
810</histogram>
811```
812
813This example defines metadata for 12 (= 3 x 4) concrete histograms, such as
814
815```xml
Robert Kaplowe1430ce2021-03-25 19:02:18816<histogram name="Pokemon.Charizard.EfficacyAgainstWater"
817 units="multiplier" expires_after="M95">
Ilya Sherman9e22dea2020-10-05 22:32:36818 <owner>[email protected]</owner>
819 <owner>[email protected]</owner>
820 <summary>
821 The efficacy multiplier for Charizard against an opponent of water type.
822 </summary>
823</histogram>
824```
825
Mark Pearson268ea6b2021-09-28 00:44:45826Each token `<variant>` defines what text should be substituted for it,
827both in the histogram name and in the summary text. The name part gets
828substituted into the histogram name; the summary part gets substituted in
829the summary field (the histogram description). As shorthand, a
830`<variant>` that omits the `summary` attribute substitutes the value of
831the `name` attribute in the histogram's `<summary>` text as well.
Ilya Sherman9e22dea2020-10-05 22:32:36832
833*** promo
834Tip: You can declare an optional token by listing an empty name: `<variant
835name="" summary="aggregated across all breakdowns"/>`. This can be useful when
836recording a "parent" histogram that aggregates across a set of breakdowns.
837***
838
839You can use the `<variants>` tag to define a set of `<variant>`s out-of-line.
840This is useful for token substitutions that are shared among multiple families
Ariel Zhang6adadaf2023-06-07 14:55:15841of histograms within the same file. See
Ilya Sherman9e22dea2020-10-05 22:32:36842[histograms.xml](https://source.chromium.org/search?q=file:histograms.xml%20%3Cvariants)
843for examples.
844
Joe Masonb468cc42022-06-21 18:02:16845*** promo
846Warning: The `name` attribute of the `<variants>` tag is globally scoped, so
Ariel Zhang6adadaf2023-06-07 14:55:15847use detailed names to avoid collisions. The `<variants>` defined should only
848be used within the file.
Joe Masonb468cc42022-06-21 18:02:16849***
850
Caitlin Fischerb5e94352020-10-27 17:34:50851By default, a `<variant>` inherits the owners declared for the patterned
Ilya Sherman9e22dea2020-10-05 22:32:36852histogram. Each variant can optionally override the inherited list with custom
853owners:
854```xml
855<variant name="SubteamBreakdown" ...>
856 <owner>[email protected]</owner>
857 <owner>[email protected]</owner>
858</variant>
859```
Mark Pearsona0109122018-05-30 18:23:05860
Ilya Sherman9e22dea2020-10-05 22:32:36861*** promo
Oksana Zhuravlova5242ad22021-02-19 00:14:20862Tip: You can run `print_expanded_histograms.py --pattern=` to show all generated
Weilun Shibac61d9d32020-11-12 02:40:26863histograms by patterned histograms or histogram suffixes including their
864summaries and owners. For example, this can be run (from the repo root) as:
865```
Oksana Zhuravlova5242ad22021-02-19 00:14:20866./tools/metrics/histograms/print_expanded_histograms.py --pattern=^UMA.A.B
Weilun Shibac61d9d32020-11-12 02:40:26867```
868***
869
870*** promo
Ilya Sherman9e22dea2020-10-05 22:32:36871Tip: You can run `print_histogram_names.py --diff` to enumerate all the
872histogram names that are generated by a particular CL. For example, this can be
873run (from the repo root) as:
Charlie Harrison90407d92020-05-19 23:57:32874```
Egor Pasko5ec32b72021-07-23 14:34:22875./tools/metrics/histograms/print_histogram_names.py --diff origin/main
Charlie Harrison90407d92020-05-19 23:57:32876```
Ilya Sherman9e22dea2020-10-05 22:32:36877***
878
879For documentation about the `<histogram_suffixes>` syntax, which is deprecated,
880see
881https://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:32882
mpearson2b5f7e02016-10-03 21:27:03883## When To Use Sparse Histograms
884
Caitlin Fischerb5e94352020-10-27 17:34:50885Sparse histograms are well-suited for recording counts of exact sample values
886that are sparsely distributed over a large range. They can be used with enums
Ilya Sherman1eee82c4c2017-12-08 01:22:19887as well as regular integer values. It is often valuable to provide labels in
888[enums.xml](./enums.xml).
mpearson2b5f7e02016-10-03 21:27:03889
890The implementation uses a lock and a map, whereas other histogram types use a
891vector and no lock. It is thus more costly to add values to, and each value
892stored has more overhead, compared to the other histogram types. However it
893may be more efficient in memory if the total number of sample values is small
894compared to the range of their values.
895
Mark Pearsoned73f1f2019-03-22 18:00:12896Please talk with the metrics team if there are more than a thousand possible
897different values that you could emit.
898
rkaplow6dfcb892016-10-04 14:04:27899For more information, see [sparse_histograms.h](https://cs.chromium.org/chromium/src/base/metrics/sparse_histogram.h).
Caitlin Fischerb466a042019-07-31 21:41:46900
Ilya Shermanf64bca252020-11-10 23:16:24901
Robert Kaplow6be6fbf2021-04-19 17:30:38902# Becoming a Metrics Reviewer
Caitlin Fischerb466a042019-07-31 21:41:46903
Jared Saul73a9daaf2021-05-04 15:33:02904Any Chromium committer who is also a Google employee is eligible to become a
905metrics reviewer. Please follow the instructions at [go/reviewing-metrics](https://goto.google.com/reviewing-metrics).
906This consists of reviewing our training materials and passing an informational
907quiz. Since metrics have a direct impact on internal systems and have privacy
Robert Kaplow6be6fbf2021-04-19 17:30:38908considerations, we're currently only adding Googlers into this program.
909
910
911# Reviewing Metrics CLs
Ilya Shermanf64bca252020-11-10 23:16:24912
Robert Kaplowcbc6fd62021-03-19 15:11:40913If you are a metric OWNER, you have the serious responsibility of ensuring
914Chrome's data collection is following best practices. If there's any concern
915about an incoming metrics changelist, please escalate by assigning to
916[email protected].
917
Ilya Shermanf64bca252020-11-10 23:16:24918When reviewing metrics CLs, look at the following, listed in approximate order
919of importance:
920
Robert Kaplow6be6fbf2021-04-19 17:30:38921## Privacy
Ilya Shermanf64bca252020-11-10 23:16:24922
923Does anything tickle your privacy senses? (Googlers, see
924[go/uma-privacy](https://goto.google.com/uma-privacy) for guidelines.)
925
926**Please escalate if there's any doubt!**
927
Robert Kaplow6be6fbf2021-04-19 17:30:38928## Clarity
Ilya Shermanf64bca252020-11-10 23:16:24929
930Is the metadata clear enough for [all Chromies](#Understandable-to-Everyone) to
931understand what the metric is recording? Consider the histogram name,
932description, units, enum labels, etc.
933
934It's really common for developers to forget to list [when the metric is
935recorded](#State-When-It-Is-Recorded). This is particularly important context,
936so please remind developers to clearly document it.
937
938Note: Clarity is a bit less important for very niche metrics used only by a
939couple of engineers. However, it's hard to assess the metric design and
940correctness if the metadata is especially unclear.
941
Robert Kaplow6be6fbf2021-04-19 17:30:38942## Metric design
Ilya Shermanf64bca252020-11-10 23:16:24943
944* Does the metric definition make sense?
945* Will the resulting data be interpretable at analysis time?
946
Robert Kaplow6be6fbf2021-04-19 17:30:38947## Correctness
Ilya Shermanf64bca252020-11-10 23:16:24948
949Is the histogram being recorded correctly?
950
951* Does the bucket layout look reasonable?
952
953 * The metrics APIs like base::UmaHistogram* have some sharp edges,
954 especially for the APIs that require specifying the number of
955 buckets. Check for off-by-one errors and unused buckets.
956
957 * Is the bucket layout efficient? Typically, push back if there are >50
958 buckets -- this can be ok in some cases, but make sure that the CL author
959 has consciously considered the tradeoffs here and is making a reasonable
960 choice.
961
962 * For timing metrics, do the min and max bounds make sense for the duration
963 that is being measured?
964
965* The base::UmaHistogram* functions are
966 [generally preferred](#Coding-Emitting-to-Histograms) over the
967 UMA_HISTOGRAM_* macros. If using the macros, remember that names must be
968 runtime constants!
969
970Also, related to [clarity](#Clarity): Does the client logic correctly implement
971the metric described in the XML metadata? Some common errors to watch out for:
972
973* The metric is only emitted within an if-stmt (e.g., only if some data is
974 available) and this restriction isn't mentioned in the metadata description.
975
976* The metric description states that it's recorded when X happens, but it's
977 actually recorded when X is scheduled to occur, or only emitted when X
978 succeeds (but omitted on failure), etc.
979
980When the metadata and the client logic do not match, the appropriate solution
981might be to update the metadata, or it might be to update the client
982logic. Guide this decision by considering what data will be more easily
983interpretable and what data will have hidden surprises/gotchas.
984
Robert Kaplow6be6fbf2021-04-19 17:30:38985## Sustainability
Ilya Shermanf64bca252020-11-10 23:16:24986
Robert Kaplowcd6e0422021-04-07 21:58:53987* Is the CL adding a reasonable number of metrics/buckets?
Ilya Shermanf64bca252020-11-10 23:16:24988 * When reviewing a CL that is trying to add many metrics at once, guide the CL
989 author toward an appropriate solution for their needs. For example,
990 multidimensional metrics can be recorded via UKM, and we are currently
Robert Kaplowcd6e0422021-04-07 21:58:53991 building support for structured metrics in UMA.
992 * There's no hard rule, but anything above 20 separate histograms should be
993 escalated by being assigned to [email protected].
994 * Similarly, any histogram with more than 100 possible buckets should be
995 escalated by being assigned to [email protected].
Ilya Shermanf64bca252020-11-10 23:16:24996
997* Are expiry dates being set
998 [appropriately](#How-to-choose-expiry-for-histograms)?
999
Robert Kaplow6be6fbf2021-04-19 17:30:381000## Everything Else!
Ilya Shermanf64bca252020-11-10 23:16:241001
1002This document describes many other nuances that are important for defining and
1003recording useful metrics. Check CLs for these other types of issues as well.
1004
1005And, as you would with a language style guide, periodically re-review the doc to
1006stay up to date on the details.
1007
Ilya Shermanf64bca252020-11-10 23:16:241008
Robert Kaplow6be6fbf2021-04-19 17:30:381009# Team Documentation
Ilya Shermanf64bca252020-11-10 23:16:241010
Caitlin Fischerb466a042019-07-31 21:41:461011
1012## Processing histograms.xml
1013
1014When working with histograms.xml, verify whether you require fully expanded
1015OWNERS files. Many scripts in this directory process histograms.xml, and
1016sometimes OWNERS file paths are expanded and other times they are not. OWNERS
1017paths are expanded when scripts make use of merge_xml's function MergeFiles;
1018otherwise, they are not.