1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 var EventsTracker = (function() { 6 'use strict'; 7 8 /** 9 * This class keeps track of all NetLog events. 10 * It receives events from the browser and when loading a log file, and passes 11 * them on to all its observers. 12 * 13 * @constructor 14 */ 15 function EventsTracker() { 16 assertFirstConstructorCall(EventsTracker); 17 18 this.capturedEvents_ = []; 19 this.observers_ = []; 20 21 // Controls how large |capturedEvents_| can grow. 22 this.softLimit_ = Infinity; 23 this.hardLimit_ = Infinity; 24 } 25 26 cr.addSingletonGetter(EventsTracker); 27 28 EventsTracker.prototype = { 29 /** 30 * Returns a list of all captured events. 31 */ 32 getAllCapturedEvents: function() { 33 return this.capturedEvents_; 34 }, 35 36 /** 37 * Returns the number of events that were captured. 38 */ 39 getNumCapturedEvents: function() { 40 return this.capturedEvents_.length; 41 }, 42 43 /** 44 * Deletes all the tracked events, and notifies any observers. 45 */ 46 deleteAllLogEntries: function() { 47 this.capturedEvents_ = []; 48 for (var i = 0; i < this.observers_.length; ++i) 49 this.observers_[i].onAllLogEntriesDeleted(); 50 }, 51 52 /** 53 * Adds captured events, and broadcasts them to any observers. 54 */ 55 addLogEntries: function(logEntries) { 56 // When reloading a page, it's possible to receive events before 57 // Constants. Discard those events, as they can cause the fake 58 // "REQUEST_ALIVE" events for pre-existing requests not be the first 59 // events for those requests. 60 if (Constants == null) 61 return; 62 63 this.capturedEvents_ = this.capturedEvents_.concat(logEntries); 64 for (var i = 0; i < this.observers_.length; ++i) { 65 this.observers_[i].onReceivedLogEntries(logEntries); 66 } 67 68 // Check that we haven't grown too big. If so, toss out older events. 69 if (this.getNumCapturedEvents() > this.hardLimit_) { 70 var originalEvents = this.capturedEvents_; 71 this.deleteAllLogEntries(); 72 // Delete the oldest events until we reach the soft limit. 73 originalEvents.splice(0, originalEvents.length - this.softLimit_); 74 this.addLogEntries(originalEvents); 75 } 76 }, 77 78 /** 79 * Adds a listener of log entries. |observer| will be called back when new 80 * log data arrives or all entries are deleted: 81 * 82 * observer.onReceivedLogEntries(entries) 83 * observer.onAllLogEntriesDeleted() 84 */ 85 addLogEntryObserver: function(observer) { 86 this.observers_.push(observer); 87 }, 88 89 /** 90 * Set bounds on the maximum number of events that will be tracked. This 91 * helps to bound the total amount of memory usage, since otherwise 92 * long-running capture sessions can exhaust the renderer's memory and 93 * crash. 94 * 95 * Once |hardLimit| number of events have been captured we do a garbage 96 * collection and toss out old events, bringing our count down to 97 * |softLimit|. 98 * 99 * To log observers this will look like all the events got deleted, and 100 * then subsequently a bunch of new events were received. In other words, it 101 * behaves the same as if the user had simply started logging a bit later 102 * in time! 103 */ 104 setLimits: function(softLimit, hardLimit) { 105 if (hardLimit != Infinity && softLimit >= hardLimit) 106 throw 'hardLimit must be greater than softLimit'; 107 108 this.softLimit_ = softLimit; 109 this.hardLimit_ = hardLimit; 110 } 111 }; 112 113 return EventsTracker; 114 })(); 115