histogram_base.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram_base.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <climits> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_string_value_serializer.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram_samples.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/sparse_histogram.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/pickle.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/process_util.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/stringprintf.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string HistogramTypeToString(HistogramType type) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(type) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HISTOGRAM: 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "HISTOGRAM"; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case LINEAR_HISTOGRAM: 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "LINEAR_HISTOGRAM"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BOOLEAN_HISTOGRAM: 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "BOOLEAN_HISTOGRAM"; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CUSTOM_HISTOGRAM: 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "CUSTOM_HISTOGRAM"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SPARSE_HISTOGRAM: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "SPARSE_HISTOGRAM"; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "UNKNOWN"; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HistogramBase* DeserializeHistogramInfo(PickleIterator* iter) { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!iter->ReadInt(&type)) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case HISTOGRAM: 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Histogram::DeserializeInfoImpl(iter); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case LINEAR_HISTOGRAM: 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return LinearHistogram::DeserializeInfoImpl(iter); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case BOOLEAN_HISTOGRAM: 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return BooleanHistogram::DeserializeInfoImpl(iter); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case CUSTOM_HISTOGRAM: 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CustomHistogram::DeserializeInfoImpl(iter); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SPARSE_HISTOGRAM: 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SparseHistogram::DeserializeInfoImpl(iter); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeserializeHistogramAndAddSamples(PickleIterator* iter) { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HistogramBase* histogram = DeserializeHistogramInfo(iter); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!histogram) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (histogram->flags() & base::HistogramBase::kIPCSerializationSourceFlag) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Single process mode, histogram observed and not copied: " 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << histogram->histogram_name(); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) histogram->AddSamplesFromPickle(iter); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const HistogramBase::Sample HistogramBase::kSampleType_MAX = INT_MAX; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistogramBase::HistogramBase(const std::string& name) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : histogram_name_(name), 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags_(kNoFlags) {} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistogramBase::~HistogramBase() {} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistogramBase::SetFlags(int32 flags) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags_ |= flags; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistogramBase::ClearFlags(int32 flags) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags_ &= ~flags; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistogramBase::AddTime(const TimeDelta& time) { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Add(static_cast<Sample>(time.InMilliseconds())); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistogramBase::AddBoolean(bool value) { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Add(value ? 1 : 0); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HistogramBase::SerializeInfo(Pickle* pickle) const { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!pickle->WriteInt(GetHistogramType())) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SerializeInfoImpl(pickle); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int HistogramBase::FindCorruption(const HistogramSamples& samples) const { 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Not supported by default. 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NO_INCONSISTENCIES; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistogramBase::WriteJSON(std::string* output) const { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Count count; 112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) int64 sum; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ListValue> buckets(new ListValue()); 114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GetCountAndBucketData(&count, &sum, buckets.get()); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DictionaryValue> parameters(new DictionaryValue()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetParameters(parameters.get()); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JSONStringValueSerializer serializer(output); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue root; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root.SetString("name", histogram_name()); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root.SetInteger("count", count); 122b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) root.SetDouble("sum", sum); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root.SetInteger("flags", flags()); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root.Set("params", parameters.release()); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root.Set("buckets", buckets.release()); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root.SetInteger("pid", GetCurrentProcId()); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) serializer.Serialize(root); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HistogramBase::WriteAsciiBucketGraph(double current_size, 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) double max_size, 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string* output) const { 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int k_line_length = 72; // Maximal horizontal width of graph. 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int x_count = static_cast<int>(k_line_length * (current_size / max_size) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) + 0.5); 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int x_remainder = k_line_length - x_count; 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (0 < x_count--) 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) output->append("-"); 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) output->append("O"); 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (0 < x_remainder--) 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) output->append(" "); 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string HistogramBase::GetSimpleAsciiBucketRange( 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Sample sample) const { 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string result; 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (kHexRangePrintingFlag & flags()) 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringAppendF(&result, "%#x", sample); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringAppendF(&result, "%d", sample); 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return result; 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HistogramBase::WriteAsciiBucketValue(Count current, 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) double scaled_sum, 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string* output) const { 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringAppendF(output, " (%d = %3.1f%%)", current, current/scaled_sum); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 162