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