// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/nacl/renderer/histogram.h" #include #include "base/metrics/histogram.h" namespace nacl { void HistogramCustomCounts(const std::string& name, int32_t sample, int32_t min, int32_t max, uint32_t bucket_count) { base::HistogramBase* counter = base::Histogram::FactoryGet( name, min, max, bucket_count, base::HistogramBase::kUmaTargetedHistogramFlag); // The histogram can be NULL if it is constructed with bad arguments. Ignore // that data for this API. An error message will be logged. if (counter) counter->Add(sample); } void HistogramEnumerate(const std::string& name, int32_t sample, int32_t boundary_value) { base::HistogramBase* counter = base::LinearHistogram::FactoryGet( name, 1, boundary_value, boundary_value + 1, base::HistogramBase::kUmaTargetedHistogramFlag); counter->Add(sample); } void HistogramEnumerateLoadStatus(PP_NaClError error_code, bool is_installed) { HistogramEnumerate("NaCl.LoadStatus.Plugin", error_code, PP_NACL_ERROR_MAX); // Gather data to see if being installed changes load outcomes. const char* name = is_installed ? "NaCl.LoadStatus.Plugin.InstalledApp" : "NaCl.LoadStatus.Plugin.NotInstalledApp"; HistogramEnumerate(name, error_code, PP_NACL_ERROR_MAX); } void HistogramEnumerateOsArch(const std::string& sandbox_isa) { enum NaClOSArch { kNaClLinux32 = 0, kNaClLinux64, kNaClLinuxArm, kNaClMac32, kNaClMac64, kNaClMacArm, kNaClWin32, kNaClWin64, kNaClWinArm, kNaClLinuxMips, kNaClOSArchMax }; NaClOSArch os_arch = kNaClOSArchMax; #if OS_LINUX os_arch = kNaClLinux32; #elif OS_MACOSX os_arch = kNaClMac32; #elif OS_WIN os_arch = kNaClWin32; #endif if (sandbox_isa == "x86-64") os_arch = static_cast(os_arch + 1); if (sandbox_isa == "arm") os_arch = static_cast(os_arch + 2); if (sandbox_isa == "mips32") os_arch = kNaClLinuxMips; HistogramEnumerate("NaCl.Client.OSArch", os_arch, kNaClOSArchMax); } // Records values up to 20 seconds. void HistogramTimeSmall(const std::string& name, int64_t sample) { if (sample < 0) sample = 0; base::HistogramBase* counter = base::Histogram::FactoryTimeGet( name, base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMilliseconds(20000), 100, base::HistogramBase::kUmaTargetedHistogramFlag); if (counter) counter->AddTime(base::TimeDelta::FromMilliseconds(sample)); } // Records values up to 3 minutes, 20 seconds. void HistogramTimeMedium(const std::string& name, int64_t sample) { if (sample < 0) sample = 0; base::HistogramBase* counter = base::Histogram::FactoryTimeGet( name, base::TimeDelta::FromMilliseconds(10), base::TimeDelta::FromMilliseconds(200000), 100, base::HistogramBase::kUmaTargetedHistogramFlag); if (counter) counter->AddTime(base::TimeDelta::FromMilliseconds(sample)); } // Records values up to 33 minutes. void HistogramTimeLarge(const std::string& name, int64_t sample) { if (sample < 0) sample = 0; base::HistogramBase* counter = base::Histogram::FactoryTimeGet( name, base::TimeDelta::FromMilliseconds(100), base::TimeDelta::FromMilliseconds(2000000), 100, base::HistogramBase::kUmaTargetedHistogramFlag); if (counter) counter->AddTime(base::TimeDelta::FromMilliseconds(sample)); } // Records values up to 12 minutes. void HistogramTimeTranslation(const std::string& name, int64_t sample_ms) { if (sample_ms < 0) sample_ms = 0; base::HistogramBase* counter = base::Histogram::FactoryTimeGet( name, base::TimeDelta::FromMilliseconds(10), base::TimeDelta::FromMilliseconds(720000), 100, base::HistogramBase::kUmaTargetedHistogramFlag); if (counter) counter->AddTime(base::TimeDelta::FromMilliseconds(sample_ms)); } void HistogramStartupTimeSmall(const std::string& name, base::TimeDelta td, int64_t nexe_size) { HistogramTimeSmall(name, static_cast(td.InMilliseconds())); if (nexe_size > 0) { float size_in_MB = static_cast(nexe_size) / (1024.f * 1024.f); HistogramTimeSmall(name + "PerMB", static_cast(td.InMilliseconds() / size_in_MB)); } } void HistogramStartupTimeMedium(const std::string& name, base::TimeDelta td, int64_t nexe_size) { HistogramTimeMedium(name, static_cast(td.InMilliseconds())); if (nexe_size > 0) { float size_in_MB = static_cast(nexe_size) / (1024.f * 1024.f); HistogramTimeMedium(name + "PerMB", static_cast(td.InMilliseconds() / size_in_MB)); } } void HistogramSizeKB(const std::string& name, int32_t sample) { if (sample < 0) return; HistogramCustomCounts(name, sample, 1, 512 * 1024, // A very large .nexe. 100); } void HistogramHTTPStatusCode(const std::string& name, int32_t status) { // Log the status codes in rough buckets - 1XX, 2XX, etc. int sample = status / 100; // HTTP status codes only go up to 5XX, using "6" to indicate an internal // error. // Note: installed files may have "0" for a status code. if (status < 0 || status >= 600) sample = 6; HistogramEnumerate(name, sample, 7); } void HistogramEnumerateManifestIsDataURI(bool is_data_uri) { HistogramEnumerate("NaCl.Manifest.IsDataURI", is_data_uri, 2); } void HistogramKBPerSec(const std::string& name, int64_t kb, int64_t us) { if (kb < 0 || us <= 0) return; static const double kMaxRate = 30 * 1000.0; // max of 30MB/sec. int32_t rate = std::min(kb / (us / 1000000.0), kMaxRate); HistogramCustomCounts(name, rate, 1, 30 * 1000, // max of 30 MB/sec. 100); } void HistogramRatio(const std::string& name, int64_t numerator, int64_t denominator) { static const int32_t kRatioMin = 10; static const int32_t kRatioMax = 10 * 100; // max of 10x difference. static const uint32_t kRatioBuckets = 100; if (numerator < 0 || denominator <= 0) return; HistogramCustomCounts(name, static_cast(100 * numerator / denominator), kRatioMin, kRatioMax, kRatioBuckets); } } // namespace nacl