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 "build/build_config.h"
12 // TODO(eroman): Temporary while investigating crbug.com/467797.
13 // Note base::Debug::StackTrace() is not supported in NACL builds
14 // so conditionally disabled it there.
16 #define TEMP_INSTRUMENTATION_467797
19 #include "base/atomicops.h"
20 #include "base/basictypes.h"
21 #include "base/callback_forward.h"
22 #include "base/compiler_specific.h"
23 #ifdef TEMP_INSTRUMENTATION_467797
24 #include "base/debug/stack_trace.h"
26 #include "base/observer_list.h"
27 #include "base/strings/string16.h"
28 #include "base/synchronization/lock.h"
29 #include "base/time/time.h"
30 #include "net/base/net_export.h"
33 class DictionaryValue
;
39 // NetLog is the destination for log messages generated by the network stack.
40 // Each log message has a "source" field which identifies the specific entity
41 // that generated the message (for example, which URLRequest or which
44 // To avoid needing to pass in the "source ID" to the logging functions, NetLog
45 // is usually accessed through a BoundNetLog, which will always pass in a
46 // specific source ID.
48 // All methods are thread safe, with the exception that no NetLog or
49 // NetLog::ThreadSafeObserver functions may be called by an observer's
50 // OnAddEntry() method. Doing so will result in a deadlock.
52 // For a broader introduction see the design document:
53 // https://sites.google.com/a/chromium.org/dev/developers/design-documents/network-stack/netlog
54 class NET_EXPORT NetLog
{
57 #define EVENT_TYPE(label) TYPE_ ## label,
58 #include "net/base/net_log_event_type_list.h"
63 // The 'phase' of an event trace (whether it marks the beginning or end
71 // The "source" identifies the entity that generated the log message.
73 #define SOURCE_TYPE(label) SOURCE_ ## label,
74 #include "net/base/net_log_source_type_list.h"
79 // Specifies the granularity of events that should be emitted to the log.
81 // Since the LogLevel may be read and set on any thread without locking, it
82 // may be possible for an Observer to receive an event or parameters that
83 // normally wouldn't be logged at the currently active log level.
85 // Log everything possible, even if it is slow and memory expensive.
86 // Includes logging of transferred bytes.
89 // Log all events, but do not include the actual transferred bytes as
90 // parameters for bytes sent/received events.
93 // Log all events, but do not include the actual transferred bytes and
94 // remove cookies and HTTP credentials.
95 LOG_STRIP_PRIVATE_DATA
,
97 // Don't log any events.
101 // A callback function that return a Value representation of the parameters
102 // associated with an event. If called, it will be called synchonously,
103 // so it need not have owning references. May be called more than once, or
104 // not at all. May return NULL.
105 typedef base::Callback
<base::Value
*(LogLevel
)> ParametersCallback
;
107 // Identifies the entity that generated this log. The |id| field should
108 // uniquely identify the source, and is used by log observers to infer
109 // message groupings. Can use NetLog::NextID() to create unique IDs.
110 struct NET_EXPORT Source
{
111 static const uint32 kInvalidId
;
114 Source(SourceType type
, uint32 id
);
115 bool IsValid() const;
117 // Adds the source to a DictionaryValue containing event parameters,
118 // using the name "source_dependency".
119 void AddToEventParameters(base::DictionaryValue
* event_params
) const;
121 // Returns a callback that returns a dictionary with a single entry
122 // named "source_dependecy" that describes |this|.
123 ParametersCallback
ToEventParametersCallback() const;
125 // Attempts to extract a Source from a set of event parameters. Returns
126 // true and writes the result to |source| on success. Returns false and
127 // makes |source| an invalid source on failure.
128 // TODO(mmenke): Long term, we want to remove this.
129 static bool FromEventParameters(base::Value
* event_params
, Source
* source
);
135 struct NET_EXPORT EntryData
{
136 EntryData(EventType type
,
139 base::TimeTicks time
,
140 const ParametersCallback
* parameters_callback
);
143 const EventType type
;
145 const EventPhase phase
;
146 const base::TimeTicks time
;
147 const ParametersCallback
* const parameters_callback
;
150 // An Entry pre-binds EntryData to a LogLevel, so observers will observe the
151 // output of ToValue() and ParametersToValue() at their log level rather than
153 class NET_EXPORT Entry
{
155 Entry(const EntryData
* data
, LogLevel log_level
);
158 EventType
type() const { return data_
->type
; }
159 Source
source() const { return data_
->source
; }
160 EventPhase
phase() const { return data_
->phase
; }
162 // Serializes the specified event to a Value. The Value also includes the
163 // current time. Caller takes ownership of returned Value. Takes in a time
164 // to allow back-dating entries.
165 base::Value
* ToValue() const;
167 // Returns the parameters as a Value. Returns NULL if there are no
168 // parameters. Caller takes ownership of returned Value.
169 base::Value
* ParametersToValue() const;
172 const EntryData
* const data_
;
174 // Log level when the event occurred.
175 const LogLevel log_level_
;
177 // It is not safe to copy this class, since |parameters_callback_| may
178 // include pointers that become stale immediately after the event is added,
179 // even if the code were modified to keep its own copy of the callback.
180 DISALLOW_COPY_AND_ASSIGN(Entry
);
183 // An observer, that must ensure its own thread safety, for events
184 // being added to a NetLog.
185 class NET_EXPORT ThreadSafeObserver
{
187 // Constructs an observer that wants to see network events, with
188 // the specified minimum event granularity. A ThreadSafeObserver can only
189 // observe a single NetLog at a time.
191 // Observers will be called on the same thread an entry is added on,
192 // and are responsible for ensuring their own thread safety.
194 // Observers must stop watching a NetLog before either the Observer or the
195 // NetLog is destroyed.
196 ThreadSafeObserver();
198 // Returns the minimum log level for events this observer wants to
199 // receive. Must not be called when not watching a NetLog.
200 LogLevel
log_level() const;
202 // Returns the NetLog we are currently watching, if any. Returns NULL
204 NetLog
* net_log() const;
206 // This method will be called on the thread that the event occurs on. It
207 // is the responsibility of the observer to handle it in a thread safe
210 // It is illegal for an Observer to call any NetLog or
211 // NetLog::Observer functions in response to a call to OnAddEntry.
212 virtual void OnAddEntry(const Entry
& entry
) = 0;
215 virtual ~ThreadSafeObserver();
220 void OnAddEntryData(const EntryData
& entry_data
);
222 // Both of these values are only modified by the NetLog.
226 DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver
);
232 // Emits a global event to the log stream, with its own unique source ID.
233 void AddGlobalEntry(EventType type
);
234 void AddGlobalEntry(EventType type
,
235 const NetLog::ParametersCallback
& parameters_callback
);
237 // Returns a unique ID which can be used as a source ID. All returned IDs
238 // will be unique and greater than 0.
241 // Returns the logging level for this NetLog. This is used to avoid computing
242 // and saving expensive log entries.
243 LogLevel
GetLogLevel() const;
245 // Adds an observer and sets its log level. The observer must not be
246 // watching any NetLog, including this one, when this is called.
248 // NetLog implementations must call NetLog::OnAddObserver to update the
249 // observer's internal state.
250 void AddThreadSafeObserver(ThreadSafeObserver
* observer
, LogLevel log_level
);
252 // Sets the log level of |observer| to |log_level|. |observer| must be
253 // watching |this|. NetLog implementations must call
254 // NetLog::OnSetObserverLogLevel to update the observer's internal state.
255 void SetObserverLogLevel(ThreadSafeObserver
* observer
, LogLevel log_level
);
257 // Removes an observer. NetLog implementations must call
258 // NetLog::OnAddObserver to update the observer's internal state.
260 // For thread safety reasons, it is recommended that this not be called in
261 // an object's destructor.
262 void RemoveThreadSafeObserver(ThreadSafeObserver
* observer
);
264 // Converts a time to the string format that the NetLog uses to represent
265 // times. Strings are used since integers may overflow.
266 static std::string
TickCountToString(const base::TimeTicks
& time
);
268 // Returns a C-String symbolic name for |event_type|.
269 static const char* EventTypeToString(EventType event_type
);
271 // Returns a dictionary that maps event type symbolic names to their enum
272 // values. Caller takes ownership of the returned Value.
273 static base::Value
* GetEventTypesAsValue();
275 // Returns a C-String symbolic name for |source_type|.
276 static const char* SourceTypeToString(SourceType source_type
);
278 // Returns a dictionary that maps source type symbolic names to their enum
279 // values. Caller takes ownership of the returned Value.
280 static base::Value
* GetSourceTypesAsValue();
282 // Returns a C-String symbolic name for |event_phase|.
283 static const char* EventPhaseToString(EventPhase event_phase
);
285 // Returns true if |log_level| indicates the actual bytes transferred should
286 // be logged. This is only the case when |log_level| is LOG_ALL.
287 static bool IsLoggingBytes(LogLevel log_level
);
289 // Returns true if |log_level| indicates that events should be logged. This is
290 // the case when |log_level| is anything other than LOG_NONE.
291 static bool IsLogging(LogLevel log_level
);
293 // Creates a ParametersCallback that encapsulates a single integer.
294 // Warning: |name| must remain valid for the life of the callback.
295 // TODO(mmenke): Rename this to be consistent with Int64Callback.
296 static ParametersCallback
IntegerCallback(const char* name
, int value
);
298 // Creates a ParametersCallback that encapsulates a single int64. The
299 // callback will return the value as a StringValue, since IntegerValues
300 // only support 32-bit values.
301 // Warning: |name| must remain valid for the life of the callback.
302 static ParametersCallback
Int64Callback(const char* name
, int64 value
);
304 // Creates a ParametersCallback that encapsulates a single UTF8 string. Takes
305 // |value| as a pointer to avoid copying, and emphasize it must be valid for
306 // the life of the callback. |value| may not be NULL.
307 // Warning: |name| and |value| must remain valid for the life of the callback.
308 static ParametersCallback
StringCallback(const char* name
,
309 const std::string
* value
);
311 // Same as above, but takes in a UTF16 string.
312 static ParametersCallback
StringCallback(const char* name
,
313 const base::string16
* value
);
316 friend class BoundNetLog
;
318 void AddEntry(EventType type
,
319 const Source
& source
,
321 const NetLog::ParametersCallback
* parameters_callback
);
323 // Called whenever an observer is added or removed, or has its log level
324 // changed. Must have acquired |lock_| prior to calling.
325 void UpdateLogLevel();
327 // |lock_| protects access to |observers_|.
330 // Last assigned source ID. Incremented to get the next one.
331 base::subtle::Atomic32 last_id_
;
333 // The current log level.
334 base::subtle::Atomic32 effective_log_level_
;
336 // |lock_| must be acquired whenever reading or writing to this.
337 ObserverList
<ThreadSafeObserver
, true> observers_
;
339 DISALLOW_COPY_AND_ASSIGN(NetLog
);
342 // Helper that binds a Source to a NetLog, and exposes convenience methods to
343 // output log messages without needing to pass in the source.
344 class NET_EXPORT BoundNetLog
{
346 BoundNetLog() : net_log_(NULL
) {}
349 // Add a log entry to the NetLog for the bound source.
350 void AddEntry(NetLog::EventType type
, NetLog::EventPhase phase
) const;
351 void AddEntry(NetLog::EventType type
,
352 NetLog::EventPhase phase
,
353 const NetLog::ParametersCallback
& get_parameters
) const;
355 // Convenience methods that call AddEntry with a fixed "capture phase"
356 // (begin, end, or none).
357 void BeginEvent(NetLog::EventType type
) const;
358 void BeginEvent(NetLog::EventType type
,
359 const NetLog::ParametersCallback
& get_parameters
) const;
361 void EndEvent(NetLog::EventType type
) const;
362 void EndEvent(NetLog::EventType type
,
363 const NetLog::ParametersCallback
& get_parameters
) const;
365 void AddEvent(NetLog::EventType type
) const;
366 void AddEvent(NetLog::EventType type
,
367 const NetLog::ParametersCallback
& get_parameters
) const;
369 // Just like AddEvent, except |net_error| is a net error code. A parameter
370 // called "net_error" with the indicated value will be recorded for the event.
371 // |net_error| must be negative, and not ERR_IO_PENDING, as it's not a true
373 void AddEventWithNetErrorCode(NetLog::EventType event_type
,
374 int net_error
) const;
376 // Just like EndEvent, except |net_error| is a net error code. If it's
377 // negative, a parameter called "net_error" with a value of |net_error| is
378 // associated with the event. Otherwise, the end event has no parameters.
379 // |net_error| must not be ERR_IO_PENDING, as it's not a true error.
380 void EndEventWithNetErrorCode(NetLog::EventType event_type
,
381 int net_error
) const;
383 // Logs a byte transfer event to the NetLog. Determines whether to log the
384 // received bytes or not based on the current logging level.
385 void AddByteTransferEvent(NetLog::EventType event_type
,
386 int byte_count
, const char* bytes
) const;
388 NetLog::LogLevel
GetLogLevel() const;
390 // Shortcut for NetLog::IsLoggingBytes(this->GetLogLevel()).
391 bool IsLoggingBytes() const;
393 // Shortcut for NetLog::IsLogging(this->GetLogLevel()).
394 bool IsLogging() const;
396 // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care
397 // of creating a unique source ID, and handles the case of NULL net_log.
398 static BoundNetLog
Make(NetLog
* net_log
, NetLog::SourceType source_type
);
400 const NetLog::Source
& source() const { return source_
; }
401 NetLog
* net_log() const { return net_log_
; }
404 #ifdef TEMP_INSTRUMENTATION_467797
405 // TODO(eroman): Temporary while investigating crbug.com/467797
412 BoundNetLog(const NetLog::Source
& source
, NetLog
* net_log
)
413 : source_(source
), net_log_(net_log
) {
416 // TODO(eroman): Temporary while investigating crbug.com/467797
417 void CrashIfInvalid() const;
419 NetLog::Source source_
;
422 #ifdef TEMP_INSTRUMENTATION_467797
423 // TODO(eroman): Temporary while investigating crbug.com/467797
424 Liveness liveness_
= ALIVE
;
425 base::debug::StackTrace stack_trace_
;
431 #endif // NET_BASE_NET_LOG_H_