1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Histogram is an object that aggregates statistics, and can summarize them in
6 // various forms, including ASCII graphical, HTML, and numerically (as a
7 // vector of numbers corresponding to each of the aggregating buckets).
9 // It supports calls to accumulate either time intervals (which are processed
10 // as integral number of milliseconds), or arbitrary integral units.
12 // The default layout of buckets is exponential. For example, buckets might
13 // contain (sequentially) the count of values in the following intervals:
14 // [0,1), [1,2), [2,4), [4,8), [8,16), [16,32), [32,64), [64,infinity)
15 // That bucket allocation would actually result from construction of a histogram
16 // for values between 1 and 64, with 8 buckets, such as:
17 // Histogram count(L"some name", 1, 64, 8);
18 // Note that the underflow bucket [0,1) and the overflow bucket [64,infinity)
19 // are not counted by the constructor in the user supplied "bucket_count"
21 // The above example has an exponential ratio of 2 (doubling the bucket width
22 // in each consecutive bucket. The Histogram class automatically calculates
23 // the smallest ratio that it can use to construct the number of buckets
24 // selected in the constructor. An another example, if you had 50 buckets,
25 // and millisecond time values from 1 to 10000, then the ratio between
26 // consecutive bucket widths will be approximately somewhere around the 50th
27 // root of 10000. This approach provides very fine grain (narrow) buckets
28 // at the low end of the histogram scale, but allows the histogram to cover a
29 // gigantic range with the addition of very few buckets.
31 #ifndef BASE_HISTOGRAM_H_
32 #define BASE_HISTOGRAM_H_
39 #include "base/ref_counted.h"
40 #include "base/logging.h"
41 #include "base/time.h"
45 //------------------------------------------------------------------------------
46 // Provide easy general purpose histogram in a macro, just like stats counters.
47 // The first four macros use 50 buckets.
49 #define HISTOGRAM_TIMES(name, sample) HISTOGRAM_CUSTOM_TIMES( \
50 name, sample, base::TimeDelta::FromMilliseconds(1), \
51 base::TimeDelta::FromSeconds(10), 50)
53 #define HISTOGRAM_COUNTS(name, sample) HISTOGRAM_CUSTOM_COUNTS( \
54 name, sample, 1, 1000000, 50)
56 #define HISTOGRAM_COUNTS_100(name, sample) HISTOGRAM_CUSTOM_COUNTS( \
57 name, sample, 1, 100, 50)
59 #define HISTOGRAM_COUNTS_10000(name, sample) HISTOGRAM_CUSTOM_COUNTS( \
60 name, sample, 1, 10000, 50)
62 #define HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \
63 static scoped_refptr<Histogram> counter = Histogram::FactoryGet( \
64 name, min, max, bucket_count, Histogram::kNoFlags); \
65 DCHECK_EQ(name, counter->histogram_name()); \
66 if (counter.get()) counter->Add(sample); \
69 #define HISTOGRAM_PERCENTAGE(name, under_one_hundred) \
70 HISTOGRAM_ENUMERATION(name, under_one_hundred, 101)
72 // For folks that need real specific times, use this to select a precise range
73 // of times you want plotted, and the number of buckets you want used.
74 #define HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \
75 static scoped_refptr<Histogram> counter = Histogram::FactoryTimeGet( \
76 name, min, max, bucket_count, Histogram::kNoFlags); \
77 DCHECK_EQ(name, counter->histogram_name()); \
78 if (counter.get()) counter->AddTime(sample); \
81 // DO NOT USE THIS. It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES.
82 #define HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \
83 static scoped_refptr<Histogram> counter = Histogram::FactoryTimeGet( \
84 name, min, max, bucket_count, Histogram::kNoFlags); \
85 DCHECK_EQ(name, counter->histogram_name()); \
86 if ((sample) < (max) && counter.get()) counter->AddTime(sample); \
89 // Support histograming of an enumerated value. The samples should always be
90 // less than boundary_value.
92 #define HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \
93 static scoped_refptr<Histogram> counter = LinearHistogram::FactoryGet( \
94 name, 1, boundary_value, boundary_value + 1, Histogram::kNoFlags); \
95 DCHECK_EQ(name, counter->histogram_name()); \
96 if (counter.get()) counter->Add(sample); \
99 #define HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) do { \
100 static scoped_refptr<Histogram> counter = CustomHistogram::FactoryGet( \
101 name, custom_ranges, Histogram::kNoFlags); \
102 DCHECK_EQ(name, counter->histogram_name()); \
103 if (counter.get()) counter->Add(sample); \
107 //------------------------------------------------------------------------------
108 // Define Debug vs non-debug flavors of macros.
111 #define DHISTOGRAM_TIMES(name, sample) HISTOGRAM_TIMES(name, sample)
112 #define DHISTOGRAM_COUNTS(name, sample) HISTOGRAM_COUNTS(name, sample)
113 #define DHISTOGRAM_PERCENTAGE(name, under_one_hundred) HISTOGRAM_PERCENTAGE(\
114 name, under_one_hundred)
115 #define DHISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \
116 HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count)
117 #define DHISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) \
118 HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count)
119 #define DHISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \
120 HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count)
121 #define DHISTOGRAM_ENUMERATION(name, sample, boundary_value) \
122 HISTOGRAM_ENUMERATION(name, sample, boundary_value)
123 #define DHISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \
124 HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges)
128 #define DHISTOGRAM_TIMES(name, sample) do {} while (0)
129 #define DHISTOGRAM_COUNTS(name, sample) do {} while (0)
130 #define DHISTOGRAM_PERCENTAGE(name, under_one_hundred) do {} while (0)
131 #define DHISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \
133 #define DHISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) \
135 #define DHISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \
137 #define DHISTOGRAM_ENUMERATION(name, sample, boundary_value) do {} while (0)
138 #define DHISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \
143 //------------------------------------------------------------------------------
144 // The following macros provide typical usage scenarios for callers that wish
145 // to record histogram data, and have the data submitted/uploaded via UMA.
146 // Not all systems support such UMA, but if they do, the following macros
147 // should work with the service.
149 #define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \
150 name, sample, base::TimeDelta::FromMilliseconds(1), \
151 base::TimeDelta::FromSeconds(10), 50)
153 #define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \
154 name, sample, base::TimeDelta::FromMilliseconds(10), \
155 base::TimeDelta::FromMinutes(3), 50)
157 // Use this macro when times can routinely be much longer than 10 seconds.
158 #define UMA_HISTOGRAM_LONG_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \
159 name, sample, base::TimeDelta::FromMilliseconds(1), \
160 base::TimeDelta::FromHours(1), 50)
162 #define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \
163 static scoped_refptr<Histogram> counter = Histogram::FactoryTimeGet( \
164 name, min, max, bucket_count, Histogram::kUmaTargetedHistogramFlag); \
165 DCHECK_EQ(name, counter->histogram_name()); \
166 if (counter.get()) counter->AddTime(sample); \
169 // DO NOT USE THIS. It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES.
170 #define UMA_HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \
171 static scoped_refptr<Histogram> counter = Histogram::FactoryTimeGet( \
172 name, min, max, bucket_count, Histogram::kUmaTargetedHistogramFlag); \
173 DCHECK_EQ(name, counter->histogram_name()); \
174 if ((sample) < (max) && counter.get()) counter->AddTime(sample); \
177 #define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
178 name, sample, 1, 1000000, 50)
180 #define UMA_HISTOGRAM_COUNTS_100(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
181 name, sample, 1, 100, 50)
183 #define UMA_HISTOGRAM_COUNTS_10000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
184 name, sample, 1, 10000, 50)
186 #define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \
187 static scoped_refptr<Histogram> counter = Histogram::FactoryGet( \
188 name, min, max, bucket_count, Histogram::kUmaTargetedHistogramFlag); \
189 DCHECK_EQ(name, counter->histogram_name()); \
190 if (counter.get()) counter->Add(sample); \
193 #define UMA_HISTOGRAM_MEMORY_KB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
194 name, sample, 1000, 500000, 50)
196 #define UMA_HISTOGRAM_MEMORY_MB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
197 name, sample, 1, 1000, 50)
199 #define UMA_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \
200 UMA_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101)
202 #define UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \
203 static scoped_refptr<Histogram> counter = LinearHistogram::FactoryGet( \
204 name, 1, boundary_value, boundary_value + 1, \
205 Histogram::kUmaTargetedHistogramFlag); \
206 DCHECK_EQ(name, counter->histogram_name()); \
207 if (counter.get()) counter->Add(sample); \
210 #define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) do { \
211 static scoped_refptr<Histogram> counter = CustomHistogram::FactoryGet( \
212 name, custom_ranges, Histogram::kUmaTargetedHistogramFlag); \
213 DCHECK_EQ(name, counter->histogram_name()); \
214 if (counter.get()) counter->Add(sample); \
217 //------------------------------------------------------------------------------
219 class BooleanHistogram
;
220 class CustomHistogram
;
222 class LinearHistogram
;
225 namespace disk_cache
{
226 class StatsHistogram
;
227 }; // namespace disk_cache
230 class Histogram
: public base::RefCountedThreadSafe
<Histogram
> {
232 typedef int Sample
; // Used for samples (and ranges of samples).
233 typedef int Count
; // Used to count samples in a bucket.
234 static const Sample kSampleType_MAX
= INT_MAX
;
236 typedef std::vector
<Count
> Counts
;
237 typedef std::vector
<Sample
> Ranges
;
239 /* These enums are meant to facilitate deserialization of renderer histograms
246 NOT_VALID_IN_RENDERER
257 kUmaTargetedHistogramFlag
= 0x1, // Histogram should be UMA uploaded.
259 // Indicate that the histogram was pickled to be sent across an IPC Channel.
260 // If we observe this flag on a histogram being aggregated into after IPC,
261 // then we are running in a single process mode, and the aggregation should
262 // not take place (as we would be aggregating back into the source
264 kIPCSerializationSourceFlag
= 0x10,
266 kHexRangePrintingFlag
= 0x8000, // Fancy bucket-naming supported.
269 struct DescriptionPair
{
271 const char* description
; // Null means end of a list of pairs.
274 //----------------------------------------------------------------------------
275 // Statistic values, developed over the life of the histogram.
279 explicit SampleSet();
280 // Adjust size of counts_ for use with given histogram.
281 void Resize(const Histogram
& histogram
);
282 void CheckSize(const Histogram
& histogram
) const;
284 // Accessor for histogram to make routine additions.
285 void Accumulate(Sample value
, Count count
, size_t index
);
288 Count
counts(size_t i
) const { return counts_
[i
]; }
289 Count
TotalCount() const;
290 int64
sum() const { return sum_
; }
291 int64
square_sum() const { return square_sum_
; }
293 // Arithmetic manipulation of corresponding elements of the set.
294 void Add(const SampleSet
& other
);
295 void Subtract(const SampleSet
& other
);
297 bool Serialize(Pickle
* pickle
) const;
298 bool Deserialize(void** iter
, const Pickle
& pickle
);
301 // Actual histogram data is stored in buckets, showing the count of values
302 // that fit into each bucket.
305 // Save simple stats locally. Note that this MIGHT get done in base class
306 // without shared memory at some point.
307 int64 sum_
; // sum of samples.
308 int64 square_sum_
; // sum of squares of samples.
310 //----------------------------------------------------------------------------
311 // minimum should start from 1. 0 is invalid as a minimum. 0 is an implicit
312 // default underflow bucket.
313 static scoped_refptr
<Histogram
> FactoryGet(const std::string
& name
,
314 Sample minimum
, Sample maximum
, size_t bucket_count
, Flags flags
);
315 static scoped_refptr
<Histogram
> FactoryTimeGet(const std::string
& name
,
316 base::TimeDelta minimum
, base::TimeDelta maximum
, size_t bucket_count
,
321 // This method is an interface, used only by BooleanHistogram.
322 virtual void AddBoolean(bool value
);
324 // Accept a TimeDelta to increment.
325 void AddTime(base::TimeDelta time
) {
326 Add(static_cast<int>(time
.InMilliseconds()));
329 void AddSampleSet(const SampleSet
& sample
);
331 // This method is an interface, used only by LinearHistogram.
332 virtual void SetRangeDescriptions(const DescriptionPair descriptions
[]);
334 // The following methods provide graphical histogram displays.
335 void WriteHTMLGraph(std::string
* output
) const;
336 void WriteAscii(bool graph_it
, const std::string
& newline
,
337 std::string
* output
) const;
339 // Support generic flagging of Histograms.
340 // 0x1 Currently used to mark this histogram to be recorded by UMA..
341 // 0x8000 means print ranges in hex.
342 void SetFlags(Flags flags
) { flags_
= static_cast<Flags
> (flags_
| flags
); }
343 void ClearFlags(Flags flags
) { flags_
= static_cast<Flags
>(flags_
& ~flags
); }
344 int flags() const { return flags_
; }
346 // Convenience methods for serializing/deserializing the histograms.
347 // Histograms from Renderer process are serialized and sent to the browser.
348 // Browser process reconstructs the histogram from the pickled version
349 // accumulates the browser-side shadow copy of histograms (that mirror
350 // histograms created in the renderer).
352 // Serialize the given snapshot of a Histogram into a String. Uses
353 // Pickle class to flatten the object.
354 static std::string
SerializeHistogramInfo(const Histogram
& histogram
,
355 const SampleSet
& snapshot
);
356 // The following method accepts a list of pickled histograms and
357 // builds a histogram and updates shadow copy of histogram data in the
359 static bool DeserializeHistogramInfo(const std::string
& histogram_info
);
361 //----------------------------------------------------------------------------
362 // Accessors for factory constuction, serialization and testing.
363 //----------------------------------------------------------------------------
364 virtual ClassType
histogram_type() const { return HISTOGRAM
; }
365 const std::string
& histogram_name() const { return histogram_name_
; }
366 Sample
declared_min() const { return declared_min_
; }
367 Sample
declared_max() const { return declared_max_
; }
368 virtual Sample
ranges(size_t i
) const { return ranges_
[i
];}
369 virtual size_t bucket_count() const { return bucket_count_
; }
370 // Snapshot the current complete set of sample data.
371 // Override with atomic/locked snapshot if needed.
372 virtual void SnapshotSample(SampleSet
* sample
) const;
374 virtual bool HasConstructorArguments(Sample minimum
, Sample maximum
,
375 size_t bucket_count
);
377 virtual bool HasConstructorTimeDeltaArguments(base::TimeDelta minimum
,
378 base::TimeDelta maximum
,
379 size_t bucket_count
);
382 friend class base::RefCountedThreadSafe
<Histogram
>;
383 Histogram(const std::string
& name
, Sample minimum
,
384 Sample maximum
, size_t bucket_count
);
385 Histogram(const std::string
& name
, base::TimeDelta minimum
,
386 base::TimeDelta maximum
, size_t bucket_count
);
388 virtual ~Histogram();
390 // Method to override to skip the display of the i'th bucket if it's empty.
391 virtual bool PrintEmptyBucket(size_t index
) const;
393 //----------------------------------------------------------------------------
394 // Methods to override to create histogram with different bucket widths.
395 //----------------------------------------------------------------------------
396 // Initialize ranges_ mapping.
397 virtual void InitializeBucketRange();
398 // Find bucket to increment for sample value.
399 virtual size_t BucketIndex(Sample value
) const;
400 // Get normalized size, relative to the ranges_[i].
401 virtual double GetBucketSize(Count current
, size_t i
) const;
403 // Return a string description of what goes in a given bucket.
404 // Most commonly this is the numeric value, but in derived classes it may
405 // be a name (or string description) given to the bucket.
406 virtual const std::string
GetAsciiBucketRange(size_t it
) const;
408 //----------------------------------------------------------------------------
409 // Methods to override to create thread safe histogram.
410 //----------------------------------------------------------------------------
411 // Update all our internal data, including histogram
412 virtual void Accumulate(Sample value
, Count count
, size_t index
);
414 //----------------------------------------------------------------------------
415 // Accessors for derived classes.
416 //----------------------------------------------------------------------------
417 void SetBucketRange(size_t i
, Sample value
);
419 // Validate that ranges_ was created sensibly (top and bottom range
420 // values relate properly to the declared_min_ and declared_max_)..
421 bool ValidateBucketRanges() const;
424 // Post constructor initialization.
427 //----------------------------------------------------------------------------
428 // Helpers for emitting Ascii graphic. Each method appends data to output.
430 // Find out how large the (graphically) the largest bucket will appear to be.
431 double GetPeakBucketSize(const SampleSet
& snapshot
) const;
433 // Write a common header message describing this histogram.
434 void WriteAsciiHeader(const SampleSet
& snapshot
,
435 Count sample_count
, std::string
* output
) const;
437 // Write information about previous, current, and next buckets.
438 // Information such as cumulative percentage, etc.
439 void WriteAsciiBucketContext(const int64 past
, const Count current
,
440 const int64 remaining
, const size_t i
,
441 std::string
* output
) const;
443 // Write textual description of the bucket contents (relative to histogram).
444 // Output is the count in the buckets, as well as the percentage.
445 void WriteAsciiBucketValue(Count current
, double scaled_sum
,
446 std::string
* output
) const;
448 // Produce actual graph (set of blank vs non blank char's) for a bucket.
449 void WriteAsciiBucketGraph(double current_size
, double max_size
,
450 std::string
* output
) const;
452 //----------------------------------------------------------------------------
453 // Invariant values set at/near construction time
455 // ASCII version of original name given to the constructor. All identically
456 // named instances will be coalesced cross-project.
457 const std::string histogram_name_
;
458 Sample declared_min_
; // Less than this goes into counts_[0]
459 Sample declared_max_
; // Over this goes into counts_[bucket_count_ - 1].
460 size_t bucket_count_
; // Dimension of counts_[].
462 // Flag the histogram for recording by UMA via metric_services.h.
465 // For each index, show the least value that can be stored in the
466 // corresponding bucket. We also append one extra element in this array,
467 // containing kSampleType_MAX, to make calculations easy.
468 // The dimension of ranges_ is bucket_count + 1.
471 // Finally, provide the state that changes with the addition of each new
475 DISALLOW_COPY_AND_ASSIGN(Histogram
);
478 //------------------------------------------------------------------------------
480 // LinearHistogram is a more traditional histogram, with evenly spaced
482 class LinearHistogram
: public Histogram
{
484 virtual ClassType
histogram_type() const;
486 // Store a list of number/text values for use in rendering the histogram.
487 // The last element in the array has a null in its "description" slot.
488 virtual void SetRangeDescriptions(const DescriptionPair descriptions
[]);
490 /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit
491 default underflow bucket. */
492 static scoped_refptr
<Histogram
> FactoryGet(const std::string
& name
,
493 Sample minimum
, Sample maximum
, size_t bucket_count
, Flags flags
);
494 static scoped_refptr
<Histogram
> FactoryTimeGet(const std::string
& name
,
495 base::TimeDelta minimum
, base::TimeDelta maximum
, size_t bucket_count
,
499 LinearHistogram(const std::string
& name
, Sample minimum
,
500 Sample maximum
, size_t bucket_count
);
502 LinearHistogram(const std::string
& name
, base::TimeDelta minimum
,
503 base::TimeDelta maximum
, size_t bucket_count
);
505 // Initialize ranges_ mapping.
506 virtual void InitializeBucketRange();
507 virtual double GetBucketSize(Count current
, size_t i
) const;
509 // If we have a description for a bucket, then return that. Otherwise
510 // let parent class provide a (numeric) description.
511 virtual const std::string
GetAsciiBucketRange(size_t i
) const;
513 // Skip printing of name for numeric range if we have a name (and if this is
515 virtual bool PrintEmptyBucket(size_t index
) const;
518 // For some ranges, we store a printable description of a bucket range.
519 // If there is no desciption, then GetAsciiBucketRange() uses parent class
520 // to provide a description.
521 typedef std::map
<Sample
, std::string
> BucketDescriptionMap
;
522 BucketDescriptionMap bucket_description_
;
524 DISALLOW_COPY_AND_ASSIGN(LinearHistogram
);
527 //------------------------------------------------------------------------------
529 // BooleanHistogram is a histogram for booleans.
530 class BooleanHistogram
: public LinearHistogram
{
532 static scoped_refptr
<Histogram
> FactoryGet(const std::string
& name
,
535 virtual ClassType
histogram_type() const;
537 virtual void AddBoolean(bool value
);
540 explicit BooleanHistogram(const std::string
& name
);
542 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram
);
545 //------------------------------------------------------------------------------
547 // CustomHistogram is a histogram for a set of custom integers.
548 class CustomHistogram
: public Histogram
{
550 virtual ClassType
histogram_type() const;
552 static scoped_refptr
<Histogram
> FactoryGet(const std::string
& name
,
553 const std::vector
<int>& custom_ranges
, Flags flags
);
556 CustomHistogram(const std::string
& name
,
557 const std::vector
<int>& custom_ranges
);
559 // Initialize ranges_ mapping.
560 virtual void InitializeBucketRange();
561 virtual double GetBucketSize(Count current
, size_t i
) const;
564 // Temporary pointer used during construction/initialization, and then NULLed.
565 const std::vector
<int>* ranges_vector_
;
567 DISALLOW_COPY_AND_ASSIGN(CustomHistogram
);
570 //------------------------------------------------------------------------------
571 // StatisticsRecorder handles all histograms in the system. It provides a
572 // general place for histograms to register, and supports a global API for
573 // accessing (i.e., dumping, or graphing) the data in all the histograms.
575 class StatisticsRecorder
{
577 typedef std::vector
<scoped_refptr
<Histogram
> > Histograms
;
579 StatisticsRecorder();
581 ~StatisticsRecorder();
583 // Find out if histograms can now be registered into our list.
584 static bool WasStarted();
586 // Register, or add a new histogram to the collection of statistics.
587 static void Register(Histogram
* histogram
);
589 // Methods for printing histograms. Only histograms which have query as
590 // a substring are written to output (an empty string will process all
591 // registered histograms).
592 static void WriteHTMLGraph(const std::string
& query
, std::string
* output
);
593 static void WriteGraph(const std::string
& query
, std::string
* output
);
595 // Method for extracting histograms which were marked for use by UMA.
596 static void GetHistograms(Histograms
* output
);
598 // Find a histogram by name. It matches the exact name. This method is thread
599 // safe. If a matching histogram is not found, then the |histogram| is
601 static bool FindHistogram(const std::string
& query
,
602 scoped_refptr
<Histogram
>* histogram
);
604 static bool dump_on_exit() { return dump_on_exit_
; }
606 static void set_dump_on_exit(bool enable
) { dump_on_exit_
= enable
; }
608 // GetSnapshot copies some of the pointers to registered histograms into the
609 // caller supplied vector (Histograms). Only histograms with names matching
610 // query are returned. The query must be a substring of histogram name for its
611 // pointer to be copied.
612 static void GetSnapshot(const std::string
& query
, Histograms
* snapshot
);
616 // We keep all registered histograms in a map, from name to histogram.
617 typedef std::map
<std::string
, scoped_refptr
<Histogram
> > HistogramMap
;
619 static HistogramMap
* histograms_
;
621 // lock protects access to the above map.
624 // Dump all known histograms to log.
625 static bool dump_on_exit_
;
627 DISALLOW_COPY_AND_ASSIGN(StatisticsRecorder
);
630 #endif // BASE_HISTOGRAM_H_