OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_BASE_LOAD_LOG_H_ | 5 #ifndef NET_BASE_NET_LOG_H_ |
6 #define NET_BASE_LOAD_LOG_H_ | 6 #define NET_BASE_NET_LOG_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/ref_counted.h" | 11 #include "base/scoped_ptr.h" |
12 #include "base/time.h" | 12 #include "base/time.h" |
| 13 #include "net/base/net_log.h" |
13 | 14 |
14 namespace net { | 15 namespace net { |
15 | 16 |
16 // LoadLog stores information associated with an individual request. This | 17 // NetLog is the destination for log messages generated by the network stack. |
17 // includes event traces (used to build up profiling information), error | 18 // Each log message has a "source" field which identifies the specific entity |
18 // return codes from network modules, and arbitrary text messages. | 19 // that generated the message (for example, which URLRequest or which |
| 20 // SocketStream). |
19 // | 21 // |
20 // Note that LoadLog is NOT THREADSAFE, however it is RefCountedThreadSafe so | 22 // To avoid needing to pass in the "source id" to the logging functions, NetLog |
21 // that it can be AddRef() / Release() across threads. | 23 // is usually accessed through a BoundNetLog, which will always pass in a |
22 class LoadLog : public base::RefCountedThreadSafe<LoadLog> { | 24 // specific source ID. |
| 25 // |
| 26 // Note that NetLog is NOT THREADSAFE. |
| 27 class NetLog { |
23 public: | 28 public: |
24 // TODO(eroman): Really, EventType and EventPhase should be | 29 // TODO(eroman): Really, EventType and EventPhase should be |
25 // Event::Type and Event::Phase, to be consisent with Entry. | 30 // Event::Type and Event::Phase, to be consisent with Entry. |
26 // But there lots of consumers to change! | 31 // But there lots of consumers to change! |
27 enum EventType { | 32 enum EventType { |
28 #define EVENT_TYPE(label) TYPE_ ## label, | 33 #define EVENT_TYPE(label) TYPE_ ## label, |
29 #include "net/base/load_log_event_type_list.h" | 34 #include "net/base/net_log_event_type_list.h" |
30 #undef EVENT_TYPE | 35 #undef EVENT_TYPE |
31 }; | 36 }; |
32 | 37 |
33 // The 'phase' of an event trace (whether it marks the beginning or end | 38 // The 'phase' of an event trace (whether it marks the beginning or end |
34 // of an event.). | 39 // of an event.). |
35 enum EventPhase { | 40 enum EventPhase { |
36 PHASE_NONE, | 41 PHASE_NONE, |
37 PHASE_BEGIN, | 42 PHASE_BEGIN, |
38 // TODO(eroman): DEPRECATED: Use TYPE_STRING_LITERAL instead. | |
39 PHASE_END, | 43 PHASE_END, |
40 }; | 44 }; |
41 | 45 |
42 struct Event { | 46 struct Event { |
43 Event(EventType type, EventPhase phase) : type(type), phase(phase) {} | 47 Event(EventType type, EventPhase phase) : type(type), phase(phase) {} |
44 Event() {} | 48 Event() {} |
45 | 49 |
46 EventType type; | 50 EventType type; |
47 EventPhase phase; | 51 EventPhase phase; |
48 }; | 52 }; |
49 | 53 |
| 54 // The "source" identifies the entity that generated the log message. |
| 55 enum SourceType { |
| 56 SOURCE_NONE, |
| 57 SOURCE_URL_REQUEST, |
| 58 SOURCE_SOCKET_STREAM, |
| 59 SOURCE_INIT_PROXY_RESOLVER, |
| 60 SOURCE_CONNECT_JOB, |
| 61 }; |
| 62 |
| 63 // Identifies the entity that generated this log. The |id| field should |
| 64 // uniquely identify the source, and is used by log observers to infer |
| 65 // message groupings. Can use NetLog::NextID() to create unique IDs. |
| 66 struct Source { |
| 67 Source() : type(SOURCE_NONE), id(-1) {} |
| 68 Source(SourceType type, int id) : type(type), id(id) {} |
| 69 |
| 70 SourceType type; |
| 71 int id; |
| 72 }; |
| 73 |
| 74 // TODO(eroman): generalize the entries so events can specify multiple |
| 75 // parameters, and TYPE_STRING is rarely needed. |
50 struct Entry { | 76 struct Entry { |
51 enum Type { | 77 enum Type { |
52 // This entry describes an event trace. | 78 // This entry describes an event trace. |
53 TYPE_EVENT, | 79 TYPE_EVENT, |
54 | 80 |
55 // This entry describes a network error code that was returned. | 81 // This entry describes a network error code that was returned. |
56 TYPE_ERROR_CODE, | 82 TYPE_ERROR_CODE, |
57 | 83 |
58 // This entry is a free-form std::string. | 84 // This entry is a free-form std::string. |
59 TYPE_STRING, | 85 TYPE_STRING, |
60 | 86 |
61 // This entry is a C-string literal. | 87 // This entry is a C-string literal. |
62 TYPE_STRING_LITERAL, | 88 TYPE_STRING_LITERAL, |
63 }; | 89 }; |
64 | 90 |
65 Entry(base::TimeTicks time, int error_code) | 91 Source source; |
66 : type(TYPE_ERROR_CODE), time(time), error_code(error_code) { | |
67 } | |
68 | |
69 Entry(base::TimeTicks time, const Event& event) | |
70 : type(TYPE_EVENT), time(time), event(event) { | |
71 } | |
72 | |
73 Entry(base::TimeTicks time, const std::string& string) | |
74 : type(TYPE_STRING), time(time), string(string) { | |
75 } | |
76 | |
77 Entry(base::TimeTicks time, const char* literal) | |
78 : type(TYPE_STRING_LITERAL), time(time), literal(literal) { | |
79 } | |
80 | 92 |
81 Type type; | 93 Type type; |
82 base::TimeTicks time; | 94 base::TimeTicks time; |
83 | 95 |
84 // The following is basically a union, only one of them should be | 96 // The following is basically a union, only one of them should be |
85 // used depending on what |type| is. | 97 // used depending on what |type| is. |
86 Event event; // valid when (type == TYPE_EVENT). | 98 Event event; // valid when (type == TYPE_EVENT). |
87 int error_code; // valid when (type == TYPE_ERROR_CODE). | 99 int error_code; // valid when (type == TYPE_ERROR_CODE). |
88 std::string string; // valid when (type == TYPE_STRING). | 100 std::string string; // valid when (type == TYPE_STRING). |
89 const char* literal; // valid when (type == TYPE_STRING_LITERAL). | 101 const char* literal; // valid when (type == TYPE_STRING_LITERAL). |
90 }; | 102 }; |
91 | 103 |
| 104 NetLog() {} |
| 105 virtual ~NetLog() {} |
| 106 |
| 107 // Adds a message to the log. |
| 108 virtual void AddEntry(const Entry& entry) = 0; |
| 109 |
| 110 // Returns a unique ID which can be used as a source ID. |
| 111 virtual int NextID() = 0; |
| 112 |
| 113 // Returns true if more complicated messages should be sent to the log. |
| 114 // TODO(eroman): This is a carry-over from refactoring; figure out |
| 115 // something better. |
| 116 virtual bool HasListener() const = 0; |
| 117 |
| 118 // Returns a C-String symbolic name for |event_type|. |
| 119 static const char* EventTypeToString(EventType event_type); |
| 120 |
| 121 private: |
| 122 DISALLOW_COPY_AND_ASSIGN(NetLog); |
| 123 }; |
| 124 |
| 125 // Helper that binds a Source to a NetLog, and exposes convenience methods to |
| 126 // output log messages without needing to pass in the source. |
| 127 class BoundNetLog { |
| 128 public: |
| 129 BoundNetLog() : net_log_(NULL) {} |
| 130 |
| 131 // TODO(eroman): This is a complete hack to allow passing in NULL in |
| 132 // place of a BoundNetLog. I added this while refactoring to simplify the |
| 133 // task of updating all the callers. |
| 134 BoundNetLog(int) : net_log_(NULL) {} |
| 135 |
| 136 BoundNetLog(const NetLog::Source& source, NetLog* net_log) |
| 137 : source_(source), net_log_(net_log) { |
| 138 } |
| 139 |
| 140 void AddEntry(const NetLog::Entry& entry) const; |
| 141 |
| 142 // Convenience methods that call through to the NetLog, passing in the |
| 143 // currently bound source. |
| 144 void AddEvent(NetLog::EventType event_type) const; |
| 145 bool HasListener() const; |
| 146 void BeginEvent(NetLog::EventType event_type) const; |
| 147 void BeginEventWithString(NetLog::EventType event_type, |
| 148 const std::string& string) const; |
| 149 void AddEventWithInteger(NetLog::EventType event_type, int integer) const; |
| 150 void EndEvent(NetLog::EventType event_type) const; |
| 151 void AddStringLiteral(const char* literal) const; |
| 152 void AddString(const std::string& string) const; |
| 153 void AddErrorCode(int error) const; |
| 154 |
| 155 // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care |
| 156 // of creating a unique source ID, and handles the case of NULL net_log. |
| 157 static BoundNetLog Make(NetLog* net_log, NetLog::SourceType source_type); |
| 158 |
| 159 const NetLog::Source& source() const { return source_; } |
| 160 NetLog* net_log() const { return net_log_; } |
| 161 |
| 162 private: |
| 163 NetLog::Source source_; |
| 164 NetLog* net_log_; |
| 165 }; |
| 166 |
| 167 // CapturingNetLog is an implementation of NetLog that saves messages to a |
| 168 // bounded buffer. |
| 169 class CapturingNetLog : public NetLog { |
| 170 public: |
92 // Ordered set of entries that were logged. | 171 // Ordered set of entries that were logged. |
93 // TODO(eroman): use a StackVector or array to avoid allocations. | |
94 typedef std::vector<Entry> EntryList; | 172 typedef std::vector<Entry> EntryList; |
95 | 173 |
96 // Value for max_num_entries to indicate the LoadLog has no size limit. | 174 enum { kUnbounded = -1 }; |
97 static const size_t kUnbounded = static_cast<size_t>(-1); | |
98 | 175 |
99 // Creates a log, which can hold up to |max_num_entries| entries. | 176 // Creates a CapturingNetLog that logs a maximum of |max_num_entries| |
100 // If |max_num_entries| is |kUnbounded|, then the log can grow arbitrarily | 177 // messages. |
101 // large. | 178 explicit CapturingNetLog(size_t max_num_entries) |
102 // | 179 : next_id_(0), max_num_entries_(max_num_entries) {} |
103 // If entries are dropped because the log has grown too large, the final entry | |
104 // will be overwritten. | |
105 explicit LoadLog(size_t max_num_entries); | |
106 | 180 |
107 // -------------------------------------------------------------------------- | 181 // NetLog implementation: |
| 182 virtual void AddEntry(const Entry& entry); |
| 183 virtual int NextID(); |
| 184 virtual bool HasListener() const { return true; } |
108 | 185 |
109 // The public interface for adding events to the log are static methods. | 186 // Returns the list of all entries in the log. |
110 // This makes it easier to deal with optionally NULL LoadLog. | 187 const EntryList& entries() const { return entries_; } |
111 | 188 |
112 // Adds an instantaneous event to the log. | 189 void Clear(); |
113 // TODO(eroman): DEPRECATED: use AddStringLiteral() instead. | 190 |
114 static void AddEvent(LoadLog* log, EventType event_type) { | 191 private: |
115 if (log) | 192 int next_id_; |
116 log->Add(Entry(base::TimeTicks::Now(), Event(event_type, PHASE_NONE))); | 193 size_t max_num_entries_; |
| 194 EntryList entries_; |
| 195 |
| 196 DISALLOW_COPY_AND_ASSIGN(CapturingNetLog); |
| 197 }; |
| 198 |
| 199 // Helper class that exposes a similar API as BoundNetLog, but uses a |
| 200 // CapturingNetLog rather than the more generic NetLog. |
| 201 // |
| 202 // CapturingBoundNetLog can easily be converted to a BoundNetLog using the |
| 203 // bound() method. |
| 204 class CapturingBoundNetLog { |
| 205 public: |
| 206 CapturingBoundNetLog(const NetLog::Source& source, CapturingNetLog* net_log) |
| 207 : source_(source), capturing_net_log_(net_log) { |
117 } | 208 } |
118 | 209 |
119 // Adds the start of an event to the log. Presumably this event type measures | 210 explicit CapturingBoundNetLog(size_t max_num_entries) |
120 // a time duration, and will be matched by a call to EndEvent(event_type). | 211 : capturing_net_log_(new CapturingNetLog(max_num_entries)) {} |
121 static void BeginEvent(LoadLog* log, EventType event_type) { | 212 |
122 if (log) | 213 // The returned BoundNetLog is only valid while |this| is alive. |
123 log->Add(Entry(base::TimeTicks::Now(), Event(event_type, PHASE_BEGIN))); | 214 BoundNetLog bound() const { |
| 215 return BoundNetLog(source_, capturing_net_log_.get()); |
124 } | 216 } |
125 | 217 |
126 // Adds the end of an event to the log. Presumably this event type measures | 218 // Returns the list of all entries in the log. |
127 // a time duration, and we are matching an earlier call to | 219 const CapturingNetLog::EntryList& entries() const { |
128 // BeginEvent(event_type). | 220 return capturing_net_log_->entries(); |
129 static void EndEvent(LoadLog* log, EventType event_type) { | |
130 if (log) | |
131 log->Add(Entry(base::TimeTicks::Now(), Event(event_type, PHASE_END))); | |
132 } | 221 } |
133 | 222 |
134 // |literal| should be a string literal (i.e. lives in static storage). | 223 void Clear(); |
135 static void AddStringLiteral(LoadLog* log, const char* literal) { | |
136 if (log) | |
137 log->Add(Entry(base::TimeTicks::Now(), literal)); | |
138 } | |
139 | 224 |
140 static void AddString(LoadLog* log, const std::string& string) { | 225 // Sends all of captured messages to |net_log|, using the same source ID |
141 if (log) | 226 // as |net_log|. |
142 log->Add(Entry(base::TimeTicks::Now(), string)); | 227 void AppendTo(const BoundNetLog& net_log) const; |
143 } | |
144 | |
145 static void AddErrorCode(LoadLog* log, int error) { | |
146 if (log) | |
147 log->Add(Entry(base::TimeTicks::Now(), error)); | |
148 } | |
149 | |
150 static bool IsUnbounded(const LoadLog* log) { | |
151 return log && log->is_unbounded(); | |
152 } | |
153 | |
154 // -------------------------------------------------------------------------- | |
155 | |
156 // Returns the list of all entries in the log. | |
157 const EntryList& entries() const { | |
158 return entries_; | |
159 } | |
160 | |
161 // Returns the number of entries that were dropped from the log because the | |
162 // maximum size had been reached. | |
163 size_t num_entries_truncated() const { | |
164 return num_entries_truncated_; | |
165 } | |
166 | |
167 // Returns the bound on the size of the log. | |
168 size_t max_num_entries() const { | |
169 return max_num_entries_; | |
170 } | |
171 | |
172 bool is_unbounded() const { | |
173 return max_num_entries_ == kUnbounded; | |
174 } | |
175 | |
176 // Returns a C-String symbolic name for |event|. | |
177 static const char* EventTypeToString(EventType event_type); | |
178 | |
179 void Add(const Entry& entry); | |
180 | |
181 // Copies all entries from |log|, appending it to the end of |this|. | |
182 void Append(const LoadLog* log); | |
183 | 228 |
184 private: | 229 private: |
185 friend class base::RefCountedThreadSafe<LoadLog>; | 230 NetLog::Source source_; |
| 231 scoped_ptr<CapturingNetLog> capturing_net_log_; |
186 | 232 |
187 ~LoadLog() {} | 233 DISALLOW_COPY_AND_ASSIGN(CapturingBoundNetLog); |
188 | |
189 EntryList entries_; | |
190 size_t num_entries_truncated_; | |
191 size_t max_num_entries_;; | |
192 }; | 234 }; |
193 | 235 |
194 } // namespace net | 236 } // namespace net |
195 | 237 |
196 #endif // NET_BASE_LOAD_LOG_H_ | 238 #endif // NET_BASE_NET_LOG_H_ |
OLD | NEW |