Fixes flakey test
[chromium-blink-merge.git] / net / log / net_log.h
blob6463c774a2e06346e547194cffafb4c2be2bede6
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.
5 #ifndef NET_LOG_NET_LOG_H_
6 #define NET_LOG_NET_LOG_H_
8 #include <string>
10 #include "build/build_config.h"
12 #include "base/atomicops.h"
13 #include "base/basictypes.h"
14 #include "base/callback_forward.h"
15 #include "base/compiler_specific.h"
16 #include "base/observer_list.h"
17 #include "base/strings/string16.h"
18 #include "base/synchronization/lock.h"
19 #include "base/time/time.h"
20 #include "net/base/net_export.h"
21 #include "net/log/net_log_capture_mode.h"
23 namespace base {
24 class DictionaryValue;
25 class Value;
28 namespace net {
30 // NetLog is the destination for log messages generated by the network stack.
31 // Each log message has a "source" field which identifies the specific entity
32 // that generated the message (for example, which URLRequest or which
33 // SpdySession).
35 // To avoid needing to pass in the "source ID" to the logging functions, NetLog
36 // is usually accessed through a BoundNetLog, which will always pass in a
37 // specific source ID.
39 // All methods are thread safe, with the exception that no NetLog or
40 // NetLog::ThreadSafeObserver functions may be called by an observer's
41 // OnAddEntry() method. Doing so will result in a deadlock.
43 // For a broader introduction see the design document:
44 // https://sites.google.com/a/chromium.org/dev/developers/design-documents/network-stack/netlog
45 class NET_EXPORT NetLog {
46 public:
47 enum EventType {
48 #define EVENT_TYPE(label) TYPE_##label,
49 #include "net/log/net_log_event_type_list.h"
50 #undef EVENT_TYPE
51 EVENT_COUNT
54 // The 'phase' of an event trace (whether it marks the beginning or end
55 // of an event.).
56 enum EventPhase {
57 PHASE_NONE,
58 PHASE_BEGIN,
59 PHASE_END,
62 // The "source" identifies the entity that generated the log message.
63 enum SourceType {
64 #define SOURCE_TYPE(label) SOURCE_##label,
65 #include "net/log/net_log_source_type_list.h"
66 #undef SOURCE_TYPE
67 SOURCE_COUNT
70 // A callback that returns a Value representation of the parameters
71 // associated with an event. If called, it will be called synchronously,
72 // so it need not have owning references. May be called more than once, or
73 // not at all. May return NULL.
74 typedef base::Callback<scoped_ptr<base::Value>(NetLogCaptureMode)>
75 ParametersCallback;
77 // Identifies the entity that generated this log. The |id| field should
78 // uniquely identify the source, and is used by log observers to infer
79 // message groupings. Can use NetLog::NextID() to create unique IDs.
80 struct NET_EXPORT Source {
81 static const uint32 kInvalidId;
83 Source();
84 Source(SourceType type, uint32 id);
85 bool IsValid() const;
87 // Adds the source to a DictionaryValue containing event parameters,
88 // using the name "source_dependency".
89 void AddToEventParameters(base::DictionaryValue* event_params) const;
91 // Returns a callback that returns a dictionary with a single entry
92 // named "source_dependency" that describes |this|.
93 ParametersCallback ToEventParametersCallback() const;
95 // Attempts to extract a Source from a set of event parameters. Returns
96 // true and writes the result to |source| on success. Returns false and
97 // makes |source| an invalid source on failure.
98 // TODO(mmenke): Long term, we want to remove this.
99 static bool FromEventParameters(base::Value* event_params, Source* source);
101 SourceType type;
102 uint32 id;
105 struct NET_EXPORT EntryData {
106 EntryData(EventType type,
107 Source source,
108 EventPhase phase,
109 base::TimeTicks time,
110 const ParametersCallback* parameters_callback);
111 ~EntryData();
113 const EventType type;
114 const Source source;
115 const EventPhase phase;
116 const base::TimeTicks time;
117 const ParametersCallback* const parameters_callback;
120 // An Entry pre-binds EntryData to a capture mode, so observers will observe
121 // the output of ToValue() and ParametersToValue() at their log capture mode
122 // rather than the current maximum.
123 class NET_EXPORT Entry {
124 public:
125 Entry(const EntryData* data, NetLogCaptureMode capture_mode);
126 ~Entry();
128 EventType type() const { return data_->type; }
129 Source source() const { return data_->source; }
130 EventPhase phase() const { return data_->phase; }
132 // Serializes the specified event to a Value. The Value also includes the
133 // current time. Caller takes ownership of returned Value. Takes in a time
134 // to allow back-dating entries.
135 base::Value* ToValue() const;
137 // Returns the parameters as a Value. Returns NULL if there are no
138 // parameters. Caller takes ownership of returned Value.
139 base::Value* ParametersToValue() const;
141 private:
142 const EntryData* const data_;
144 // Log capture mode when the event occurred.
145 const NetLogCaptureMode capture_mode_;
147 // It is not safe to copy this class, since |parameters_callback_| may
148 // include pointers that become stale immediately after the event is added,
149 // even if the code were modified to keep its own copy of the callback.
150 DISALLOW_COPY_AND_ASSIGN(Entry);
153 // An observer, that must ensure its own thread safety, for events
154 // being added to a NetLog.
155 class NET_EXPORT ThreadSafeObserver {
156 public:
157 // Constructs an observer that wants to see network events, with
158 // the specified minimum event granularity. A ThreadSafeObserver can only
159 // observe a single NetLog at a time.
161 // Observers will be called on the same thread an entry is added on,
162 // and are responsible for ensuring their own thread safety.
164 // Observers must stop watching a NetLog before either the Observer or the
165 // NetLog is destroyed.
166 ThreadSafeObserver();
168 // Returns the capture mode for events this observer wants to
169 // receive. Must not be called when not watching a NetLog.
170 NetLogCaptureMode capture_mode() const;
172 // Returns the NetLog we are currently watching, if any. Returns NULL
173 // otherwise.
174 NetLog* net_log() const;
176 // This method will be called on the thread that the event occurs on. It
177 // is the responsibility of the observer to handle it in a thread safe
178 // manner.
180 // It is illegal for an Observer to call any NetLog or
181 // NetLog::Observer functions in response to a call to OnAddEntry.
182 virtual void OnAddEntry(const Entry& entry) = 0;
184 protected:
185 virtual ~ThreadSafeObserver();
187 private:
188 friend class NetLog;
190 void OnAddEntryData(const EntryData& entry_data);
192 // Both of these values are only modified by the NetLog.
193 NetLogCaptureMode capture_mode_;
194 NetLog* net_log_;
196 DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver);
199 NetLog();
200 virtual ~NetLog();
202 // Emits a global event to the log stream, with its own unique source ID.
203 void AddGlobalEntry(EventType type);
204 void AddGlobalEntry(EventType type,
205 const NetLog::ParametersCallback& parameters_callback);
207 // Returns a unique ID which can be used as a source ID. All returned IDs
208 // will be unique and greater than 0.
209 uint32 NextID();
211 // Returns true if there are any observers attached to the NetLog. This can be
212 // used as an optimization to avoid emitting log entries when there is no
213 // chance that the data will be consumed.
214 bool IsCapturing() const;
216 // Adds an observer and sets its log capture mode. The observer must not be
217 // watching any NetLog, including this one, when this is called.
219 // NetLog implementations must call NetLog::OnAddObserver to update the
220 // observer's internal state.
222 // DEPRECATED: The ability to watch the netlog stream is being phased out
223 // (crbug.com/472693) as it can be misused in production code. Please consult
224 // with a net/log OWNER before introducing a new dependency on this.
225 void DeprecatedAddObserver(ThreadSafeObserver* observer,
226 NetLogCaptureMode capture_mode);
228 // Sets the log capture mode of |observer| to |capture_mode|. |observer| must
229 // be watching |this|. NetLog implementations must call
230 // NetLog::OnSetObserverCaptureMode to update the observer's internal state.
231 void SetObserverCaptureMode(ThreadSafeObserver* observer,
232 NetLogCaptureMode capture_mode);
234 // Removes an observer. NetLog implementations must call
235 // NetLog::OnAddObserver to update the observer's internal state.
237 // For thread safety reasons, it is recommended that this not be called in
238 // an object's destructor.
240 // DEPRECATED: The ability to watch the netlog stream is being phased out
241 // (crbug.com/472693) as it can be misused in production code. Please consult
242 // with a net/log OWNER before introducing a new dependency on this.
243 void DeprecatedRemoveObserver(ThreadSafeObserver* observer);
245 // Converts a time to the string format that the NetLog uses to represent
246 // times. Strings are used since integers may overflow.
247 static std::string TickCountToString(const base::TimeTicks& time);
249 // Returns a C-String symbolic name for |event_type|.
250 static const char* EventTypeToString(EventType event_type);
252 // Returns a dictionary that maps event type symbolic names to their enum
253 // values. Caller takes ownership of the returned Value.
254 static base::Value* GetEventTypesAsValue();
256 // Returns a C-String symbolic name for |source_type|.
257 static const char* SourceTypeToString(SourceType source_type);
259 // Returns a dictionary that maps source type symbolic names to their enum
260 // values. Caller takes ownership of the returned Value.
261 static base::Value* GetSourceTypesAsValue();
263 // Returns a C-String symbolic name for |event_phase|.
264 static const char* EventPhaseToString(EventPhase event_phase);
266 // Creates a ParametersCallback that encapsulates a single bool.
267 // Warning: |name| must remain valid for the life of the callback.
268 static ParametersCallback BoolCallback(const char* name, bool value);
270 // Warning: |name| must remain valid for the life of the callback.
271 // TODO(mmenke): Rename this to be consistent with Int64Callback.
272 static ParametersCallback IntegerCallback(const char* name, int value);
274 // Creates a ParametersCallback that encapsulates a single int64. The
275 // callback will return the value as a StringValue, since IntegerValues
276 // only support 32-bit values.
277 // Warning: |name| must remain valid for the life of the callback.
278 static ParametersCallback Int64Callback(const char* name, int64 value);
280 // Creates a ParametersCallback that encapsulates a single UTF8 string. Takes
281 // |value| as a pointer to avoid copying, and emphasize it must be valid for
282 // the life of the callback. |value| may not be NULL.
283 // Warning: |name| and |value| must remain valid for the life of the callback.
284 static ParametersCallback StringCallback(const char* name,
285 const std::string* value);
287 // Same as above, but takes in a UTF16 string.
288 static ParametersCallback StringCallback(const char* name,
289 const base::string16* value);
291 private:
292 friend class BoundNetLog;
294 void AddEntry(EventType type,
295 const Source& source,
296 EventPhase phase,
297 const NetLog::ParametersCallback* parameters_callback);
299 // Called whenever an observer is added or removed, to update
300 // |has_observers_|. Must have acquired |lock_| prior to calling.
301 void UpdateIsCapturing();
303 // |lock_| protects access to |observers_|.
304 base::Lock lock_;
306 // Last assigned source ID. Incremented to get the next one.
307 base::subtle::Atomic32 last_id_;
309 // |is_capturing_| will be 0 when there are no observers watching the NetLog,
310 // 1 otherwise. Note that this is stored as an Atomic32 rather than a boolean
311 // so it can be accessed without needing a lock.
312 base::subtle::Atomic32 is_capturing_;
314 // |lock_| must be acquired whenever reading or writing to this.
315 ObserverList<ThreadSafeObserver, true> observers_;
317 DISALLOW_COPY_AND_ASSIGN(NetLog);
320 // Helper that binds a Source to a NetLog, and exposes convenience methods to
321 // output log messages without needing to pass in the source.
322 class NET_EXPORT BoundNetLog {
323 public:
324 BoundNetLog() : net_log_(NULL) {}
325 ~BoundNetLog();
327 // Add a log entry to the NetLog for the bound source.
328 void AddEntry(NetLog::EventType type, NetLog::EventPhase phase) const;
329 void AddEntry(NetLog::EventType type,
330 NetLog::EventPhase phase,
331 const NetLog::ParametersCallback& get_parameters) const;
333 // Convenience methods that call AddEntry with a fixed "capture phase"
334 // (begin, end, or none).
335 void BeginEvent(NetLog::EventType type) const;
336 void BeginEvent(NetLog::EventType type,
337 const NetLog::ParametersCallback& get_parameters) const;
339 void EndEvent(NetLog::EventType type) const;
340 void EndEvent(NetLog::EventType type,
341 const NetLog::ParametersCallback& get_parameters) const;
343 void AddEvent(NetLog::EventType type) const;
344 void AddEvent(NetLog::EventType type,
345 const NetLog::ParametersCallback& get_parameters) const;
347 // Just like AddEvent, except |net_error| is a net error code. A parameter
348 // called "net_error" with the indicated value will be recorded for the event.
349 // |net_error| must be negative, and not ERR_IO_PENDING, as it's not a true
350 // error.
351 void AddEventWithNetErrorCode(NetLog::EventType event_type,
352 int net_error) const;
354 // Just like EndEvent, except |net_error| is a net error code. If it's
355 // negative, a parameter called "net_error" with a value of |net_error| is
356 // associated with the event. Otherwise, the end event has no parameters.
357 // |net_error| must not be ERR_IO_PENDING, as it's not a true error.
358 void EndEventWithNetErrorCode(NetLog::EventType event_type,
359 int net_error) const;
361 // Logs a byte transfer event to the NetLog. Determines whether to log the
362 // received bytes or not based on the current logging level.
363 void AddByteTransferEvent(NetLog::EventType event_type,
364 int byte_count,
365 const char* bytes) const;
367 bool IsCapturing() const;
369 // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care
370 // of creating a unique source ID, and handles the case of NULL net_log.
371 static BoundNetLog Make(NetLog* net_log, NetLog::SourceType source_type);
373 const NetLog::Source& source() const { return source_; }
374 NetLog* net_log() const { return net_log_; }
376 private:
377 // TODO(eroman): Temporary until crbug.com/467797 is solved.
378 enum Liveness {
379 ALIVE = 0xCA11AB13,
380 DEAD = 0xDEADBEEF,
383 BoundNetLog(const NetLog::Source& source, NetLog* net_log)
384 : source_(source), net_log_(net_log) {}
386 // TODO(eroman): Temporary until crbug.com/467797 is solved.
387 void CrashIfInvalid() const;
389 NetLog::Source source_;
390 NetLog* net_log_;
392 // TODO(eroman): Temporary until crbug.com/467797 is solved.
393 Liveness liveness_ = ALIVE;
396 } // namespace net
398 #endif // NET_LOG_NET_LOG_H_