1<!DOCTYPE html>
2<!--
3Copyright 2016 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/metrics/metric_registry.html">
9<link rel="import" href="/tracing/value/numeric.html">
10<link rel="import" href="/tracing/value/value.html">
11
12<script>
13'use strict';
14
15tr.exportTo('tr.metrics', function() {
16
17  function tracingMetric(valueList, model) {
18    if (!model.stats.hasEventSizesinBytes) {
19      throw new Error('Model stats does not have event size information. ' +
20                      'Please enable ImportOptions.trackDetailedModelStats.');
21    }
22
23    var eventStats = model.stats.allTraceEventStatsInTimeIntervals;
24    eventStats.sort(function(a, b) {
25      return a.timeInterval - b.timeInterval;
26    });
27
28    var maxEventCountPerSec = 0;
29    var maxEventBytesPerSec = 0;
30    var totalTraceBytes = 0;
31
32    var WINDOW_SIZE = Math.floor(1000 / model.stats.TIME_INTERVAL_SIZE_IN_MS);
33    var runningEventNumPerSec = 0;
34    var runningEventBytesPerSec = 0;
35    var start = 0;
36    var end = 0;
37    while (end < eventStats.length) {
38      var startEventStats = eventStats[start];
39      var endEventStats = eventStats[end];
40      var timeWindow =
41          endEventStats.timeInterval - startEventStats.timeInterval;
42      if (timeWindow >= WINDOW_SIZE) {
43        runningEventNumPerSec -= startEventStats.numEvents;
44        runningEventBytesPerSec -= startEventStats.totalEventSizeinBytes;
45        start++;
46        continue;
47      }
48
49      runningEventNumPerSec += endEventStats.numEvents;
50      if (maxEventCountPerSec < runningEventNumPerSec)
51        maxEventCountPerSec = runningEventNumPerSec;
52
53      runningEventBytesPerSec += endEventStats.totalEventSizeinBytes;
54      if (maxEventBytesPerSec < runningEventBytesPerSec)
55        maxEventBytesPerSec = runningEventBytesPerSec;
56
57      totalTraceBytes += endEventStats.totalEventSizeinBytes;
58
59      end++;
60    }
61
62    var stats = model.stats.allTraceEventStats;
63    var categoryStatsMap = new Map();
64    var categoryStats = [];
65    for (var i = 0; i < stats.length; i++) {
66      var categoryStat = categoryStatsMap.get(stats[i].category);
67      if (categoryStat === undefined) {
68        categoryStat = {
69          category: stats[i].category,
70          totalEventSizeinBytes: 0
71        };
72        categoryStatsMap.set(stats[i].category, categoryStat);
73        categoryStats.push(categoryStat);
74      }
75      categoryStat.totalEventSizeinBytes += stats[i].totalEventSizeinBytes;
76    }
77    var maxCategoryStats = categoryStats.reduce(function(a, b) {
78      return a.totalEventSizeinBytes < b.totalEventSizeinBytes ? b : a;
79    });
80    var maxEventBytesPerCategory = maxCategoryStats.totalEventSizeinBytes;
81    var maxCategoryName = maxCategoryStats.category;
82
83    var maxEventCountPerSecValue = new tr.v.ScalarNumeric(
84        tr.v.Unit.byName.unitlessNumber_smallerIsBetter, maxEventCountPerSec);
85    var maxEventBytesPerSecValue = new tr.v.ScalarNumeric(
86        tr.v.Unit.byName.sizeInBytes_smallerIsBetter, maxEventBytesPerSec);
87    var totalTraceBytesValue = new tr.v.ScalarNumeric(
88        tr.v.Unit.byName.sizeInBytes_smallerIsBetter, totalTraceBytes);
89
90    var diagnostics = {
91      category_with_max_event_size: {
92        name: maxCategoryName,
93        size_in_bytes: maxEventBytesPerCategory
94      }
95    };
96
97    valueList.addValue(new tr.v.NumericValue(
98        model.canonicalUrlThatCreatedThisTrace,
99        'Total trace size in bytes',
100        totalTraceBytesValue,
101        undefined, undefined, diagnostics));
102    valueList.addValue(new tr.v.NumericValue(
103        model.canonicalUrlThatCreatedThisTrace,
104        'Max number of events per second',
105        maxEventCountPerSecValue,
106        undefined, undefined, diagnostics));
107    valueList.addValue(new tr.v.NumericValue(
108        model.canonicalUrlThatCreatedThisTrace,
109        'Max event size in bytes per second',
110        maxEventBytesPerSecValue,
111        undefined, undefined, diagnostics));
112  }
113
114  tracingMetric.prototype = {
115    __proto__: Function.prototype
116  };
117
118  tr.metrics.MetricRegistry.register(tracingMetric);
119
120  return {
121    tracingMetric: tracingMetric
122  };
123
124});
125</script>
126