1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/metrics/serialization/metric_sample.h" 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string> 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <vector> 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_split.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/stringprintf.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace metrics { 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MetricSample::MetricSample(MetricSample::SampleType sample_type, 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& metric_name, 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int sample, 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int min, 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int max, 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int bucket_count) 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : type_(sample_type), 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) name_(metric_name), 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample_(sample), 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) min_(min), 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) max_(max), 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bucket_count_(bucket_count) { 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MetricSample::~MetricSample() { 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool MetricSample::IsValid() const { 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return name().find(' ') == std::string::npos && 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) name().find('\0') == std::string::npos && !name().empty(); 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string MetricSample::ToString() const { 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (type_ == CRASH) { 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return base::StringPrintf("crash%c%s%c", 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '\0', 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) name().c_str(), 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '\0'); 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (type_ == SPARSE_HISTOGRAM) { 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return base::StringPrintf("sparsehistogram%c%s %d%c", 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '\0', 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) name().c_str(), 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample_, 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '\0'); 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (type_ == LINEAR_HISTOGRAM) { 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return base::StringPrintf("linearhistogram%c%s %d %d%c", 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '\0', 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) name().c_str(), 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample_, 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) max_, 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '\0'); 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (type_ == HISTOGRAM) { 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return base::StringPrintf("histogram%c%s %d %d %d %d%c", 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '\0', 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) name().c_str(), 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample_, 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) min_, 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) max_, 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bucket_count_, 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '\0'); 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The type can only be USER_ACTION. 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_EQ(type_, USER_ACTION); 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return base::StringPrintf("useraction%c%s%c", 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '\0', 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) name().c_str(), 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '\0'); 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int MetricSample::sample() const { 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_NE(type_, USER_ACTION); 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_NE(type_, CRASH); 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return sample_; 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int MetricSample::min() const { 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_EQ(type_, HISTOGRAM); 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return min_; 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int MetricSample::max() const { 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_NE(type_, CRASH); 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_NE(type_, USER_ACTION); 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_NE(type_, SPARSE_HISTOGRAM); 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return max_; 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int MetricSample::bucket_count() const { 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_EQ(type_, HISTOGRAM); 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return bucket_count_; 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<MetricSample> MetricSample::CrashSample( 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& crash_name) { 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>( 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new MetricSample(CRASH, crash_name, 0, 0, 0, 0)); 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<MetricSample> MetricSample::HistogramSample( 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& histogram_name, 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int sample, 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int min, 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int max, 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int bucket_count) { 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>(new MetricSample( 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HISTOGRAM, histogram_name, sample, min, max, bucket_count)); 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<MetricSample> MetricSample::ParseHistogram( 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& serialized_histogram) { 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string> parts; 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::SplitString(serialized_histogram, ' ', &parts); 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (parts.size() != 5) 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>(); 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int sample, min, max, bucket_count; 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (parts[0].empty() || !base::StringToInt(parts[1], &sample) || 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !base::StringToInt(parts[2], &min) || 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !base::StringToInt(parts[3], &max) || 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !base::StringToInt(parts[4], &bucket_count)) { 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>(); 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return HistogramSample(parts[0], sample, min, max, bucket_count); 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<MetricSample> MetricSample::SparseHistogramSample( 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& histogram_name, 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int sample) { 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>( 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new MetricSample(SPARSE_HISTOGRAM, histogram_name, sample, 0, 0, 0)); 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<MetricSample> MetricSample::ParseSparseHistogram( 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& serialized_histogram) { 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string> parts; 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::SplitString(serialized_histogram, ' ', &parts); 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (parts.size() != 2) 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>(); 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int sample; 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (parts[0].empty() || !base::StringToInt(parts[1], &sample)) 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>(); 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return SparseHistogramSample(parts[0], sample); 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<MetricSample> MetricSample::LinearHistogramSample( 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& histogram_name, 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int sample, 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int max) { 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>( 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new MetricSample(LINEAR_HISTOGRAM, histogram_name, sample, 0, max, 0)); 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<MetricSample> MetricSample::ParseLinearHistogram( 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& serialized_histogram) { 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string> parts; 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int sample, max; 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::SplitString(serialized_histogram, ' ', &parts); 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (parts.size() != 3) 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>(); 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (parts[0].empty() || !base::StringToInt(parts[1], &sample) || 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !base::StringToInt(parts[2], &max)) { 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>(); 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return LinearHistogramSample(parts[0], sample, max); 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<MetricSample> MetricSample::UserActionSample( 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& action_name) { 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<MetricSample>( 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new MetricSample(USER_ACTION, action_name, 0, 0, 0, 0)); 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool MetricSample::IsEqual(const MetricSample& metric) { 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return type_ == metric.type_ && name_ == metric.name_ && 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample_ == metric.sample_ && min_ == metric.min_ && 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) max_ == metric.max_ && bucket_count_ == metric.bucket_count_; 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace metrics 198