• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/serialization/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 
MetricSample(MetricSample::SampleType sample_type,const std::string & metric_name,int sample,int min,int max,int bucket_count)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 
~MetricSample()31 MetricSample::~MetricSample() {
32 }
33 
IsValid() const34 bool MetricSample::IsValid() const {
35   return name().find(' ') == std::string::npos &&
36          name().find('\0') == std::string::npos && !name().empty();
37 }
38 
ToString() const39 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 
sample() const77 const int MetricSample::sample() const {
78   CHECK_NE(type_, USER_ACTION);
79   CHECK_NE(type_, CRASH);
80   return sample_;
81 }
82 
min() const83 const int MetricSample::min() const {
84   CHECK_EQ(type_, HISTOGRAM);
85   return min_;
86 }
87 
max() const88 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 
bucket_count() const95 const int MetricSample::bucket_count() const {
96   CHECK_EQ(type_, HISTOGRAM);
97   return bucket_count_;
98 }
99 
100 // static
CrashSample(const std::string & crash_name)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
HistogramSample(const std::string & histogram_name,int sample,int min,int max,int bucket_count)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
ParseHistogram(const std::string & serialized_histogram)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
SparseHistogramSample(const std::string & histogram_name,int sample)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
ParseSparseHistogram(const std::string & serialized_histogram)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
LinearHistogramSample(const std::string & histogram_name,int sample,int max)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
ParseLinearHistogram(const std::string & serialized_histogram)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
UserActionSample(const std::string & action_name)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 
IsEqual(const MetricSample & metric)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