| // Copyright (c) 2011 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. |
| |
| #ifndef CHROME_BROWSER_NET_CHROME_NET_LOG_H_ |
| #define CHROME_BROWSER_NET_CHROME_NET_LOG_H_ |
| #pragma once |
| |
| #include <vector> |
| |
| #include "base/atomicops.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/observer_list.h" |
| #include "base/synchronization/lock.h" |
| #include "base/time.h" |
| #include "net/base/net_log.h" |
| |
| class LoadTimingObserver; |
| class NetLogLogger; |
| class PassiveLogCollector; |
| |
| // ChromeNetLog is an implementation of NetLog that dispatches network log |
| // messages to a list of observers. |
| // |
| // All methods are thread safe, with the exception that no ChromeNetLog or |
| // ChromeNetLog::ThreadSafeObserver functions may be called by an observer's |
| // OnAddEntry() method. Doing so will result in a deadlock. |
| // |
| // By default, ChromeNetLog will attach the observer PassiveLogCollector which |
| // will keep track of recent request information (which used when displaying |
| // the about:net-internals page). |
| // |
| class ChromeNetLog : public net::NetLog { |
| public: |
| // This structure encapsulates all of the parameters of an event, |
| // including an "order" field that identifies when it was captured relative |
| // to other events. |
| struct Entry { |
| Entry(uint32 order, |
| net::NetLog::EventType type, |
| const base::TimeTicks& time, |
| net::NetLog::Source source, |
| net::NetLog::EventPhase phase, |
| net::NetLog::EventParameters* params); |
| ~Entry(); |
| |
| uint32 order; |
| net::NetLog::EventType type; |
| base::TimeTicks time; |
| net::NetLog::Source source; |
| net::NetLog::EventPhase phase; |
| scoped_refptr<net::NetLog::EventParameters> params; |
| }; |
| |
| typedef std::vector<Entry> EntryList; |
| |
| // Interface for observing the events logged by the network stack. |
| class ThreadSafeObserver { |
| public: |
| // Constructs an observer that wants to see network events, with |
| // the specified minimum event granularity. A ThreadSafeObserver can only |
| // observe a single ChromeNetLog at a time. |
| // |
| // Typical observers should specify LOG_BASIC. |
| // |
| // Observers that need to see the full granularity of events can |
| // specify LOG_ALL. However doing so will have performance consequences, |
| // and may cause PassiveLogCollector to use more memory than anticipated. |
| // |
| // Observers will be called on the same thread an entry is added on, |
| // and are responsible for ensuring their own thread safety. |
| explicit ThreadSafeObserver(LogLevel log_level); |
| |
| virtual ~ThreadSafeObserver(); |
| |
| // This method will be called on the thread that the event occurs on. It |
| // is the responsibility of the observer to handle it in a thread safe |
| // manner. |
| // |
| // It is illegal for an Observer to call any ChromeNetLog or |
| // ChromeNetLog::ThreadSafeObserver functions in response to a call to |
| // OnAddEntry. |
| virtual void OnAddEntry(EventType type, |
| const base::TimeTicks& time, |
| const Source& source, |
| EventPhase phase, |
| EventParameters* params) = 0; |
| LogLevel log_level() const; |
| |
| protected: |
| void AssertNetLogLockAcquired() const; |
| |
| // Can only be called when actively observing a ChromeNetLog. |
| void SetLogLevel(LogLevel log_level); |
| |
| // ChromeNetLog currently being observed, if any. Set by ChromeNetLog's |
| // AddObserver and RemoveObserver methods. |
| ChromeNetLog* net_log_; |
| |
| private: |
| friend class ChromeNetLog; |
| LogLevel log_level_; |
| DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver); |
| }; |
| |
| ChromeNetLog(); |
| ~ChromeNetLog(); |
| |
| // NetLog implementation: |
| virtual void AddEntry(EventType type, |
| const base::TimeTicks& time, |
| const Source& source, |
| EventPhase phase, |
| EventParameters* params); |
| virtual uint32 NextID(); |
| virtual LogLevel GetLogLevel() const; |
| |
| void AddObserver(ThreadSafeObserver* observer); |
| void RemoveObserver(ThreadSafeObserver* observer); |
| |
| // Adds |observer| and writes all passively captured events to |
| // |passive_entries|. Guarantees that no events in |passive_entries| will be |
| // sent to |observer| and all future events that have yet been sent to the |
| // PassiveLogCollector will be sent to |observer|. |
| void AddObserverAndGetAllPassivelyCapturedEvents(ThreadSafeObserver* observer, |
| EntryList* passive_entries); |
| |
| void GetAllPassivelyCapturedEvents(EntryList* passive_entries); |
| |
| void ClearAllPassivelyCapturedEvents(); |
| |
| LoadTimingObserver* load_timing_observer() { |
| return load_timing_observer_.get(); |
| } |
| |
| private: |
| void AddObserverWhileLockHeld(ThreadSafeObserver* observer); |
| |
| // Called whenever an observer is added or removed, or changes its log level. |
| // Must have acquired |lock_| prior to calling. |
| void UpdateLogLevel_(); |
| |
| // |lock_| protects access to |observers_| and, indirectly, to |
| // |passive_collector_|. Should not be acquired by observers. |
| base::Lock lock_; |
| |
| // Last assigned source ID. Incremented to get the next one. |
| base::subtle::Atomic32 last_id_; |
| |
| base::subtle::Atomic32 log_level_; |
| |
| // Not thread safe. Must only be used when |lock_| is acquired. |
| scoped_ptr<PassiveLogCollector> passive_collector_; |
| |
| scoped_ptr<LoadTimingObserver> load_timing_observer_; |
| scoped_ptr<NetLogLogger> net_log_logger_; |
| |
| // |lock_| must be acquired whenever reading or writing to this. |
| ObserverList<ThreadSafeObserver, true> observers_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ChromeNetLog); |
| }; |
| |
| #endif // CHROME_BROWSER_NET_CHROME_NET_LOG_H_ |