Home | History | Annotate | Download | only in chromeos
      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