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