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/nacl/renderer/histogram.h"
6 
7 #include <algorithm>
8 
9 #include "base/metrics/histogram.h"
10 
11 namespace nacl {
12 
HistogramCustomCounts(const std::string & name,int32_t sample,int32_t min,int32_t max,uint32_t bucket_count)13 void HistogramCustomCounts(const std::string& name,
14                            int32_t sample,
15                            int32_t min,
16                            int32_t max,
17                            uint32_t bucket_count) {
18   base::HistogramBase* counter =
19       base::Histogram::FactoryGet(
20           name,
21           min,
22           max,
23           bucket_count,
24           base::HistogramBase::kUmaTargetedHistogramFlag);
25   // The histogram can be NULL if it is constructed with bad arguments.  Ignore
26   // that data for this API.  An error message will be logged.
27   if (counter)
28     counter->Add(sample);
29 }
30 
HistogramEnumerate(const std::string & name,int32_t sample,int32_t boundary_value)31 void HistogramEnumerate(const std::string& name,
32                         int32_t sample,
33                         int32_t boundary_value) {
34   base::HistogramBase* counter =
35       base::LinearHistogram::FactoryGet(
36           name,
37           1,
38           boundary_value,
39           boundary_value + 1,
40           base::HistogramBase::kUmaTargetedHistogramFlag);
41   counter->Add(sample);
42 }
43 
HistogramEnumerateLoadStatus(PP_NaClError error_code,bool is_installed)44 void HistogramEnumerateLoadStatus(PP_NaClError error_code,
45                                   bool is_installed) {
46   HistogramEnumerate("NaCl.LoadStatus.Plugin", error_code, PP_NACL_ERROR_MAX);
47 
48   // Gather data to see if being installed changes load outcomes.
49   const char* name = is_installed ?
50       "NaCl.LoadStatus.Plugin.InstalledApp" :
51       "NaCl.LoadStatus.Plugin.NotInstalledApp";
52   HistogramEnumerate(name, error_code, PP_NACL_ERROR_MAX);
53 }
54 
HistogramEnumerateOsArch(const std::string & sandbox_isa)55 void HistogramEnumerateOsArch(const std::string& sandbox_isa) {
56   enum NaClOSArch {
57     kNaClLinux32 = 0,
58     kNaClLinux64,
59     kNaClLinuxArm,
60     kNaClMac32,
61     kNaClMac64,
62     kNaClMacArm,
63     kNaClWin32,
64     kNaClWin64,
65     kNaClWinArm,
66     kNaClLinuxMips,
67     kNaClOSArchMax
68   };
69 
70   NaClOSArch os_arch = kNaClOSArchMax;
71 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
72   os_arch = kNaClLinux32;
73 #elif defined(OS_MAC)
74   os_arch = kNaClMac32;
75 #elif defined(OS_WIN)
76   os_arch = kNaClWin32;
77 #endif
78 
79   if (sandbox_isa == "x86-64")
80     os_arch = static_cast<NaClOSArch>(os_arch + 1);
81   if (sandbox_isa == "arm")
82     os_arch = static_cast<NaClOSArch>(os_arch + 2);
83   if (sandbox_isa == "mips32")
84     os_arch = kNaClLinuxMips;
85 
86   HistogramEnumerate("NaCl.Client.OSArch", os_arch, kNaClOSArchMax);
87 }
88 
89 // Records values up to 20 seconds.
HistogramTimeSmall(const std::string & name,int64_t sample)90 void HistogramTimeSmall(const std::string& name, int64_t sample) {
91   if (sample < 0)
92     sample = 0;
93   base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
94       name,
95       base::TimeDelta::FromMilliseconds(1),
96       base::TimeDelta::FromMilliseconds(20000),
97       100,
98       base::HistogramBase::kUmaTargetedHistogramFlag);
99   if (counter)
100     counter->AddTime(base::TimeDelta::FromMilliseconds(sample));
101 }
102 
103 // Records values up to 3 minutes, 20 seconds.
HistogramTimeMedium(const std::string & name,int64_t sample)104 void HistogramTimeMedium(const std::string& name, int64_t sample) {
105   if (sample < 0)
106     sample = 0;
107   base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
108       name,
109       base::TimeDelta::FromMilliseconds(10),
110       base::TimeDelta::FromMilliseconds(200000),
111       100,
112       base::HistogramBase::kUmaTargetedHistogramFlag);
113   if (counter)
114     counter->AddTime(base::TimeDelta::FromMilliseconds(sample));
115 }
116 
117 // Records values up to 33 minutes.
HistogramTimeLarge(const std::string & name,int64_t sample)118 void HistogramTimeLarge(const std::string& name, int64_t sample) {
119   if (sample < 0)
120     sample = 0;
121   base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
122       name,
123       base::TimeDelta::FromMilliseconds(100),
124       base::TimeDelta::FromMilliseconds(2000000),
125       100,
126       base::HistogramBase::kUmaTargetedHistogramFlag);
127   if (counter)
128     counter->AddTime(base::TimeDelta::FromMilliseconds(sample));
129 }
130 
131 // Records values up to 12 minutes.
HistogramTimeTranslation(const std::string & name,int64_t sample_ms)132 void HistogramTimeTranslation(const std::string& name, int64_t sample_ms) {
133   if (sample_ms < 0)
134     sample_ms = 0;
135   base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
136       name,
137       base::TimeDelta::FromMilliseconds(10),
138       base::TimeDelta::FromMilliseconds(720000),
139       100,
140       base::HistogramBase::kUmaTargetedHistogramFlag);
141   if (counter)
142     counter->AddTime(base::TimeDelta::FromMilliseconds(sample_ms));
143 }
144 
HistogramStartupTimeSmall(const std::string & name,base::TimeDelta td,int64_t nexe_size)145 void HistogramStartupTimeSmall(const std::string& name,
146                                base::TimeDelta td,
147                                int64_t nexe_size) {
148   HistogramTimeSmall(name, static_cast<int64_t>(td.InMilliseconds()));
149   if (nexe_size > 0) {
150     float size_in_MB = static_cast<float>(nexe_size) / (1024.f * 1024.f);
151     HistogramTimeSmall(name + "PerMB",
152                        static_cast<int64_t>(td.InMilliseconds() / size_in_MB));
153   }
154 }
155 
HistogramStartupTimeMedium(const std::string & name,base::TimeDelta td,int64_t nexe_size)156 void HistogramStartupTimeMedium(const std::string& name,
157                                 base::TimeDelta td,
158                                 int64_t nexe_size) {
159   HistogramTimeMedium(name, static_cast<int64_t>(td.InMilliseconds()));
160   if (nexe_size > 0) {
161     float size_in_MB = static_cast<float>(nexe_size) / (1024.f * 1024.f);
162     HistogramTimeMedium(name + "PerMB",
163                         static_cast<int64_t>(td.InMilliseconds() / size_in_MB));
164   }
165 }
166 
HistogramSizeKB(const std::string & name,int32_t sample)167 void HistogramSizeKB(const std::string& name, int32_t sample) {
168   if (sample < 0) return;
169   HistogramCustomCounts(name,
170                         sample,
171                         1,
172                         512 * 1024,  // A very large .nexe.
173                         100);
174 }
175 
HistogramHTTPStatusCode(const std::string & name,int32_t status)176 void HistogramHTTPStatusCode(const std::string& name,
177                              int32_t status) {
178   // Log the status codes in rough buckets - 1XX, 2XX, etc.
179   int sample = status / 100;
180   // HTTP status codes only go up to 5XX, using "6" to indicate an internal
181   // error.
182   // Note: installed files may have "0" for a status code.
183   if (status < 0 || status >= 600)
184     sample = 6;
185   HistogramEnumerate(name, sample, 7);
186 }
187 
HistogramEnumerateManifestIsDataURI(bool is_data_uri)188 void HistogramEnumerateManifestIsDataURI(bool is_data_uri) {
189   HistogramEnumerate("NaCl.Manifest.IsDataURI", is_data_uri, 2);
190 }
191 
HistogramKBPerSec(const std::string & name,int64_t kb,int64_t us)192 void HistogramKBPerSec(const std::string& name, int64_t kb, int64_t us) {
193   if (kb < 0 || us <= 0) return;
194   static const double kMaxRate = 30 * 1000.0;  // max of 30MB/sec.
195   int32_t rate = std::min(kb / (us / 1000000.0), kMaxRate);
196   HistogramCustomCounts(name,
197                         rate,
198                         1,
199                         30 * 1000,  // max of 30 MB/sec.
200                         100);
201 }
202 
HistogramRatio(const std::string & name,int64_t numerator,int64_t denominator)203 void HistogramRatio(const std::string& name,
204                     int64_t numerator,
205                     int64_t denominator) {
206   static const int32_t kRatioMin = 10;
207   static const int32_t kRatioMax = 10 * 100;  // max of 10x difference.
208   static const uint32_t kRatioBuckets = 100;
209   if (numerator < 0 || denominator <= 0)
210     return;
211   HistogramCustomCounts(name,
212                         static_cast<int32_t>(100 * numerator / denominator),
213                         kRatioMin, kRatioMax, kRatioBuckets);
214 }
215 
216 }  // namespace nacl
217