chromium/components/nacl/renderer/histogram.cc

// Copyright 2014 The Chromium Authors
// 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 <algorithm>

#include "base/metrics/histogram.h"
#include "build/build_config.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 BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  os_arch = kNaClLinux32;
#endif

  if (sandbox_isa == "x86-64")
    os_arch = static_cast<NaClOSArch>(os_arch + 1);
  if (sandbox_isa == "arm")
    os_arch = static_cast<NaClOSArch>(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::Milliseconds(1), base::Milliseconds(20000), 100,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  if (counter)
    counter->AddTime(base::Milliseconds(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::Milliseconds(10), base::Milliseconds(200000), 100,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  if (counter)
    counter->AddTime(base::Milliseconds(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::Milliseconds(100), base::Milliseconds(2000000), 100,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  if (counter)
    counter->AddTime(base::Milliseconds(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::Milliseconds(10), base::Milliseconds(720000), 100,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  if (counter)
    counter->AddTime(base::Milliseconds(sample_ms));
}

void HistogramStartupTimeSmall(const std::string& name,
                               base::TimeDelta td,
                               int64_t nexe_size) {
  HistogramTimeSmall(name, static_cast<int64_t>(td.InMilliseconds()));
  if (nexe_size > 0) {
    float size_in_MB = static_cast<float>(nexe_size) / (1024.f * 1024.f);
    HistogramTimeSmall(name + "PerMB",
                       static_cast<int64_t>(td.InMilliseconds() / size_in_MB));
  }
}

void HistogramStartupTimeMedium(const std::string& name,
                                base::TimeDelta td,
                                int64_t nexe_size) {
  HistogramTimeMedium(name, static_cast<int64_t>(td.InMilliseconds()));
  if (nexe_size > 0) {
    float size_in_MB = static_cast<float>(nexe_size) / (1024.f * 1024.f);
    HistogramTimeMedium(name + "PerMB",
                        static_cast<int64_t>(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<int32_t>(100 * numerator / denominator),
                        kRatioMin, kRatioMax, kRatioBuckets);
}

}  // namespace nacl