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