blob: c858a8bcb2d74936d816f3177929a3489b231b3f [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/value/histogram.html">
<script>
'use strict';
tr.exportTo('tr.metrics.sh', function() {
function getCpuSnapshotsFromModel(model) {
const snapshots = [];
for (const pid in model.processes) {
const snapshotInstances =
model.processes[pid].objects.getAllInstancesNamed('CPUSnapshots');
if (!snapshotInstances) continue;
for (const object of snapshotInstances[0].snapshots) {
snapshots.push(object.args.processes);
}
}
return snapshots;
}
function getProcessSumsFromSnapshot(snapshot) {
const processSums = new Map();
for (const processData of snapshot) {
const processName = processData.name;
if (!(processSums.has(processName))) {
processSums.set(processName, {sum: 0.0, paths: new Set()});
}
processSums.get(processName).sum += parseFloat(processData.pCpu);
// The process path may be missing on Windows because of AccessDenied
// error thrown by psutil package used by CPU tracing agent.
if (processData.path) {
processSums.get(processName).paths.add(processData.path);
}
}
return processSums;
}
function buildNumericsFromSnapshots(snapshots) {
const processNumerics = new Map();
for (const snapshot of snapshots) {
const processSums = getProcessSumsFromSnapshot(snapshot);
for (const [processName, processData] of processSums.entries()) {
if (!(processNumerics.has(processName))) {
processNumerics.set(processName, {
numeric: new tr.v.Histogram('cpu:percent:' + processName,
tr.b.Unit.byName.normalizedPercentage_smallerIsBetter),
paths: new Set()
});
}
processNumerics.get(processName).numeric.addSample(
processData.sum / 100.0);
for (const path of processData.paths) {
processNumerics.get(processName).paths.add(path);
}
}
}
return processNumerics;
}
function cpuProcessMetric(histograms, model) {
const snapshots = getCpuSnapshotsFromModel(model);
const processNumerics = buildNumericsFromSnapshots(snapshots);
for (const [processName, processData] of processNumerics) {
const numeric = processData.numeric;
// Treat missing snapshots as zeros. A process is missing from a snapshots
// when its CPU usage was below minimum threshold when the snapshot was
// taken.
const missingSnapshotCount = snapshots.length - numeric.numValues;
for (let i = 0; i < missingSnapshotCount; i++) {
numeric.addSample(0);
}
numeric.diagnostics.set('paths', new
tr.v.d.GenericSet([...processData.paths]));
histograms.addHistogram(numeric);
}
}
tr.metrics.MetricRegistry.register(cpuProcessMetric);
return {
cpuProcessMetric,
};
});
</script>