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 const HistogramBase::Sample HistogramBase::kSampleType_MAX = INT_MAX; 62 63 HistogramBase::HistogramBase(const std::string& name) 64 : histogram_name_(name), 65 flags_(kNoFlags) {} 66 67 HistogramBase::~HistogramBase() {} 68 69 void HistogramBase::SetFlags(int32 flags) { 70 flags_ |= flags; 71 } 72 73 void HistogramBase::ClearFlags(int32 flags) { 74 flags_ &= ~flags; 75 } 76 77 void HistogramBase::AddTime(const TimeDelta& time) { 78 Add(static_cast<Sample>(time.InMilliseconds())); 79 } 80 81 void HistogramBase::AddBoolean(bool value) { 82 Add(value ? 1 : 0); 83 } 84 85 bool HistogramBase::SerializeInfo(Pickle* pickle) const { 86 if (!pickle->WriteInt(GetHistogramType())) 87 return false; 88 return SerializeInfoImpl(pickle); 89 } 90 91 int HistogramBase::FindCorruption(const HistogramSamples& samples) const { 92 // Not supported by default. 93 return NO_INCONSISTENCIES; 94 } 95 96 void HistogramBase::WriteJSON(std::string* output) const { 97 Count count; 98 int64 sum; 99 scoped_ptr<ListValue> buckets(new ListValue()); 100 GetCountAndBucketData(&count, &sum, buckets.get()); 101 scoped_ptr<DictionaryValue> parameters(new DictionaryValue()); 102 GetParameters(parameters.get()); 103 104 JSONStringValueSerializer serializer(output); 105 DictionaryValue root; 106 root.SetString("name", histogram_name()); 107 root.SetInteger("count", count); 108 root.SetDouble("sum", sum); 109 root.SetInteger("flags", flags()); 110 root.Set("params", parameters.release()); 111 root.Set("buckets", buckets.release()); 112 root.SetInteger("pid", GetCurrentProcId()); 113 serializer.Serialize(root); 114 } 115 116 void HistogramBase::WriteAsciiBucketGraph(double current_size, 117 double max_size, 118 std::string* output) const { 119 const int k_line_length = 72; // Maximal horizontal width of graph. 120 int x_count = static_cast<int>(k_line_length * (current_size / max_size) 121 + 0.5); 122 int x_remainder = k_line_length - x_count; 123 124 while (0 < x_count--) 125 output->append("-"); 126 output->append("O"); 127 while (0 < x_remainder--) 128 output->append(" "); 129 } 130 131 const std::string HistogramBase::GetSimpleAsciiBucketRange( 132 Sample sample) const { 133 std::string result; 134 if (kHexRangePrintingFlag & flags()) 135 StringAppendF(&result, "%#x", sample); 136 else 137 StringAppendF(&result, "%d", sample); 138 return result; 139 } 140 141 void HistogramBase::WriteAsciiBucketValue(Count current, 142 double scaled_sum, 143 std::string* output) const { 144 StringAppendF(output, " (%d = %3.1f%%)", current, current/scaled_sum); 145 } 146 147 } // namespace base 148