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