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