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