blob: 2d22034dbadb7b2ee6c22cde9e9f345e28809fea [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright 2016 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.
-->
<link rel="import" href="/tracing/metrics/metric_registry.html">
<link rel="import" href="/tracing/model/helpers/chrome_model_helper.html">
<link rel="import" href="/tracing/model/helpers/chrome_renderer_helper.html">
<link rel="import" href="/tracing/value/diagnostics/alert_groups.html">
<link rel="import" href="/tracing/value/histogram.html">
<script>
'use strict';
tr.exportTo('tr.metrics.sh', function() {
// Use a lower bound of 0.01 for the metric boundaries (when no CPU time
// is consumed) and an upper bound of 50 (fifty cores are all active
// for the entire time). We can't use zero exactly for the lower bound with an
// exponential histogram.
const CPU_TIME_PERCENTAGE_BOUNDARIES =
tr.v.HistogramBinBoundaries.createExponential(0.01, 50, 200);
/**
* This metric measures total CPU time for Chrome processes, per second of
* clock time.
* This metric requires only the 'toplevel' tracing category.
*
* @param {!tr.v.HistogramSet} histograms
* @param {!tr.model.Model} model
* @param {!Object=} opt_options
*/
function cpuTimeMetric(histograms, model, opt_options) {
let rangeOfInterest = model.bounds;
if (opt_options && opt_options.rangeOfInterest) {
rangeOfInterest = opt_options.rangeOfInterest;
} else {
// If no range of interest is provided, limit the relevant range to
// Chrome processes. This prevents us from normalizing against non-Chrome
// related slices in the trace.
const chromeHelper = model.getOrCreateHelper(
tr.model.helpers.ChromeModelHelper);
if (chromeHelper) {
const chromeBounds = chromeHelper.chromeBounds;
if (chromeBounds) {
rangeOfInterest = chromeBounds;
}
}
}
let allProcessCpuTime = 0;
for (const pid in model.processes) {
const process = model.processes[pid];
if (tr.model.helpers.ChromeRendererHelper.isTracingProcess(process)) {
continue;
}
let processCpuTime = 0;
for (const tid in process.threads) {
const thread = process.threads[tid];
processCpuTime += thread.getCpuTimeForRange(rangeOfInterest);
}
allProcessCpuTime += processCpuTime;
}
// Normalize cpu time by clock time.
let normalizedAllProcessCpuTime = 0;
if (rangeOfInterest.duration > 0) {
normalizedAllProcessCpuTime =
allProcessCpuTime / rangeOfInterest.duration;
}
const unit = tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;
const cpuTimeHist = new tr.v.Histogram(
'cpu_time_percentage', unit, CPU_TIME_PERCENTAGE_BOUNDARIES);
cpuTimeHist.description =
'Percent CPU utilization, normalized against a single core. Can be ' +
'greater than 100% if machine has multiple cores.';
cpuTimeHist.setAlertGrouping([tr.v.d.ALERT_GROUPS.CPU_USAGE]);
cpuTimeHist.customizeSummaryOptions({
avg: true,
count: false,
max: false,
min: false,
std: false,
sum: false
});
cpuTimeHist.addSample(normalizedAllProcessCpuTime);
histograms.addHistogram(cpuTimeHist);
}
tr.metrics.MetricRegistry.register(cpuTimeMetric, {
supportsRangeOfInterest: true
});
return {
cpuTimeMetric,
};
});
</script>