1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_NET_CHROME_NET_LOG_H_ 6 #define CHROME_BROWSER_NET_CHROME_NET_LOG_H_ 7 #pragma once 8 9 #include <vector> 10 11 #include "base/atomicops.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/observer_list.h" 14 #include "base/synchronization/lock.h" 15 #include "base/time.h" 16 #include "net/base/net_log.h" 17 18 class LoadTimingObserver; 19 class NetLogLogger; 20 class PassiveLogCollector; 21 22 // ChromeNetLog is an implementation of NetLog that dispatches network log 23 // messages to a list of observers. 24 // 25 // All methods are thread safe, with the exception that no ChromeNetLog or 26 // ChromeNetLog::ThreadSafeObserver functions may be called by an observer's 27 // OnAddEntry() method. Doing so will result in a deadlock. 28 // 29 // By default, ChromeNetLog will attach the observer PassiveLogCollector which 30 // will keep track of recent request information (which used when displaying 31 // the about:net-internals page). 32 // 33 class ChromeNetLog : public net::NetLog { 34 public: 35 // This structure encapsulates all of the parameters of an event, 36 // including an "order" field that identifies when it was captured relative 37 // to other events. 38 struct Entry { 39 Entry(uint32 order, 40 net::NetLog::EventType type, 41 const base::TimeTicks& time, 42 net::NetLog::Source source, 43 net::NetLog::EventPhase phase, 44 net::NetLog::EventParameters* params); 45 ~Entry(); 46 47 uint32 order; 48 net::NetLog::EventType type; 49 base::TimeTicks time; 50 net::NetLog::Source source; 51 net::NetLog::EventPhase phase; 52 scoped_refptr<net::NetLog::EventParameters> params; 53 }; 54 55 typedef std::vector<Entry> EntryList; 56 57 // Interface for observing the events logged by the network stack. 58 class ThreadSafeObserver { 59 public: 60 // Constructs an observer that wants to see network events, with 61 // the specified minimum event granularity. A ThreadSafeObserver can only 62 // observe a single ChromeNetLog at a time. 63 // 64 // Typical observers should specify LOG_BASIC. 65 // 66 // Observers that need to see the full granularity of events can 67 // specify LOG_ALL. However doing so will have performance consequences, 68 // and may cause PassiveLogCollector to use more memory than anticipated. 69 // 70 // Observers will be called on the same thread an entry is added on, 71 // and are responsible for ensuring their own thread safety. 72 explicit ThreadSafeObserver(LogLevel log_level); 73 74 virtual ~ThreadSafeObserver(); 75 76 // This method will be called on the thread that the event occurs on. It 77 // is the responsibility of the observer to handle it in a thread safe 78 // manner. 79 // 80 // It is illegal for an Observer to call any ChromeNetLog or 81 // ChromeNetLog::ThreadSafeObserver functions in response to a call to 82 // OnAddEntry. 83 virtual void OnAddEntry(EventType type, 84 const base::TimeTicks& time, 85 const Source& source, 86 EventPhase phase, 87 EventParameters* params) = 0; 88 LogLevel log_level() const; 89 90 protected: 91 void AssertNetLogLockAcquired() const; 92 93 // Can only be called when actively observing a ChromeNetLog. 94 void SetLogLevel(LogLevel log_level); 95 96 // ChromeNetLog currently being observed, if any. Set by ChromeNetLog's 97 // AddObserver and RemoveObserver methods. 98 ChromeNetLog* net_log_; 99 100 private: 101 friend class ChromeNetLog; 102 LogLevel log_level_; 103 DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver); 104 }; 105 106 ChromeNetLog(); 107 ~ChromeNetLog(); 108 109 // NetLog implementation: 110 virtual void AddEntry(EventType type, 111 const base::TimeTicks& time, 112 const Source& source, 113 EventPhase phase, 114 EventParameters* params); 115 virtual uint32 NextID(); 116 virtual LogLevel GetLogLevel() const; 117 118 void AddObserver(ThreadSafeObserver* observer); 119 void RemoveObserver(ThreadSafeObserver* observer); 120 121 // Adds |observer| and writes all passively captured events to 122 // |passive_entries|. Guarantees that no events in |passive_entries| will be 123 // sent to |observer| and all future events that have yet been sent to the 124 // PassiveLogCollector will be sent to |observer|. 125 void AddObserverAndGetAllPassivelyCapturedEvents(ThreadSafeObserver* observer, 126 EntryList* passive_entries); 127 128 void GetAllPassivelyCapturedEvents(EntryList* passive_entries); 129 130 void ClearAllPassivelyCapturedEvents(); 131 load_timing_observer()132 LoadTimingObserver* load_timing_observer() { 133 return load_timing_observer_.get(); 134 } 135 136 private: 137 void AddObserverWhileLockHeld(ThreadSafeObserver* observer); 138 139 // Called whenever an observer is added or removed, or changes its log level. 140 // Must have acquired |lock_| prior to calling. 141 void UpdateLogLevel_(); 142 143 // |lock_| protects access to |observers_| and, indirectly, to 144 // |passive_collector_|. Should not be acquired by observers. 145 base::Lock lock_; 146 147 // Last assigned source ID. Incremented to get the next one. 148 base::subtle::Atomic32 last_id_; 149 150 base::subtle::Atomic32 log_level_; 151 152 // Not thread safe. Must only be used when |lock_| is acquired. 153 scoped_ptr<PassiveLogCollector> passive_collector_; 154 155 scoped_ptr<LoadTimingObserver> load_timing_observer_; 156 scoped_ptr<NetLogLogger> net_log_logger_; 157 158 // |lock_| must be acquired whenever reading or writing to this. 159 ObserverList<ThreadSafeObserver, true> observers_; 160 161 DISALLOW_COPY_AND_ASSIGN(ChromeNetLog); 162 }; 163 164 #endif // CHROME_BROWSER_NET_CHROME_NET_LOG_H_ 165