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_BASE_NET_LOG_H_
6 #define NET_BASE_NET_LOG_H_
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"
21 class DictionaryValue
;
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
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.
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.
40 // For a broader introduction see the design document:
41 // https://sites.google.com/a/chromium.org/dev/developers/design-documents/network-stack/netlog
42 class NET_EXPORT NetLog
{
45 #define EVENT_TYPE(label) TYPE_ ## label,
46 #include "net/base/net_log_event_type_list.h"
51 // The 'phase' of an event trace (whether it marks the beginning or end
59 // The "source" identifies the entity that generated the log message.
61 #define SOURCE_TYPE(label) SOURCE_ ## label,
62 #include "net/base/net_log_source_type_list.h"
67 // Specifies the granularity of events that should be emitted to the log.
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.
73 // Log everything possible, even if it is slow and memory expensive.
74 // Includes logging of transferred bytes.
77 // Log all events, but do not include the actual transferred bytes as
78 // parameters for bytes sent/received events.
81 // Log all events, but do not include the actual transferred bytes and
82 // remove cookies and HTTP credentials.
83 LOG_STRIP_PRIVATE_DATA
,
85 // Don't log any events.
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
;
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
;
102 Source(SourceType type
, uint32 id
);
103 bool IsValid() const;
105 // Adds the source to a DictionaryValue containing event parameters,
106 // using the name "source_dependency".
107 void AddToEventParameters(base::DictionaryValue
* event_params
) const;
109 // Returns a callback that returns a dictionary with a single entry
110 // named "source_dependecy" that describes |this|.
111 ParametersCallback
ToEventParametersCallback() const;
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
);
123 struct NET_EXPORT EntryData
{
124 EntryData(EventType type
,
127 base::TimeTicks time
,
128 const ParametersCallback
* parameters_callback
);
131 const EventType type
;
133 const EventPhase phase
;
134 const base::TimeTicks time
;
135 const ParametersCallback
* const parameters_callback
;
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
141 class NET_EXPORT Entry
{
143 Entry(const EntryData
* data
, LogLevel log_level
);
146 EventType
type() const { return data_
->type
; }
147 Source
source() const { return data_
->source
; }
148 EventPhase
phase() const { return data_
->phase
; }
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;
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;
160 const EntryData
* const data_
;
162 // Log level when the event occurred.
163 const LogLevel log_level_
;
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
);
171 // An observer, that must ensure its own thread safety, for events
172 // being added to a NetLog.
173 class NET_EXPORT ThreadSafeObserver
{
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.
179 // Observers will be called on the same thread an entry is added on,
180 // and are responsible for ensuring their own thread safety.
182 // Observers must stop watching a NetLog before either the Observer or the
183 // NetLog is destroyed.
184 ThreadSafeObserver();
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;
190 // Returns the NetLog we are currently watching, if any. Returns NULL
192 NetLog
* net_log() const;
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
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;
203 virtual ~ThreadSafeObserver();
208 void OnAddEntryData(const EntryData
& entry_data
);
210 // Both of these values are only modified by the NetLog.
214 DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver
);
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
);
225 // Returns a unique ID which can be used as a source ID. All returned IDs
226 // will be unique and greater than 0.
229 // Returns the logging level for this NetLog. This is used to avoid computing
230 // and saving expensive log entries.
231 LogLevel
GetLogLevel() const;
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.
236 // NetLog implementations must call NetLog::OnAddObserver to update the
237 // observer's internal state.
238 void AddThreadSafeObserver(ThreadSafeObserver
* observer
, LogLevel log_level
);
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
);
245 // Removes an observer. NetLog implementations must call
246 // NetLog::OnAddObserver to update the observer's internal state.
248 // For thread safety reasons, it is recommended that this not be called in
249 // an object's destructor.
250 void RemoveThreadSafeObserver(ThreadSafeObserver
* observer
);
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
);
256 // Returns a C-String symbolic name for |event_type|.
257 static const char* EventTypeToString(EventType event_type
);
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();
263 // Returns a C-String symbolic name for |source_type|.
264 static const char* SourceTypeToString(SourceType source_type
);
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();
270 // Returns a C-String symbolic name for |event_phase|.
271 static const char* EventPhaseToString(EventPhase event_phase
);
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
);
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
);
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
);
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
);
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
);
299 // Same as above, but takes in a UTF16 string.
300 static ParametersCallback
StringCallback(const char* name
,
301 const base::string16
* value
);
304 // Set the lowest allowed log level, regardless of any Observers.
305 void SetBaseLogLevel(LogLevel log_level
);
308 friend class BoundNetLog
;
310 void AddEntry(EventType type
,
311 const Source
& source
,
313 const NetLog::ParametersCallback
* parameters_callback
);
315 // Called whenever an observer is added or removed, or has its log level
316 // changed. Must have acquired |lock_| prior to calling.
317 void UpdateLogLevel();
319 // |lock_| protects access to |observers_|.
322 // Last assigned source ID. Incremented to get the next one.
323 base::subtle::Atomic32 last_id_
;
325 // The lowest allowed log level, regardless of any Observers.
326 // Normally defaults to LOG_NONE, but can be changed with SetBaseLogLevel
327 LogLevel base_log_level_
;
329 // The current log level.
330 base::subtle::Atomic32 effective_log_level_
;
332 // |lock_| must be acquired whenever reading or writing to this.
333 ObserverList
<ThreadSafeObserver
, true> observers_
;
335 DISALLOW_COPY_AND_ASSIGN(NetLog
);
338 // Helper that binds a Source to a NetLog, and exposes convenience methods to
339 // output log messages without needing to pass in the source.
340 class NET_EXPORT BoundNetLog
{
342 BoundNetLog() : net_log_(NULL
) {}
344 // Add a log entry to the NetLog for the bound source.
345 void AddEntry(NetLog::EventType type
, NetLog::EventPhase phase
) const;
346 void AddEntry(NetLog::EventType type
,
347 NetLog::EventPhase phase
,
348 const NetLog::ParametersCallback
& get_parameters
) const;
350 // Convenience methods that call AddEntry with a fixed "capture phase"
351 // (begin, end, or none).
352 void BeginEvent(NetLog::EventType type
) const;
353 void BeginEvent(NetLog::EventType type
,
354 const NetLog::ParametersCallback
& get_parameters
) const;
356 void EndEvent(NetLog::EventType type
) const;
357 void EndEvent(NetLog::EventType type
,
358 const NetLog::ParametersCallback
& get_parameters
) const;
360 void AddEvent(NetLog::EventType type
) const;
361 void AddEvent(NetLog::EventType type
,
362 const NetLog::ParametersCallback
& get_parameters
) const;
364 // Just like AddEvent, except |net_error| is a net error code. A parameter
365 // called "net_error" with the indicated value will be recorded for the event.
366 // |net_error| must be negative, and not ERR_IO_PENDING, as it's not a true
368 void AddEventWithNetErrorCode(NetLog::EventType event_type
,
369 int net_error
) const;
371 // Just like EndEvent, except |net_error| is a net error code. If it's
372 // negative, a parameter called "net_error" with a value of |net_error| is
373 // associated with the event. Otherwise, the end event has no parameters.
374 // |net_error| must not be ERR_IO_PENDING, as it's not a true error.
375 void EndEventWithNetErrorCode(NetLog::EventType event_type
,
376 int net_error
) const;
378 // Logs a byte transfer event to the NetLog. Determines whether to log the
379 // received bytes or not based on the current logging level.
380 void AddByteTransferEvent(NetLog::EventType event_type
,
381 int byte_count
, const char* bytes
) const;
383 NetLog::LogLevel
GetLogLevel() const;
385 // Shortcut for NetLog::IsLoggingBytes(this->GetLogLevel()).
386 bool IsLoggingBytes() const;
388 // Shortcut for NetLog::IsLogging(this->GetLogLevel()).
389 bool IsLogging() const;
391 // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care
392 // of creating a unique source ID, and handles the case of NULL net_log.
393 static BoundNetLog
Make(NetLog
* net_log
, NetLog::SourceType source_type
);
395 const NetLog::Source
& source() const { return source_
; }
396 NetLog
* net_log() const { return net_log_
; }
399 BoundNetLog(const NetLog::Source
& source
, NetLog
* net_log
)
400 : source_(source
), net_log_(net_log
) {
403 NetLog::Source source_
;
409 #endif // NET_BASE_NET_LOG_H_