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
18class LoadTimingObserver;
19class NetLogLogger;
20class 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//
33class 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
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