• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.base.metrics;
6 
7 import android.text.format.DateUtils;
8 
9 import java.util.List;
10 
11 /**
12  * Java API for recording UMA histograms.
13  * */
14 public class RecordHistogram {
15     /**
16      * Records a sample in a boolean UMA histogram of the given name. Boolean histogram has two
17      * buckets, corresponding to success (true) and failure (false). This is the Java equivalent of
18      * the UMA_HISTOGRAM_BOOLEAN C++ macro.
19      *
20      * @param name name of the histogram
21      * @param sample sample to be recorded, either true or false
22      */
recordBooleanHistogram(String name, boolean sample)23     public static void recordBooleanHistogram(String name, boolean sample) {
24         UmaRecorderHolder.get().recordBooleanHistogram(name, sample);
25     }
26 
27     /**
28      * Records a sample in an enumerated histogram of the given name and boundary. Note that
29      * {@code max} identifies the histogram - it should be the same at every invocation. This is the
30      * Java equivalent of the UMA_HISTOGRAM_ENUMERATION C++ macro.
31      *
32      * @param name name of the histogram
33      * @param sample sample to be recorded, at least 0 and at most {@code max-1}
34      * @param max upper bound for legal sample values - all sample values have to be strictly
35      *            lower than {@code max}
36      */
recordEnumeratedHistogram(String name, int sample, int max)37     public static void recordEnumeratedHistogram(String name, int sample, int max) {
38         recordExactLinearHistogram(name, sample, max);
39     }
40 
41     /**
42      * Records a sample in a count histogram. This is the Java equivalent of the
43      * UMA_HISTOGRAM_COUNTS_1M C++ macro.
44      *
45      * @param name name of the histogram
46      * @param sample sample to be recorded, at least 1 and at most 999999
47      */
recordCount1MHistogram(String name, int sample)48     public static void recordCount1MHistogram(String name, int sample) {
49         UmaRecorderHolder.get().recordExponentialHistogram(name, sample, 1, 1_000_000, 50);
50     }
51 
52     /**
53      * Records a sample in a count histogram. This is the Java equivalent of the
54      * UMA_HISTOGRAM_COUNTS_100 C++ macro.
55      *
56      * @param name name of the histogram
57      * @param sample sample to be recorded, at least 1 and at most 99
58      */
recordCount100Histogram(String name, int sample)59     public static void recordCount100Histogram(String name, int sample) {
60         UmaRecorderHolder.get().recordExponentialHistogram(name, sample, 1, 100, 50);
61     }
62 
63     /**
64      * Records a sample in a count histogram. This is the Java equivalent of the
65      * UMA_HISTOGRAM_COUNTS_1000 C++ macro.
66      *
67      * @param name name of the histogram
68      * @param sample sample to be recorded, at least 1 and at most 999
69      */
recordCount1000Histogram(String name, int sample)70     public static void recordCount1000Histogram(String name, int sample) {
71         UmaRecorderHolder.get().recordExponentialHistogram(name, sample, 1, 1_000, 50);
72     }
73 
74     /**
75      * Records a sample in a count histogram. This is the Java equivalent of the
76      * UMA_HISTOGRAM_COUNTS_100000 C++ macro.
77      *
78      * @param name name of the histogram
79      * @param sample sample to be recorded, at least 1 and at most 99999
80      */
recordCount100000Histogram(String name, int sample)81     public static void recordCount100000Histogram(String name, int sample) {
82         UmaRecorderHolder.get().recordExponentialHistogram(name, sample, 1, 100_000, 50);
83     }
84 
85     /**
86      * Records a sample in a count histogram. This is the Java equivalent of the
87      * UMA_HISTOGRAM_CUSTOM_COUNTS C++ macro.
88      *
89      * @param name name of the histogram
90      * @param sample sample to be recorded, expected to fall in range {@code [min, max)}
91      * @param min the smallest expected sample value; at least 1
92      * @param max the smallest sample value that will be recorded in overflow bucket
93      * @param numBuckets the number of buckets including underflow ({@code [0, min)}) and overflow
94      *                   ({@code [max, inf)}) buckets; at most 100
95      */
recordCustomCountHistogram( String name, int sample, int min, int max, int numBuckets)96     public static void recordCustomCountHistogram(
97             String name, int sample, int min, int max, int numBuckets) {
98         UmaRecorderHolder.get().recordExponentialHistogram(name, sample, min, max, numBuckets);
99     }
100 
101     /**
102      * Records a sample in a linear histogram. This is the Java equivalent for using
103      * {@code base::LinearHistogram}.
104      *
105      * @param name name of the histogram
106      * @param sample sample to be recorded, expected to fall in range {@code [min, max)}
107      * @param min the smallest expected sample value; at least 1
108      * @param max the smallest sample value that will be recorded in overflow bucket
109      * @param numBuckets the number of buckets including underflow ({@code [0, min)}) and overflow
110      *                   ({@code [max, inf)}) buckets; at most 100
111      */
recordLinearCountHistogram( String name, int sample, int min, int max, int numBuckets)112     public static void recordLinearCountHistogram(
113             String name, int sample, int min, int max, int numBuckets) {
114         UmaRecorderHolder.get().recordLinearHistogram(name, sample, min, max, numBuckets);
115     }
116 
117     /**
118      * Records a sample in a percentage histogram. This is the Java equivalent of the
119      * UMA_HISTOGRAM_PERCENTAGE C++ macro.
120      *
121      * @param name name of the histogram
122      * @param sample sample to be recorded, at least 0 and at most 100
123      */
recordPercentageHistogram(String name, int sample)124     public static void recordPercentageHistogram(String name, int sample) {
125         recordExactLinearHistogram(name, sample, 101);
126     }
127 
128     /**
129      * Records a sparse histogram. This is the Java equivalent of {@code base::UmaHistogramSparse}.
130      *
131      * @param name name of the histogram
132      * @param sample sample to be recorded: All values of {@code sample} are valid, including
133      *               negative values. Keep the number of distinct values across all users
134      *               {@code <= 100} ideally, definitely {@code <= 1000}.
135      */
recordSparseHistogram(String name, int sample)136     public static void recordSparseHistogram(String name, int sample) {
137         UmaRecorderHolder.get().recordSparseHistogram(name, sample);
138     }
139 
140     /**
141      * Records a sample in a histogram of times. Useful for recording short durations. This is the
142      * Java equivalent of the UMA_HISTOGRAM_TIMES C++ macro.
143      * <p>
144      * Note that histogram samples will always be converted to milliseconds when logged.
145      *
146      * @param name name of the histogram
147      * @param durationMs duration to be recorded in milliseconds
148      */
recordTimesHistogram(String name, long durationMs)149     public static void recordTimesHistogram(String name, long durationMs) {
150         recordCustomTimesHistogramMilliseconds(
151                 name, durationMs, 1, DateUtils.SECOND_IN_MILLIS * 10, 50);
152     }
153 
154     /**
155      * Records a sample in a histogram of times. Useful for recording medium durations. This is the
156      * Java equivalent of the UMA_HISTOGRAM_MEDIUM_TIMES C++ macro.
157      * <p>
158      * Note that histogram samples will always be converted to milliseconds when logged.
159      *
160      * @param name name of the histogram
161      * @param durationMs duration to be recorded in milliseconds
162      */
recordMediumTimesHistogram(String name, long durationMs)163     public static void recordMediumTimesHistogram(String name, long durationMs) {
164         recordCustomTimesHistogramMilliseconds(
165                 name, durationMs, 10, DateUtils.MINUTE_IN_MILLIS * 3, 50);
166     }
167 
168     /**
169      * Records a sample in a histogram of times. Useful for recording long durations. This is the
170      * Java equivalent of the UMA_HISTOGRAM_LONG_TIMES C++ macro.
171      * <p>
172      * Note that histogram samples will always be converted to milliseconds when logged.
173      *
174      * @param name name of the histogram
175      * @param durationMs duration to be recorded in milliseconds
176      */
recordLongTimesHistogram(String name, long durationMs)177     public static void recordLongTimesHistogram(String name, long durationMs) {
178         recordCustomTimesHistogramMilliseconds(name, durationMs, 1, DateUtils.HOUR_IN_MILLIS, 50);
179     }
180 
181     /**
182      * Records a sample in a histogram of times. Useful for recording long durations. This is the
183      * Java equivalent of the UMA_HISTOGRAM_LONG_TIMES_100 C++ macro.
184      * <p>
185      * Note that histogram samples will always be converted to milliseconds when logged.
186      *
187      * @param name name of the histogram
188      * @param durationMs duration to be recorded in milliseconds
189      */
recordLongTimesHistogram100(String name, long durationMs)190     public static void recordLongTimesHistogram100(String name, long durationMs) {
191         recordCustomTimesHistogramMilliseconds(name, durationMs, 1, DateUtils.HOUR_IN_MILLIS, 100);
192     }
193 
194     /**
195      * Records a sample in a histogram of times with custom buckets. This is the Java equivalent of
196      * the UMA_HISTOGRAM_CUSTOM_TIMES C++ macro.
197      * <p>
198      * Note that histogram samples will always be converted to milliseconds when logged.
199      *
200      * @param name name of the histogram
201      * @param durationMs duration to be recorded in milliseconds; expected to fall in range
202      *                   {@code [min, max)}
203      * @param min the smallest expected sample value; at least 1
204      * @param max the smallest sample value that will be recorded in overflow bucket
205      * @param numBuckets the number of buckets including underflow ({@code [0, min)}) and overflow
206      *                   ({@code [max, inf)}) buckets; at most 100
207      */
recordCustomTimesHistogram( String name, long durationMs, long min, long max, int numBuckets)208     public static void recordCustomTimesHistogram(
209             String name, long durationMs, long min, long max, int numBuckets) {
210         recordCustomTimesHistogramMilliseconds(name, durationMs, min, max, numBuckets);
211     }
212 
213     /**
214      * Records a sample in a histogram of sizes in KB. This is the Java equivalent of the
215      * UMA_HISTOGRAM_MEMORY_KB C++ macro.
216      * <p>
217      * Good for sizes up to about 500MB.
218      *
219      * @param name name of the histogram
220      * @param sizeInkB Sample to record in KB
221      */
recordMemoryKBHistogram(String name, int sizeInKB)222     public static void recordMemoryKBHistogram(String name, int sizeInKB) {
223         UmaRecorderHolder.get().recordExponentialHistogram(name, sizeInKB, 1000, 500000, 50);
224     }
225 
226     /**
227      * Records a sample in a histogram of sizes in MB. This is the Java equivalent of the
228      * UMA_HISTOGRAM_MEMORY_MEDIUM_MB C++ macro.
229      * <p>
230      * Good for sizes up to about 4000MB.
231      *
232      * @param name name of the histogram
233      * @param sizeInMB Sample to record in MB
234      */
recordMemoryMediumMBHistogram(String name, int sizeInMB)235     public static void recordMemoryMediumMBHistogram(String name, int sizeInMB) {
236         UmaRecorderHolder.get().recordExponentialHistogram(name, sizeInMB, 1, 4000, 100);
237     }
238 
239     /**
240      * Records a sample in a linear histogram where each bucket in range {@code [0, max)} counts
241      * exactly a single value.
242      *
243      * @param name name of the histogram
244      * @param sample sample to be recorded, expected to fall in range {@code [0, max)}
245      * @param max the smallest value counted in the overflow bucket, shouldn't be larger than 100
246      */
recordExactLinearHistogram(String name, int sample, int max)247     public static void recordExactLinearHistogram(String name, int sample, int max) {
248         // Range [0, 1) is counted in the underflow bucket. The first "real" bucket starts at 1.
249         final int min = 1;
250         // One extra is added for the overflow bucket.
251         final int numBuckets = max + 1;
252         UmaRecorderHolder.get().recordLinearHistogram(name, sample, min, max, numBuckets);
253     }
254 
clampToInt(long value)255     private static int clampToInt(long value) {
256         if (value > Integer.MAX_VALUE) return Integer.MAX_VALUE;
257         // Note: Clamping to MIN_VALUE rather than 0, to let base/ histograms code do its own
258         // handling of negative values in the future.
259         if (value < Integer.MIN_VALUE) return Integer.MIN_VALUE;
260         return (int) value;
261     }
262 
recordCustomTimesHistogramMilliseconds( String name, long duration, long min, long max, int numBuckets)263     private static void recordCustomTimesHistogramMilliseconds(
264             String name, long duration, long min, long max, int numBuckets) {
265         UmaRecorderHolder.get()
266                 .recordExponentialHistogram(
267                         name, clampToInt(duration), clampToInt(min), clampToInt(max), numBuckets);
268     }
269 
270     /**
271      * Returns the number of samples recorded in the given bucket of the given histogram.
272      *
273      * @deprecated Raw counts are easy to misuse. Does not reset between batched tests. Use
274      * {@link org.chromium.base.test.util.HistogramWatcher} instead.
275      *
276      * @param name name of the histogram to look up
277      * @param sample the bucket containing this sample value will be looked up
278      */
279     @Deprecated
getHistogramValueCountForTesting(String name, int sample)280     public static int getHistogramValueCountForTesting(String name, int sample) {
281         return UmaRecorderHolder.get().getHistogramValueCountForTesting(name, sample);
282     }
283 
284     /**
285      * Returns the number of samples recorded for the given histogram.
286      *
287      * @deprecated Raw counts are easy to misuse. Does not reset between batched tests. Use
288      * {@link org.chromium.base.test.util.HistogramWatcher} instead.
289      *
290      * @param name name of the histogram to look up
291      */
292     @Deprecated
getHistogramTotalCountForTesting(String name)293     public static int getHistogramTotalCountForTesting(String name) {
294         return UmaRecorderHolder.get().getHistogramTotalCountForTesting(name);
295     }
296 
297     /**
298      * Returns the buckets of samples recorded for the given histogram.
299      *
300      * Use {@link org.chromium.base.test.util.HistogramWatcher} instead of using this directly.
301      *
302      * @param name name of the histogram to look up
303      */
getHistogramSamplesForTesting(String name)304     public static List<HistogramBucket> getHistogramSamplesForTesting(String name) {
305         return UmaRecorderHolder.get().getHistogramSamplesForTesting(name);
306     }
307 }
308