Home | History | Annotate | Download | only in metrics
      1 // Copyright (c) 2012 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.
      4 
      5 #include "base/metrics/histogram_base.h"
      6 
      7 #include <limits.h>
      8 
      9 #include <utility>
     10 
     11 #include "base/json/json_string_value_serializer.h"
     12 #include "base/logging.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/metrics/histogram.h"
     15 #include "base/metrics/histogram_samples.h"
     16 #include "base/metrics/sparse_histogram.h"
     17 #include "base/metrics/statistics_recorder.h"
     18 #include "base/pickle.h"
     19 #include "base/process/process_handle.h"
     20 #include "base/strings/stringprintf.h"
     21 #include "base/values.h"
     22 
     23 namespace base {
     24 
     25 std::string HistogramTypeToString(HistogramType type) {
     26   switch (type) {
     27     case HISTOGRAM:
     28       return "HISTOGRAM";
     29     case LINEAR_HISTOGRAM:
     30       return "LINEAR_HISTOGRAM";
     31     case BOOLEAN_HISTOGRAM:
     32       return "BOOLEAN_HISTOGRAM";
     33     case CUSTOM_HISTOGRAM:
     34       return "CUSTOM_HISTOGRAM";
     35     case SPARSE_HISTOGRAM:
     36       return "SPARSE_HISTOGRAM";
     37     default:
     38       NOTREACHED();
     39   }
     40   return "UNKNOWN";
     41 }
     42 
     43 HistogramBase* DeserializeHistogramInfo(PickleIterator* iter) {
     44   int type;
     45   if (!iter->ReadInt(&type))
     46     return NULL;
     47 
     48   switch (type) {
     49     case HISTOGRAM:
     50       return Histogram::DeserializeInfoImpl(iter);
     51     case LINEAR_HISTOGRAM:
     52       return LinearHistogram::DeserializeInfoImpl(iter);
     53     case BOOLEAN_HISTOGRAM:
     54       return BooleanHistogram::DeserializeInfoImpl(iter);
     55     case CUSTOM_HISTOGRAM:
     56       return CustomHistogram::DeserializeInfoImpl(iter);
     57     case SPARSE_HISTOGRAM:
     58       return SparseHistogram::DeserializeInfoImpl(iter);
     59     default:
     60       return NULL;
     61   }
     62 }
     63 
     64 const HistogramBase::Sample HistogramBase::kSampleType_MAX = INT_MAX;
     65 
     66 HistogramBase::HistogramBase(const std::string& name)
     67     : histogram_name_(name),
     68       flags_(kNoFlags) {}
     69 
     70 HistogramBase::~HistogramBase() {}
     71 
     72 void HistogramBase::CheckName(const StringPiece& name) const {
     73   DCHECK_EQ(histogram_name(), name);
     74 }
     75 
     76 void HistogramBase::SetFlags(int32_t flags) {
     77   HistogramBase::Count old_flags = subtle::NoBarrier_Load(&flags_);
     78   subtle::NoBarrier_Store(&flags_, old_flags | flags);
     79 }
     80 
     81 void HistogramBase::ClearFlags(int32_t flags) {
     82   HistogramBase::Count old_flags = subtle::NoBarrier_Load(&flags_);
     83   subtle::NoBarrier_Store(&flags_, old_flags & ~flags);
     84 }
     85 
     86 void HistogramBase::AddTime(const TimeDelta& time) {
     87   Add(static_cast<Sample>(time.InMilliseconds()));
     88 }
     89 
     90 void HistogramBase::AddBoolean(bool value) {
     91   Add(value ? 1 : 0);
     92 }
     93 
     94 bool HistogramBase::SerializeInfo(Pickle* pickle) const {
     95   if (!pickle->WriteInt(GetHistogramType()))
     96     return false;
     97   return SerializeInfoImpl(pickle);
     98 }
     99 
    100 int HistogramBase::FindCorruption(const HistogramSamples& /* samples */) const {
    101   // Not supported by default.
    102   return NO_INCONSISTENCIES;
    103 }
    104 
    105 void HistogramBase::WriteJSON(std::string* output) const {
    106   Count count;
    107   int64_t sum;
    108   scoped_ptr<ListValue> buckets(new ListValue());
    109   GetCountAndBucketData(&count, &sum, buckets.get());
    110   scoped_ptr<DictionaryValue> parameters(new DictionaryValue());
    111   GetParameters(parameters.get());
    112 
    113   JSONStringValueSerializer serializer(output);
    114   DictionaryValue root;
    115   root.SetString("name", histogram_name());
    116   root.SetInteger("count", count);
    117   root.SetDouble("sum", static_cast<double>(sum));
    118   root.SetInteger("flags", flags());
    119   root.Set("params", std::move(parameters));
    120   root.Set("buckets", std::move(buckets));
    121   root.SetInteger("pid", GetCurrentProcId());
    122   serializer.Serialize(root);
    123 }
    124 
    125 void HistogramBase::FindAndRunCallback(HistogramBase::Sample sample) const {
    126   if ((flags() & kCallbackExists) == 0)
    127     return;
    128 
    129   StatisticsRecorder::OnSampleCallback cb =
    130       StatisticsRecorder::FindCallback(histogram_name());
    131   if (!cb.is_null())
    132     cb.Run(sample);
    133 }
    134 
    135 void HistogramBase::WriteAsciiBucketGraph(double current_size,
    136                                           double max_size,
    137                                           std::string* output) const {
    138   const int k_line_length = 72;  // Maximal horizontal width of graph.
    139   int x_count = static_cast<int>(k_line_length * (current_size / max_size)
    140                                  + 0.5);
    141   int x_remainder = k_line_length - x_count;
    142 
    143   while (0 < x_count--)
    144     output->append("-");
    145   output->append("O");
    146   while (0 < x_remainder--)
    147     output->append(" ");
    148 }
    149 
    150 const std::string HistogramBase::GetSimpleAsciiBucketRange(
    151     Sample sample) const {
    152   std::string result;
    153   if (kHexRangePrintingFlag & flags())
    154     StringAppendF(&result, "%#x", sample);
    155   else
    156     StringAppendF(&result, "%d", sample);
    157   return result;
    158 }
    159 
    160 void HistogramBase::WriteAsciiBucketValue(Count current,
    161                                           double scaled_sum,
    162                                           std::string* output) const {
    163   StringAppendF(output, " (%d = %3.1f%%)", current, current/scaled_sum);
    164 }
    165 
    166 }  // namespace base
    167