OLD | NEW |
| (Empty) |
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 #ifndef NET_BASE_NET_LOG_H_ | |
6 #define NET_BASE_NET_LOG_H_ | |
7 | |
8 #include <string> | |
9 | |
10 #include "base/atomicops.h" | |
11 #include "base/basictypes.h" | |
12 #include "base/callback_forward.h" | |
13 #include "base/compiler_specific.h" | |
14 #include "base/observer_list.h" | |
15 #include "base/strings/string16.h" | |
16 #include "base/synchronization/lock.h" | |
17 #include "base/time/time.h" | |
18 #include "net/base/net_export.h" | |
19 | |
20 namespace base { | |
21 class DictionaryValue; | |
22 class Value; | |
23 } | |
24 | |
25 namespace net { | |
26 | |
27 // NetLog is the destination for log messages generated by the network stack. | |
28 // Each log message has a "source" field which identifies the specific entity | |
29 // that generated the message (for example, which URLRequest or which | |
30 // SpdySession). | |
31 // | |
32 // To avoid needing to pass in the "source ID" to the logging functions, NetLog | |
33 // is usually accessed through a BoundNetLog, which will always pass in a | |
34 // specific source ID. | |
35 // | |
36 // All methods are thread safe, with the exception that no NetLog or | |
37 // NetLog::ThreadSafeObserver functions may be called by an observer's | |
38 // OnAddEntry() method. Doing so will result in a deadlock. | |
39 // | |
40 // For a broader introduction see the design document: | |
41 // https://sites.google.com/a/chromium.org/dev/developers/design-documents/netwo
rk-stack/netlog | |
42 class NET_EXPORT NetLog { | |
43 public: | |
44 enum EventType { | |
45 #define EVENT_TYPE(label) TYPE_ ## label, | |
46 #include "net/base/net_log_event_type_list.h" | |
47 #undef EVENT_TYPE | |
48 EVENT_COUNT | |
49 }; | |
50 | |
51 // The 'phase' of an event trace (whether it marks the beginning or end | |
52 // of an event.). | |
53 enum EventPhase { | |
54 PHASE_NONE, | |
55 PHASE_BEGIN, | |
56 PHASE_END, | |
57 }; | |
58 | |
59 // The "source" identifies the entity that generated the log message. | |
60 enum SourceType { | |
61 #define SOURCE_TYPE(label) SOURCE_ ## label, | |
62 #include "net/base/net_log_source_type_list.h" | |
63 #undef SOURCE_TYPE | |
64 SOURCE_COUNT | |
65 }; | |
66 | |
67 // Specifies the granularity of events that should be emitted to the log. | |
68 // | |
69 // Since the LogLevel may be read and set on any thread without locking, it | |
70 // may be possible for an Observer to receive an event or parameters that | |
71 // normally wouldn't be logged at the currently active log level. | |
72 enum LogLevel { | |
73 // Log everything possible, even if it is slow and memory expensive. | |
74 // Includes logging of transferred bytes. | |
75 LOG_ALL, | |
76 | |
77 // Log all events, but do not include the actual transferred bytes as | |
78 // parameters for bytes sent/received events. | |
79 LOG_ALL_BUT_BYTES, | |
80 | |
81 // Log all events, but do not include the actual transferred bytes and | |
82 // remove cookies and HTTP credentials. | |
83 LOG_STRIP_PRIVATE_DATA, | |
84 | |
85 // Don't log any events. | |
86 LOG_NONE, | |
87 }; | |
88 | |
89 // A callback function that return a Value representation of the parameters | |
90 // associated with an event. If called, it will be called synchonously, | |
91 // so it need not have owning references. May be called more than once, or | |
92 // not at all. May return NULL. | |
93 typedef base::Callback<base::Value*(LogLevel)> ParametersCallback; | |
94 | |
95 // Identifies the entity that generated this log. The |id| field should | |
96 // uniquely identify the source, and is used by log observers to infer | |
97 // message groupings. Can use NetLog::NextID() to create unique IDs. | |
98 struct NET_EXPORT Source { | |
99 static const uint32 kInvalidId; | |
100 | |
101 Source(); | |
102 Source(SourceType type, uint32 id); | |
103 bool IsValid() const; | |
104 | |
105 // Adds the source to a DictionaryValue containing event parameters, | |
106 // using the name "source_dependency". | |
107 void AddToEventParameters(base::DictionaryValue* event_params) const; | |
108 | |
109 // Returns a callback that returns a dictionary with a single entry | |
110 // named "source_dependecy" that describes |this|. | |
111 ParametersCallback ToEventParametersCallback() const; | |
112 | |
113 // Attempts to extract a Source from a set of event parameters. Returns | |
114 // true and writes the result to |source| on success. Returns false and | |
115 // makes |source| an invalid source on failure. | |
116 // TODO(mmenke): Long term, we want to remove this. | |
117 static bool FromEventParameters(base::Value* event_params, Source* source); | |
118 | |
119 SourceType type; | |
120 uint32 id; | |
121 }; | |
122 | |
123 struct NET_EXPORT EntryData { | |
124 EntryData(EventType type, | |
125 Source source, | |
126 EventPhase phase, | |
127 base::TimeTicks time, | |
128 const ParametersCallback* parameters_callback); | |
129 ~EntryData(); | |
130 | |
131 const EventType type; | |
132 const Source source; | |
133 const EventPhase phase; | |
134 const base::TimeTicks time; | |
135 const ParametersCallback* const parameters_callback; | |
136 }; | |
137 | |
138 // An Entry pre-binds EntryData to a LogLevel, so observers will observe the | |
139 // output of ToValue() and ParametersToValue() at their log level rather than | |
140 // current maximum. | |
141 class NET_EXPORT Entry { | |
142 public: | |
143 Entry(const EntryData* data, LogLevel log_level); | |
144 ~Entry(); | |
145 | |
146 EventType type() const { return data_->type; } | |
147 Source source() const { return data_->source; } | |
148 EventPhase phase() const { return data_->phase; } | |
149 | |
150 // Serializes the specified event to a Value. The Value also includes the | |
151 // current time. Caller takes ownership of returned Value. Takes in a time | |
152 // to allow back-dating entries. | |
153 base::Value* ToValue() const; | |
154 | |
155 // Returns the parameters as a Value. Returns NULL if there are no | |
156 // parameters. Caller takes ownership of returned Value. | |
157 base::Value* ParametersToValue() const; | |
158 | |
159 private: | |
160 const EntryData* const data_; | |
161 | |
162 // Log level when the event occurred. | |
163 const LogLevel log_level_; | |
164 | |
165 // It is not safe to copy this class, since |parameters_callback_| may | |
166 // include pointers that become stale immediately after the event is added, | |
167 // even if the code were modified to keep its own copy of the callback. | |
168 DISALLOW_COPY_AND_ASSIGN(Entry); | |
169 }; | |
170 | |
171 // An observer, that must ensure its own thread safety, for events | |
172 // being added to a NetLog. | |
173 class NET_EXPORT ThreadSafeObserver { | |
174 public: | |
175 // Constructs an observer that wants to see network events, with | |
176 // the specified minimum event granularity. A ThreadSafeObserver can only | |
177 // observe a single NetLog at a time. | |
178 // | |
179 // Observers will be called on the same thread an entry is added on, | |
180 // and are responsible for ensuring their own thread safety. | |
181 // | |
182 // Observers must stop watching a NetLog before either the Observer or the | |
183 // NetLog is destroyed. | |
184 ThreadSafeObserver(); | |
185 | |
186 // Returns the minimum log level for events this observer wants to | |
187 // receive. Must not be called when not watching a NetLog. | |
188 LogLevel log_level() const; | |
189 | |
190 // Returns the NetLog we are currently watching, if any. Returns NULL | |
191 // otherwise. | |
192 NetLog* net_log() const; | |
193 | |
194 // This method will be called on the thread that the event occurs on. It | |
195 // is the responsibility of the observer to handle it in a thread safe | |
196 // manner. | |
197 // | |
198 // It is illegal for an Observer to call any NetLog or | |
199 // NetLog::Observer functions in response to a call to OnAddEntry. | |
200 virtual void OnAddEntry(const Entry& entry) = 0; | |
201 | |
202 protected: | |
203 virtual ~ThreadSafeObserver(); | |
204 | |
205 private: | |
206 friend class NetLog; | |
207 | |
208 void OnAddEntryData(const EntryData& entry_data); | |
209 | |
210 // Both of these values are only modified by the NetLog. | |
211 LogLevel log_level_; | |
212 NetLog* net_log_; | |
213 | |
214 DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver); | |
215 }; | |
216 | |
217 NetLog(); | |
218 virtual ~NetLog(); | |
219 | |
220 // Emits a global event to the log stream, with its own unique source ID. | |
221 void AddGlobalEntry(EventType type); | |
222 void AddGlobalEntry(EventType type, | |
223 const NetLog::ParametersCallback& parameters_callback); | |
224 | |
225 // Returns a unique ID which can be used as a source ID. All returned IDs | |
226 // will be unique and greater than 0. | |
227 uint32 NextID(); | |
228 | |
229 // Returns the logging level for this NetLog. This is used to avoid computing | |
230 // and saving expensive log entries. | |
231 LogLevel GetLogLevel() const; | |
232 | |
233 // Adds an observer and sets its log level. The observer must not be | |
234 // watching any NetLog, including this one, when this is called. | |
235 // | |
236 // NetLog implementations must call NetLog::OnAddObserver to update the | |
237 // observer's internal state. | |
238 void AddThreadSafeObserver(ThreadSafeObserver* observer, LogLevel log_level); | |
239 | |
240 // Sets the log level of |observer| to |log_level|. |observer| must be | |
241 // watching |this|. NetLog implementations must call | |
242 // NetLog::OnSetObserverLogLevel to update the observer's internal state. | |
243 void SetObserverLogLevel(ThreadSafeObserver* observer, LogLevel log_level); | |
244 | |
245 // Removes an observer. NetLog implementations must call | |
246 // NetLog::OnAddObserver to update the observer's internal state. | |
247 // | |
248 // For thread safety reasons, it is recommended that this not be called in | |
249 // an object's destructor. | |
250 void RemoveThreadSafeObserver(ThreadSafeObserver* observer); | |
251 | |
252 // Converts a time to the string format that the NetLog uses to represent | |
253 // times. Strings are used since integers may overflow. | |
254 static std::string TickCountToString(const base::TimeTicks& time); | |
255 | |
256 // Returns a C-String symbolic name for |event_type|. | |
257 static const char* EventTypeToString(EventType event_type); | |
258 | |
259 // Returns a dictionary that maps event type symbolic names to their enum | |
260 // values. Caller takes ownership of the returned Value. | |
261 static base::Value* GetEventTypesAsValue(); | |
262 | |
263 // Returns a C-String symbolic name for |source_type|. | |
264 static const char* SourceTypeToString(SourceType source_type); | |
265 | |
266 // Returns a dictionary that maps source type symbolic names to their enum | |
267 // values. Caller takes ownership of the returned Value. | |
268 static base::Value* GetSourceTypesAsValue(); | |
269 | |
270 // Returns a C-String symbolic name for |event_phase|. | |
271 static const char* EventPhaseToString(EventPhase event_phase); | |
272 | |
273 // Returns true if |log_level| indicates the actual bytes transferred should | |
274 // be logged. This is only the case when |log_level| is LOG_ALL. | |
275 static bool IsLoggingBytes(LogLevel log_level); | |
276 | |
277 // Returns true if |log_level| indicates that events should be logged. This is | |
278 // the case when |log_level| is anything other than LOG_NONE. | |
279 static bool IsLogging(LogLevel log_level); | |
280 | |
281 // Creates a ParametersCallback that encapsulates a single integer. | |
282 // Warning: |name| must remain valid for the life of the callback. | |
283 // TODO(mmenke): Rename this to be consistent with Int64Callback. | |
284 static ParametersCallback IntegerCallback(const char* name, int value); | |
285 | |
286 // Creates a ParametersCallback that encapsulates a single int64. The | |
287 // callback will return the value as a StringValue, since IntegerValues | |
288 // only support 32-bit values. | |
289 // Warning: |name| must remain valid for the life of the callback. | |
290 static ParametersCallback Int64Callback(const char* name, int64 value); | |
291 | |
292 // Creates a ParametersCallback that encapsulates a single UTF8 string. Takes | |
293 // |value| as a pointer to avoid copying, and emphasize it must be valid for | |
294 // the life of the callback. |value| may not be NULL. | |
295 // Warning: |name| and |value| must remain valid for the life of the callback. | |
296 static ParametersCallback StringCallback(const char* name, | |
297 const std::string* value); | |
298 | |
299 // Same as above, but takes in a UTF16 string. | |
300 static ParametersCallback StringCallback(const char* name, | |
301 const base::string16* value); | |
302 | |
303 private: | |
304 friend class BoundNetLog; | |
305 | |
306 void AddEntry(EventType type, | |
307 const Source& source, | |
308 EventPhase phase, | |
309 const NetLog::ParametersCallback* parameters_callback); | |
310 | |
311 // Called whenever an observer is added or removed, or has its log level | |
312 // changed. Must have acquired |lock_| prior to calling. | |
313 void UpdateLogLevel(); | |
314 | |
315 // |lock_| protects access to |observers_|. | |
316 base::Lock lock_; | |
317 | |
318 // Last assigned source ID. Incremented to get the next one. | |
319 base::subtle::Atomic32 last_id_; | |
320 | |
321 // The current log level. | |
322 base::subtle::Atomic32 effective_log_level_; | |
323 | |
324 // |lock_| must be acquired whenever reading or writing to this. | |
325 ObserverList<ThreadSafeObserver, true> observers_; | |
326 | |
327 DISALLOW_COPY_AND_ASSIGN(NetLog); | |
328 }; | |
329 | |
330 // Helper that binds a Source to a NetLog, and exposes convenience methods to | |
331 // output log messages without needing to pass in the source. | |
332 class NET_EXPORT BoundNetLog { | |
333 public: | |
334 BoundNetLog() : net_log_(NULL) {} | |
335 | |
336 // Add a log entry to the NetLog for the bound source. | |
337 void AddEntry(NetLog::EventType type, NetLog::EventPhase phase) const; | |
338 void AddEntry(NetLog::EventType type, | |
339 NetLog::EventPhase phase, | |
340 const NetLog::ParametersCallback& get_parameters) const; | |
341 | |
342 // Convenience methods that call AddEntry with a fixed "capture phase" | |
343 // (begin, end, or none). | |
344 void BeginEvent(NetLog::EventType type) const; | |
345 void BeginEvent(NetLog::EventType type, | |
346 const NetLog::ParametersCallback& get_parameters) const; | |
347 | |
348 void EndEvent(NetLog::EventType type) const; | |
349 void EndEvent(NetLog::EventType type, | |
350 const NetLog::ParametersCallback& get_parameters) const; | |
351 | |
352 void AddEvent(NetLog::EventType type) const; | |
353 void AddEvent(NetLog::EventType type, | |
354 const NetLog::ParametersCallback& get_parameters) const; | |
355 | |
356 // Just like AddEvent, except |net_error| is a net error code. A parameter | |
357 // called "net_error" with the indicated value will be recorded for the event. | |
358 // |net_error| must be negative, and not ERR_IO_PENDING, as it's not a true | |
359 // error. | |
360 void AddEventWithNetErrorCode(NetLog::EventType event_type, | |
361 int net_error) const; | |
362 | |
363 // Just like EndEvent, except |net_error| is a net error code. If it's | |
364 // negative, a parameter called "net_error" with a value of |net_error| is | |
365 // associated with the event. Otherwise, the end event has no parameters. | |
366 // |net_error| must not be ERR_IO_PENDING, as it's not a true error. | |
367 void EndEventWithNetErrorCode(NetLog::EventType event_type, | |
368 int net_error) const; | |
369 | |
370 // Logs a byte transfer event to the NetLog. Determines whether to log the | |
371 // received bytes or not based on the current logging level. | |
372 void AddByteTransferEvent(NetLog::EventType event_type, | |
373 int byte_count, const char* bytes) const; | |
374 | |
375 NetLog::LogLevel GetLogLevel() const; | |
376 | |
377 // Shortcut for NetLog::IsLoggingBytes(this->GetLogLevel()). | |
378 bool IsLoggingBytes() const; | |
379 | |
380 // Shortcut for NetLog::IsLogging(this->GetLogLevel()). | |
381 bool IsLogging() const; | |
382 | |
383 // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care | |
384 // of creating a unique source ID, and handles the case of NULL net_log. | |
385 static BoundNetLog Make(NetLog* net_log, NetLog::SourceType source_type); | |
386 | |
387 const NetLog::Source& source() const { return source_; } | |
388 NetLog* net_log() const { return net_log_; } | |
389 | |
390 private: | |
391 BoundNetLog(const NetLog::Source& source, NetLog* net_log) | |
392 : source_(source), net_log_(net_log) { | |
393 } | |
394 | |
395 NetLog::Source source_; | |
396 NetLog* net_log_; | |
397 }; | |
398 | |
399 } // namespace net | |
400 | |
401 #endif // NET_BASE_NET_LOG_H_ | |
OLD | NEW |