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